Как мы уже знаем, для обработки физических взаимодействий, например столкновений, игровым объектам нужны физические тела, добавленные в движок.
Мы уже создали тела героя и платформ и можем обрабатывать их столкновения.
Игрок собирает алмазы, касаясь их спрайтом героя во время прыжка. Значит, алмазам тоже нужны тела. Доработаем класс Diamond:
export class Diamond {
constructor(x, y) {
this.createSprite(x, y);
}
createSprite(x, y) {
this.sprite = App.sprite("diamond");
this.sprite.x = x;
this.sprite.y = y;
}
createBody() {
this.body = Matter.Bodies.rectangle(this.sprite.width / 2 + this.sprite.x + this.sprite.parent.x, this.sprite.height / 2 + this.sprite.y + this.sprite.parent.y, this.sprite.width, this.sprite.height, {friction: 0, isStatic: true, render: { fillStyle: '#060a19' }});
this.body.gameDiamond = this;
this.body.isSensor = true;
Matter.World.add(App.physics.world, this.body);
}
}
Мы создали физическое тело так же, как для платформы и героя: прямоугольник в координатах спрайта с размерами алмаза. Как обычно, сохранили в теле ссылку на объект алмаза, чтобы обращаться к нему при событиях столкновения.
Также установили this.body.isSensor в true. Так спрайт героя сможет проходить сквозь алмаз, в отличие от платформы, которая не должна пропускать его через себя.
Осталось вызвать createBody после добавления алмаза дочерним элементом контейнера платформы в Platform.js:
createDiamonds() {
const y = App.config.diamonds.offset.min + Math.random() * (App.config.diamonds.offset.max - App.config.diamonds.offset.min);
for (let i = 0; i < this.cols; i++) {
if (Math.random() < App.config.diamonds.chance) {
this.createDiamond(this.tileSize * i, -y);
}
}
}
createDiamond(x, y) {
const diamond = new Diamond(x, y);
this.container.addChild(diamond.sprite);
diamond.createBody();
this.diamonds.push(diamond);
}