grapefruitjs / grapefruit

Outdated, I recommend you use photonstorm/phaser instead!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How do I programmatically set a tile as collidable?

krazyjakee opened this issue · comments

The buzz words I looked for in the grapefruit source were 'hitarea' and 'static'. I'm presuming that static is applied to the body of something that is collidable but it also has to have a hitarea?

Is there a simple utility already available that allows me to do this?

I understand that map editor has its tile properties in the tilemap but I want to set mine programmatically.

thanks

Settings those properties in the tilemap just tells the renderer how to create the physical bodies for a tile. When you enable physics on any object the collision shape created for it is based on whatever is in the hitArea property. You can put a Rectangle, Circle, Polygon or any shape in there and then enable physics.

Setting a tile to static means that the mass is also infinite (you could also say mass: 1 to make it collidable but not static). All you need to do is get the tile, set the hitArea (collision shape), set the mass, and enable physics:

//`map` is the instance of the tilemap
//`game` is the instance of the grapefruit game

var tile = map.findLayer('myLayer').tiles[tileX][tileY];

tile.hitArea = new gf.Rectangle(0, 0, 10, 10); //rectangle with offset (0, 0) and 10 width / 10 height.
tile.mass = Infinity; //Infinity means it is static (never moves)
tile.enablePhysics(game.physics);

I realized you may have meant how to change a tile to be physics whenever it is shown onscreen (i.e let the engine do it for me). To do that, you would have to access the definition of the tile in the Tileset object. Currently this is possible but highly involved (requires knowledge of Tiled format). To be able to do this, you will need to know the tile's ID and basically set those properties yourself.

Until there is a setter, you should be able to do:

var tileset = map.getTileset(tileId),
    props = tileset.tileproperties[tileId] || {};

props.hitArea = new gf.Rectangle(0, 0, 10, 10);
props.mass = Infinity;

tileset.tileproperties[tileId] = props;

I'll add an easier way to accomplish this in v0.2

this worked but I have found further issues, for instance a correct hitarea for a 32x32 tile was:
tile.hitArea = new gf.Rectangle(-32, -32, 64, 64);

Anyway, the initial problem is solved.

That isn't an issue, the hit area is based on anchor. So if your anchor is (0.5, 0.5) then your hit area would definately have to be like you describe.

I am keeping this open as a tracker for adding those setters.