Статьи

GameDev Archives | Ugolnik's blog

Опубликовано: 01.09.2018

видео GameDev Archives | Ugolnik's blog

Game Dev Story Android Complete Playthrough - NintendoComplete

Мой обновленный способ инициализации. В целом он почти не отличается от использованного мною все эти годы. И является практически дефольтным, согласно документации. Но, на одном параметре стоит заострить внимание.



По-умолчанию этот параметр установлен в TRUE. И сегодня я получил слайд-шоу, установив его в значение по-умолчанию.

EmscriptenWebGLContextAttributes attr; emscripten_webgl_init_context_attributes(&attr); attr.alpha = EM_FALSE; attr.depth = EM_FALSE; attr.stencil = EM_FALSE; attr.antialias = EM_FALSE; // <-- this should be set to FALSE! attr.preserveDrawingBuffer = EM_FALSE; attr.preferLowPowerToHighPerformance = EM_FALSE; attr.failIfMajorPerformanceCaveat = EM_FALSE; attr.enableExtensionsByDefault = EM_TRUE; attr.premultipliedAlpha = EM_TRUE; attr.majorVersion = 1; attr.minorVersion = 0; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(nullptr, &attr); emscripten_webgl_make_context_current(ctx);

На HiDPI мониторах downscaled текстуры выглядят мягко говоря не очень красиво. Искал способ решить эту проблему. В итоге мои исследования привели к такому не самому легковесному решению.


Halloween Forever gamedev archive: Chainsaw Megamaniac attacks! #gamedev

Получить device pixel ratio для настройки размров canvas. Получить размер canvas и разрешение css. На их основе вычислить отношение. Использовать это отношение для расчета координат мыши и тача.

После этого все будет выглядеть красиво на HiDPI мониторах. Но есть одна “особенность” – увеличенный (в зависимости от отношения размеров css и canvas) в несколько раз фреймбуфер. При отношении равном 2, получаем размер фреймбуфера в четыре раза больший, со всеми вытекающими.


GameDev: Tower of Souls - "Titles and Archive" 1/2

Немного кода

CSS

canvas { width: 100vw; height: 100vh; display: block; }

JavaScript

window.addEventListener('resize', resizeCanvas, false); function resizeCanvas() { var realToCSSPixels = window.devicePixelRatio; var displayWidth = Math.floor(canvas.clientWidth * realToCSSPixels); var displayHeight = Math.floor(canvas.clientHeight * realToCSSPixels); if (canvas.width !== displayWidth || canvas.height !== displayHeight) { canvas.width = displayWidth; canvas.height = displayHeight; } } resizeCanvas();

C++

int width, height; emscripten_get_canvas_element_size(nullptr, &width, &height); double cssWidth, cssHeight; emscripten_get_element_css_size(nullptr, &cssWidth, &cssHeight); const auto ratiox = (float)(width / cssWidth); const auto ration = (float)(height / cssHeight);

Можно сделать настройку, доступную пользователю – пусть он сам решает, что ему лучше – производительность или качество рендеринга.

Довольно много времени потратил на поиск “плавающего” бага. За это время успел отрефакторить кучу кода, до которого руки не доходили ранее. Но баг не ловился. И в его поимке не смогли помочь ни Xcode Instruments, ни Xcode Analyzer (фронтэнд к статическому анализатору llvm).

Баг проявлялся редко и далеко не на всех девайсах. Я никак не мог понять условия его проявления. Пробовал записывать направление и температуру ветра, положение звезд на небе и длительность соседского ора. Но это никак не помогало в поиске проблемы.

Падения игры под отладчиком и backtrace давали BAD EXC, что как бы намекало на испорченную где-то ранее память. Но где именно? Статический анализатор, по идее, должен на раз находить access out of bounds. Но анализатор молчал, типа вообще все пучком.

От безысходности и обиды на самого себя, решил синхронизировать линуксовую версию с main branch, т.к. в процессе поиска бага был сделан серьезный рефакторинг кода. Ну и очевидно, что погонять движок под valgrind никогда лишним не будет.

