Jump to content

Sprite collide between all tiles in tilemap layer


ste2425
 Share

Recommended Posts

Hi all.

 

Looked through the various tilemap examples regarding collision and they all implement .setCollision() or .setCollisionBetween(). Which is great if you know the indexes of the specific tiles you want to collide with. However i don't. I may be trying to accomplish this in the wrong way however. What I have got is a tilemap with multiple layers. A ground layer that could have any tile from my set and a collision layer that could also have any tile from my set. What i want to be able to say to Phaser is collide with any tile that is being used within this layer, at the position specified in this layer. That way i could easily plug in and out different tilemaps without have to have any extra config/logic. However looking at the different map and layer objects in devtools the layers don't seem to have anything specifying the tiles used in that layer. They have a multidimensional array specifying the grid and tiles though.

 

At the moment ive hard coded the setCollision() to a tile index i know is used in the collision layer, but with the way im trying to implement the layer having to specify this wont scale very well.

 

Is this accomplish-able (is that even a word, spell check says no)? Or am i trying to doing against the standard way. 

 

Thanks all for your time.

 

Here's my awesome code.

function preload() {    game.load.tilemap('desert', 'assets/desert.json', null, Phaser.Tilemap.TILED_JSON);    game.load.image('tiles', 'assets/tmw_desert_spacing.png');    game.load.image('car', 'assets/car90.png');}var map;var tileset;var layer;var collision;var cursors;var sprite;function create() {    game.physics.startSystem(Phaser.Physics.ARCADE);    map = game.add.tilemap('desert');    map.addTilesetImage('Desert', 'tiles');    layer = map.createLayer('Ground');    layer.resizeWorld();    collision = map.createLayer('collision');    collision.resizeWorld();    console.log(map)    sprite = game.add.sprite(450, 80, 'car');    sprite.anchor.setTo(0.5, 0.5);    game.camera.follow(sprite);    map.setCollision(9, true, collision);    game.physics.enable(sprite);    sprite.body.collideWorldBounds = true;    sprite.body.bounce.y = 250;    cursors = game.input.keyboard.createCursorKeys();}function update() {    game.physics.arcade.collide(sprite, collision);    sprite.body.velocity.x = 0;    sprite.body.velocity.y = 0;    sprite.body.angularVelocity = 0;    if (cursors.left.isDown)    {        sprite.body.angularVelocity = -200;    }    else if (cursors.right.isDown)    {        sprite.body.angularVelocity = 200;    }    if (cursors.up.isDown)    {        game.physics.arcade.velocityFromAngle(sprite.angle, 200, sprite.body.velocity);    }}
Link to comment
Share on other sites

Erm, I may be misunderstanding you, but with 

game.physics.arcade.collide(sprite, collision);

in your update function you pretty much already specified that your game object should ONLY collide with the collision layer. You did not add the same function for the Ground layer, so it will not do anything with it.

 

If instead you meant that you want specific tiles to allow collision, you could throw those indexes in an array, and set their collision markers to true, like this:

var tempIndex = this.map.getTilesetIndex("tiletypes");var firstGid = this.map.tilesets[tempIndex].firstgid;var collisionTiles = [];for(var a = firstGid;a < firstGid + 16;a++) {   collisionTiles.push(a);}this.map.setCollision(collisionTiles, true, this.mapData.layers.collision);

(And yes, that number 16 in the for loop is hardcoded atm, I was too lazy to check for the firstgid or existence of the tileset afterwards atm...)

Link to comment
Share on other sites

Erm, I may be misunderstanding you, but with 

game.physics.arcade.collide(sprite, collision);

 

 

Thats what i thought, however if i remove the line 

map.setCollision(9, true, collision);

then my car sprite just move over the collision layer objects. Adding that line back it and it collides with the layer, but only with the tile with an ID of 9.

 

Your second snippet looks like exactly what i want if i do have to explicitly specify the tiles ID's to collide with in the layer.

 

EDIT: Ey, up. Wait a minuet your second sample is searching for tilesets right? Im not implementing any tilesets (have to readup on their purpose). Im creating a layer from my tilemap by the name of the layer in the maps json file. Then trying to apply the physics of that. Could this be the reason?

Link to comment
Share on other sites

Ah, I think I understand now. I hope. You want to have all tiles types be collidable, so long as its on the collision layer.

 

What I've seen a lot of people use is

map.setCollisionBetween(1, 10000, true, collisionLayer);

That sets the collision flag to true for every tile with a gid between 1 and 10000. So, unless you have more than 10000 different types of tiles in your map, all tile types.

Link to comment
Share on other sites

Thats exactly what im trying to achieve. I guess most people perform collisions by tile type rather than layer?

 

Anyhow your example did the trick. Does feel a little hacky though, does that have any performance issues do you know? 

 

Either way thanks for your help pal.

Link to comment
Share on other sites

FYI, I made a collision layer with two tiles in it. It is always the first layer in all my maps so I know the GIDs of the two tiles in it.

 

You could also do something like this:

  var tiles = layer.getTiles(0, 0, layer.layer.widthInPixels, layer.layer.heightInPixels);

Then iterate the tiles and check *their* properties. Assign a tile a property in Tiled by right-clicking on it in the tilesets tool window. You could, for instance, assign its collisionCallback and collisionCallbackContext.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...