Новости
Статьи
GameDev Archives | Ugolnik's blog
Опубликовано: 01.09.2018
Мой обновленный способ инициализации. В целом он почти не отличается от использованного мною все эти годы. И является практически дефольтным, согласно документации. Но, на одном параметре стоит заострить внимание.
По-умолчанию этот параметр установлен в 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 moreRoad Fighter — видеоигра в жанре аркадных автогонок, разработанная компанией Konami и выпущенная в виде игрового автомата 7 декабря 1984 года. Позднее были выпущены версии для компьютеров стандарта MSX1 (1985) и для игровой консоли Nintendo Entertainment System (1985 в Японии и 1991 в Европе).
» Read moreTexture 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); }