cseibert Posted July 22, 2018 Share Posted July 22, 2018 so I have a tilemap with tiles that make up a bridge (see attached image). I'm trying to figure out if there is a way I can customize the bounds of the tiles to have the player collide only where the water starts on the tile. I'm trying to read through the phaser3 code, but I'm not sure where it calculates the tile x, y, width, height for collision. Is it possible for me to manually change the bounds x, y, width, height for certain tiles? Is there a different approach I should be using to handle these collisions (separate collision layer? modify my tiles to have the bridge almost be full width?). One thing I have tried is just treating the tiles as 16x16 so that I can declare the water tiles with setCollision, but it seems hacky.. Link to comment Share on other sites More sharing options...
NoxBrutalis Posted July 22, 2018 Share Posted July 22, 2018 I think if you load the tilemap as a dynamic layer, you can loop through the tiles or something and change the body dimensions. Otherwise, use matter.js. I had a similar concern myself, I'd even set the collision boxes in tiled, but with arcade physics, you can only use plain axis aligned boxes for collision. The first suggestion - dynamic layer- is just a guess tho really, but as dynamic tiles have bodies and bodies can be resized, it made your only option. If you're suing tiled, you could add custom properties to the tiles you need to change, possibly even add their desired width/height as properties also so when looping you can automate the process somewhat. Link to comment Share on other sites More sharing options...
nkholski Posted July 22, 2018 Share Posted July 22, 2018 You can achieve it with collision callbacks. Read my answer here: Link to comment Share on other sites More sharing options...
NoxBrutalis Posted July 22, 2018 Share Posted July 22, 2018 well, I have managed in my own efforts to make the collisions the right size for my needs, sadly though, collision just doesn't work for me at the minute. Cant get playergroup to collide with bounds or with these colliders i have just arranged. Anyways, here's code for making your colliding tiles a better fit. this.layer5 = this.map.createStaticLayer('WallLayer', this.tiles, 0, 0).setOrigin(0, 0); this.layer5.tilemap.layer.data.forEach( i =>{ i.forEach(j =>{ if(j.index !== -1) { var wall = this.physics.add.sprite(j.x * 32, j.y * 32, null, null).setOrigin(0, 0).setVisible(false); var props = this.layer5.tileset.getTileProperties(j.index); wall.body.setOffset(props.x + 16, props.y + 16); wall.body.width = props.w; wall.body.height = props.h; this.wallGrp.add(wall); } }); }); this.physics.add.collider(this.playerGrp, this.wallGrp, function(p, w){ console.log(p, w, "collision detected"); }); Also see the picture below, the tiles are 32x32, but the colliders are now various sizers, all smaller than 32x32 tho. There is a downside to this and that is you need to us Tiled, and you have to manually set the properties for each tile (in the tileset, not the map thankfully) that you want to have this info. I set my tiles to have a bool called collides, and 4 ints, x, y, w, and h. These numbers are RELATIVE to the tile's position, not their global position. To see the properties of the collision box, you have to draw it on in the tileset editor, and then make sure you have the collider selected, otherwise you can only see the tile's normal info etc. Anyways, hopefully this helps someone, I'm off to try and fix my collision woes Link to comment Share on other sites More sharing options...
NoxBrutalis Posted July 22, 2018 Share Posted July 22, 2018 Oh and the collision issue I was having seems to be because the first argument in a collider can't be static, I think its because it implies that it caused the collision, when obviously that's not possible if you're static. Like being drunk and accusing the lamp post of walking into you So just bear in mind that the code would need adjusting Link to comment Share on other sites More sharing options...
cseibert Posted July 22, 2018 Author Share Posted July 22, 2018 Thanks for the different approaches, I'll try to figure out which one is a best fit for my goals. This community is really helpful! NoxBrutalis 1 Link to comment Share on other sites More sharing options...
NoxBrutalis Posted July 22, 2018 Share Posted July 22, 2018 Just a quick update, sorry to bump, but further to the above, I realised that the built-in tilemap collider is way more efficient, ofc it only depends on the size of your map, mine is 10k tiles, so pretty big. So i counted up the collision tiles and I had 1768 collision tiles, and it was noticeable because lag. So I optimised further. I found out that using the tiled object layer, although tedious, allows for more simple data loading. I went back into my tiled map, and added another object layer for collision tiles, and instead of having one per tile, I made all the walls into long tiles etc and loaded them. I went from 1768 collision tiles, to 850 something... Here's a pic: and this is how I extract the data I need to remake the colliders how they are in Tiled. Best avoid rotation, I had to redo half my map because lazily rotating selections in Tiled resulted in unusable collision tiles ? this.map.objects[1].objects.forEach(ele=>{ var wall = this.physics.add.sprite(ele.x, ele.y, null, null).setVisible(false).setActive(true).setOrigin(0, 0); wall.body.setOffset(16, 16); wall.body.width = ele.width; wall.body.height = ele.height; wall.body.immovable = true; this.wallGrp.add(wall); }); Link to comment Share on other sites More sharing options...
Recommended Posts