Box2D на WebAssembly внутри canvas
Валерий Кузьмин, СКБ Контур
Екатеринбург, DUMP 2018
Подготовка
https://github.com/malcoriel/wasm-workshop.git
+
npm/yarn install
npm/yarn start
затем
План
- Что такое WebAssembly и emscripten
- Как подключать emscripten-модули
- Как создавать объекты в Box2D (практика)
- Как добавлять отрисовку в paper.js (практика)
- Как писать js + wasm код, чтобы память не текла
- Как писать игровую логику (домашка)
Что за WASM?
WebAssembly - это...
- Развиваемая W3C спецификация платформы
- Работающая рядом с JS "виртуальная машина"
- Текстовый и бинарный формат
- Цель компиляции для С/С++/Rust
WebAssembly - это...
- Быстро грузится (чем JS)
- Быстро парсится (чем JS)
- Быстро работает (чем JS)
какой-то бинарный файлик с логикой, который
Применение - cpu/memory-bound задачи
Рендеринг PDF
Работа с изображениями
Криптография
Обработка видео
Сериализация и
десериализация xml, json
Игры
Запуск других языков
Браузер в браузере
Математика, переборы,
сортировки
Базы данных на клиенте
Работа с архивами
Machine Learning
Что интересного уже есть
- asm-dom - SPA на C++
- webkit.js - запуск вебкита в другом браузере
- gccx - аналог jsx на C++
- MS Blazor - Razor на webassembly
- jsnet - глубокое обучение на JS
- Поддержка в Unity и UnrealEngine
- Порты ammo и Box2D
Где мне это взять?
С++
wasm
JS
LLVM
emscripten
все руками
Нечто бинарное
Полезный код
API
emscripten
для Rust есть wasm-bindgen
для C++ embind
Что за emscripten?
- Компилятор С/С++ в asm.js и wasm
- Обертка для получившихся wasm-файликов
- Оптимизация и минификация wasm/js кода
Задание 1
подключаем emscripten-модуль
task1
Задание 2.1
создаем объекты Box2D
Ширина клетки - wallSize = 1 метр
Отступ (в клетках) слева - j
Отступ (в клетках) сверху - i
j = 2
i = 1
Искомые координаты (2.5, 1.5)
task2.1
Задание 2.2
создаем объекты Box2D
new Box2D.b2Vec2(x : number, y : number);
bodyDef.set_position(pos : b2Vec2)
new Box2D.b2PolygonShape();
shape.SetAsBox(
halfWidth : number,
halfHeight : number
);
bodyDef.set_type(Box2D.b2_dynamicBody);
body.CreateFixture(
shape : b2Shape,
density : number
);
anyEMCObj.__destroy__();
body
fixture
fixture
fixture
task2.2
Задание 3.1
рисуем спрайты на paper.js
yOffset=16
xOffset=0
80px
64px
dX
=
24
dY = 16
task3.1
Задание 3.2
рисуем спрайты на paper.js
const path = new Paper.Shape.Rectangle({
position: position,
size: new Paper.Size(xSize, xSize),
strokeColor: 'red',
}); // уже есть
new Paper.Group([path, raster]);
group.scale(scaleTo);
group.clipped = true;
task3.2
Память в JS и WASM
JS: garbage collected
WASM: all manual
(речь про кучу)
Память в JS
GC roots
business
logic
Память в JS
GC roots
business
logic
delete
Память в WASM
b2Vec2
b2Body
X
Y
...
...
...
ptr
JS-обертка
это уже от emscripten
Память в WASM
b2Body
...
...
...
ptr
JS-обертка
Module._free (ptr)
obj.__destroy__()
или
(emscripten)
(Box2D.wasm)
Память: простые правила
- Локальные переменные - очищаем сразу
- Сначала чистим WASM, затем JS
- Долгоживущие объекты - только 1 владелец
- Лимитируйте рост
Задание 4
делаем игровую логику
- В методе boulder/tryBreak добавьте создание нескольких объектов Rock
- В методе player/tryShoot сделайте создание объектов типа Pickaxe
task4.2
task4.1
malcoriel@gmail.com
malcoriel
http://bit.ly/wasm-at-dump2018
final
wasm-at-dump2018
By Valeriy Kuzmin
wasm-at-dump2018
- 664