И valgrind сразу же нашел memory corruption (тот самый “плавающий” баг, на поиски которого я убил много времени. И мелкий ничего не значащий memory leak.

Linux и valgrind рулят!

Столкнулся с проблемой на itch.io , когда приложение запущенной внутри iframe не получает события клавиатуры. Придумал вот такой workaround:

postRun: (function() { window.addEventListener('mousedown', function(evt) { window.focus(); evt.preventDefault(); evt.stopPropagation(); evt.target.style.cursor = 'default'; }, false); })(),

К событию postRun добавляем установку листенера на событие mousedown. Теперь при клике мышью на канавасе с игрой события от клавиатуры будут передаваться в наше приложение.

Way of Tanks – это танковый ранер с бесконечным геймплеем и разнообразной трассой. Игрок свайпами (или кнопками клавиатуры, или жестами на пульте Apple TV) управляет танком. Задача игрока преодолеть как можно большую дистанцию не столкнувшись с препятствиями и не погибнув в бою с боссами. Так может перемещаться с дорожки на дорожку, стрелять и перепрыгивать рвы (да, вот такой современный танк). В игре есть различные поверапы, которые временно улучшают характеристики танка – маневренность, супер-снаряд, удвоение собранных денег, способность пробивать препятствия. Так же игрок может приобрести, за собранные во время гонки деньги, новый улучшенный танк. Всего в игре четыре танка, которые отличаются по характеристикам и возможностям.

» Read more

Road Fighter — видеоигра в жанре аркадных автогонок, разработанная компанией Konami и выпущенная в виде игрового автомата 7 декабря 1984 года. Позднее были выпущены версии для компьютеров стандарта MSX1 (1985) и для игровой консоли Nintendo Entertainment System (1985 в Японии и 1991 в Европе).

» Read more

Texture Packer для Linux и macOS – утилита, которая упаковывает набор входных изображений в один большой атлас. Утилита консольная, что удобно для автоматизации.

Из возможностей:

Достаточно шустрая. Сравнивал с “обычным платным” (с) пакером. Умеет создавать Power of Two атлас. Можно ограничить максимальный размер атласа. Умеет отрезать “лишние” пиксели (trim) у входных изображений. Может добавить бордюр нужного размера вокруг изображений при размещении в атласе.

Утилита делалась для себя, а теперь доступна на Bitbucket – Texture Packer .

Emscripten is an LLVM-based project that compiles C and C++ into highly-optimizable JavaScript in asm.js format. This lets you run C and C++ on the web at near-native speed, without plugins.

Решил еще раз установить Emscripten с помощью brew, на сей раз все оказалось гораздо проще. Возможно это работало и раньше, но я только сегодня обратил на это внимание.

Правильный способ установки Emscripten с помощью brew:

# устанавливаем emscripten как обычно: $ brew install emscripten # запускаем emcc, что бы он создал файл ~/.emscripten $ emcc # исправляем LLVM_ROOT: $ vim ~/.emscripten

Должно получиться как-то так:

LLVM_ROOT = '/usr/local/opt/emscripten/libexec/llvm/bin'

К сожалению с помощью brew правильно установить emscripten под OS X El Capitan мне не удалось.

Я не смог найти какую-либо информацию по правильной установке emscripten с помощью brew, поэтому получилась вот такая магическая инструкция.

Список шагов для установки emscripten из-под OS X :

С официального сайта качаем портабельную версию emscripten – http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html#sdk-download-and-install Распаковываем и запускаем ./emsdk update . С помощью команды ./emsdk list можно посмотреть список доступных пакетов, утилит и sdk. С помощью комады ./emsdk install latest устанавливаем самые последние версии. Командой ./emsdk activate активируем переменные окружения emscripten. Теперь при необходимости сборки проекта инициализируем переменные окружения с помощью команды source ./emsdk_env.sh . По желанию можно прописать путь к директории с emsdk.

Иногда не нужно делать локализацию всех строк. К примеру, зачем переводить идентификаторы сетей или прочие технические данные.

Если нужно полностью подавить сообщение об ошибке, то в build.gradle достаточно добавить такие параметры:

lintOptions { disable 'MissingTranslation' }

Если нужно подавить сообщение об ошибке только для определенных файлов, то добавляются такие атрибуты в каждый файл:

<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">

Написал GLES шейдер, который имитирует круговое заполнение энергии (прогресса, маны, etc.). Код шейдера и демонстрация работы доступна на сайте ShaderToy .

#define M_PI 3.1415926535897932384626433832795 vec4 col = vec4(0.0, 0.0, 0.0, 0.0); void mainImage( out vec4 fragColor, in vec2 fragCoord ) { float angle = mod(iGlobalTime, M_PI * 2.0); vec2 p = (iResolution.xy - 2.0 * fragCoord.xy) / iResolution.y; float q = atan(-p.x, p.y); float f = step(0.0, cos((q + angle) * 0.5)); // mix with texture vec2 uv = fragCoord.xy / iResolution.xy; vec4 tc = texture2D(iChannel0, uv); fragColor = mix(tc, col, f); }
2011.11.19
Карта
rss