I’m making a top down game and I have everything coded to run on arcade physics. The only thing I need the matter physics engine for is sloped tiles used for diagonal walls.
Here are screenshots of what I have.
I haven’t figured out a way to have the two collide properly. I tried using this.physics.add.collider(this.player.sprite, groundLayer); which does work, but the slopes are turned into rectangles.
With matter, it seems like the collision is enabled by default, and the only instance of using a collision code is to trigger an event, which isn’t necessary.
I don’t want to convert my player sprite to matter since it’s a lot of work and quite complicated with my level of knowledge.
Here’s my code.
My level file:
import Player from './Player.js';
export default class Field01 extends Phaser.Scene {
constructor () {
super({
key: 'field01',
physics: {
arcade: {
debug: true,
gravity: { y: 0 }
},
matter: {
debug: true,
gravity: { y: 0 },
debugShowBody: true,
debugBodyColor: 0x0000ff
}
}
});
}
preload()
{
this.load.image('tiles', 'assets/tilemaps/tiles/overworld-ground.png');
this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/Field01.json');
this.load.image('ground', 'assets/platform.png');
this.load.spritesheet('dude', 'assets/sprites/characters/link.png', { frameWidth: 16, frameHeight: 24 });
}
create()
{
var platforms;
var player;
this.map = this.make.tilemap({ key: 'map' });
this.map.landscape = this.map.addTilesetImage('fieldfare', 'tiles');
const groundLayer = this.map.createLayer("ground", [this.map.landscape], 0, 0);
this.map.setCollisionBetween(2,9);
this.cameras.main.setSize(256,224);
this.cameras.main.setBounds(0, 0, this.map.widthInPixels, this.map.heightInPixels);
this.player = new Player(this, 352, 48);
this.add.existing(Player);
this.cameras.main.startFollow(this.player.sprite);
this.cameras.main.setDeadzone(4,4);
platforms = this.physics.add.staticGroup();
platforms.create(64, 64, 'ground');
groundLayer.setCollisionByProperty({ collides: true });
this.matter.world.convertTilemapLayer(groundLayer);
this.physics.add.collider(this.player.sprite, groundLayer);
this.physics.add.collider(this.player.sprite, platforms, function(player, platforms) { this.scene.switch('Level1'), player.y += 48}, null, this);
}
update() {
this.player.update();
}
}
My player file:
export default class Player {
constructor(scene, x, y) {
this.scene = scene;
const anims = scene.anims;
anims.create({
key: 'turn1',
frames: [ { key: 'dude', frame: 32 } ],
frameRate: 20
});
anims.create({
key: 'rdown',
frames: anims.generateFrameNumbers('dude', { start: 0, end: 7 }),
frameRate: 16,
repeat: -1
});
anims.create({
key: 'rright',
frames: anims.generateFrameNumbers('dude', { frames: [ 8, 9, 10, 11, 12, 13, 14, 15 ] }),
frameRate: 16,
repeat: -1
});
anims.create({
key: 'rup',
frames: anims.generateFrameNumbers('dude', { frames: [ 16, 17, 18, 19, 20, 21, 21, 23 ] }),
frameRate: 16,
repeat: -1
});
anims.create({
key: 'rleft',
frames: anims.generateFrameNumbers('dude', { frames: [ 24, 25, 26, 27, 28, 29, 30, 31 ] }),
frameRate: 16,
repeat: -1
});
this.sprite = scene.physics.add.sprite(x, y, "dude", 0).setSize(16, 16).setOffset(0, 8);
this.sprite.anims.play("rdown");
this.gamepad = scene.input.gamepad.once('down', function (pad, button, index) {
this.gamepad = pad;
}, this);
}
update() {
const gamepad = this.gamepad;
const sprite = this.sprite;
const speed = 90;
const prevVelocity = sprite.body.velocity.clone();
sprite.body.setVelocity(0);
if (gamepad.right && gamepad.up) {
sprite.body.setVelocityX(speed);
sprite.body.setVelocityY(-speed);
} else if (gamepad.right && gamepad.down) {
sprite.body.setVelocityX(speed);
sprite.body.setVelocityY(speed);
} else if (gamepad.left && gamepad.up) {
sprite.body.setVelocityX(-speed);
sprite.body.setVelocityY(-speed);
} else if (gamepad.left && gamepad.down) {
sprite.body.setVelocityX(-speed);
sprite.body.setVelocityY(speed);
} else if (gamepad.left) {
sprite.body.setVelocityX(-speed);
} else if (gamepad.right) {
sprite.body.setVelocityX(speed);
} else if (gamepad.up) {
sprite.body.setVelocityY(-speed);
} else if (gamepad.down) {
sprite.body.setVelocityY(speed);
}
sprite.body.velocity.normalize().scale(speed);
if (gamepad.left) {
sprite.anims.play("rleft", true);
} else if (gamepad.left && gamepad.down) {
sprite.anims.play("rleft", true);
} else if (gamepad.left && gamepad.up) {
sprite.anims.play("rleft", true);
} else if (gamepad.right && gamepad.down) {
sprite.anims.play("rright", true);
} else if (gamepad.right && gamepad.up) {
sprite.anims.play("rright", true);
} else if (gamepad.up) {
sprite.anims.play("rup", true);
} else if (gamepad.right) {
sprite.anims.play("rright", true);
} else if (gamepad.down) {
sprite.anims.play("rdown", true);
} else {
sprite.stopOnFrame(sprite.anims.currentAnim.getFrameAt(0))
}
}
}
Here’s my game config file;
import Field01 from "./Field01.js";
var config = {
type: Phaser.AUTO,
width: 256,
height: 224,
pixelArt: true,
input: {
gamepad: true
},
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 },
debug: true
}
},
scene: [ Field01 ]
}
var game = new Phaser.Game(config);
And my index file:
<!DOCTYPE html>
<html>
<head>
<script src="phaser.js"></script>
<script src="matter.js"></script>
</head>
<body>
<script type="module" src="game.js"></script>
</body>
</html>
Anything I can do?
If I have to change to matter, then how would I properly convert it? This is just a last resort if nothing else is possible.