Im trying to create a platformer game in phaser 3 using the matter physics engine, currently im trying to create levels using tiled, I have gotten to a point where the player can’t infinitely jump however they can still jump up walls.
Im currently trying to make it so they can only jump if they are colliding with a specific layer called floor.
When I try to use the code below I get an error saying:
Uncaught TypeError: Cannot set properties of null (setting ‘label’)
game.js (create function):
create() { //External function to create player player(this,'test',300,200,'player') pawn.setScale(1.5) pawn.setDepth(2) pawn.setBounce(0.1) pawn.setFriction(0,0,1) pawn.setCircle(20) pawn.setMass(1) this.touchingGround = false; this.jumpForce = 0.05 this.map = this.make.tilemap({key: 'lv3'}) this.tileset = this.map.addTilesetImage('tiles','tile', 32, 32) this.walls = this.map.createLayer('walls', this.tileset) this.walls.setCollisionByExclusion(-1, true); this.floor = this.map.createLayer('floor', this.tileset) this.floor.setCollisionByExclusion(-1, true); this.matter.world.convertTilemapLayer(this.walls); this.matter.world.convertTilemapLayer(this.floor); pawn.body.label = 'player' this.floor.body.label = 'floor' this.matter.world.on("collisionactive", (e,o1, o2) => { if(o1.label == 'player' && o2.label == 'floor') { this.touchingGround = true; } }); };
Sorry if this is a really easy fix or just doesn’t work and I’m being stupid.
Advertisement
Answer
I’m no matter.js-engine expert, but I assume the error happens on the line this.floor.body.label = 'floor'
. A easy solution would be to use the options
parameter, from the convertTilemapLayer
method (Documentation).
Here a working Demo:
(code based on this phaser.io example )
var config = { type: Phaser.AUTO, width: 11 * 16, height: 6 * 16, zoom: 2, pixelArt: true, scene: { preload: preload, create: create }, physics: { default: 'matter', matter: { gravity: { y:.3 }, } }, banner: false }; function preload (){ this.load.image('mario-tiles', 'https://labs.phaser.io/assets/tilemaps/tiles/super-mario.png'); } function create (){ var level = [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 14, 14, 14, 14, 14, 0, 0, 0, 0 ], ] var map = this.make.tilemap({ data: level, tileWidth: 16, tileHeight: 16 }); var tiles = map.addTilesetImage('mario-tiles'); var layer = map.createLayer(0, tiles, 0, 0); let player = this.add.rectangle(40, 10, 8, 8, 0xffffff) layer.setCollision([14]); this.matter.add.gameObject(player); this.matter.world.convertTilemapLayer(layer, {label:'floor'}); let info = this.add.text(4, 4, 'Waiting for collision', {color:'#ffffff', fontSize:10}) .setOrigin(0); player.body.label = 'player'; this.matter.world.on("collisionactive", (e, o1, o2) => { if(o1.label == 'player' && o2.label == 'floor') { info.setText('touching'); } }); } new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>