Box2D на WebAssembly внутри canvas

Валерий Кузьмин, СКБ Контур

Екатеринбург, DUMP 2018

Подготовка

https://github.com/malcoriel/wasm-workshop.git

+

npm/yarn install

npm/yarn start

затем

План

  1. Что такое WebAssembly и emscripten
  2. Как подключать emscripten-модули
  3. Как создавать объекты в Box2D (практика)
  4. Как добавлять отрисовку в paper.js (практика)
  5. Как писать js + wasm код, чтобы память не текла
  6. Как писать игровую логику (домашка)

Что за 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

делаем игровую логику

  1. В методе boulder/tryBreak добавьте создание нескольких объектов Rock
  2. В методе 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