Jump to content

phaser 2.0.3 to 2.0.4 - how to get tilemaps working again


valueerror
 Share

Recommended Posts

huh.. that update completely broke all of my tilemap/collision code..  

 

i now have to setCollisionBetween (or collisionByExclusion) to get my player to collide with something (this wasn't necessary before but why not)

 

map.getTileWorldXY always returns a tile..  even if there is none..  :(  in phaser 2.0.3 it returned false if there was an empty tile.

for example i check for a tile on an invisible layer and if there is a tile my player can climb... now i can climb everywhere..

 

 

also createFromObjects goes completely nuts..  objects are created but not scaled and positioned in the upper left corner of the screen and they don't move or collide ...

 

my chain (can be found in examples) is also broken.. 

 

:wacko:

 

i tried my best, read the changelog, the docs, but i couldn't get anything to work..

 

thx for any help!

 

Link to comment
Share on other sites

Yes in order to fix a load of other issues (things like Tilemap.fill not working on blank maps) getTile and getTileXY now always return a Tile object. However 2.0.4 shouldn't have changed the API like this, so I've modified it so it will return null again if the tile has an index of -1. This fix is now in the dev branch.

 

I don't understand this bit though:

 

"i now have to setCollisionBetween (or collisionByExclusion) to get my player to collide with something (this wasn't necessary before but why not)"

 

 

You've always had to set collision one way or another. What did you mean?

 

also createFromObjects goes completely nuts..  objects are created but not scaled and positioned in the upper left corner of the screen and they don't move or collide ...

my chain (can be found in examples) is also broken..

 

 

Your chain example still works fine for me, as does the createFromObjects test, so this is a bit confusing.

 

Update: Ok for some reason when I test these things out locally they work fine (I do test quite a lot before release!) because I inline each source file on its own. But when I use the single phaser.js file they are indeed broken as you describe. So something must have buggered up in the build process. I'm looking into it now to figure out what.

Link to comment
Share on other sites

cool thx! will try it after work.. as for the "i now have to set collision between" part.. no. this line wasn't needed before..

i created the layers.. created the arrays of physics bodies and then used a for loop to set collisiongroups and materials.. done.

that way all tiles of my tileset collided with my player and thats ok because i use another approach for non collision tiles - they are on their own layer (i also have a layer that only collides with enemies...)

Link to comment
Share on other sites

i don't understand it either :)  but it's true..  this is my code

map = game.add.tilemap('trainingmap');map.addTilesetImage('mariotileset');
and then i call  a custom function
setupLayers();
function setupLayers(){     //create layers    layerbackground = map.createLayer('background');    layerropes= map.createLayer('ropes');    layerropes.alpha=0;    layerice = map.createLayer('icelayer');    layerenemy = map.createLayer('enemylayer');    layerenemybounds = map.createLayer('enemybounds');    layerenemybounds.alpha=0;   //only enemies need to "see" (collide) with this one so they don't drop in holes..    layermain = map.createLayer('mainlayer');    layermain.resizeWorld();  // this stretches the world to the size of layermain       //make physic bodies for each and every tile on the layer    layermain_tiles = game.physics.p2.convertTilemap(map, layermain);    layerice_tiles = game.physics.p2.convertTilemap(map, layerice);    layerenemy_tiles = game.physics.p2.convertTilemap(map, layerenemy);    layerenemybounds_tiles = game.physics.p2.convertTilemap(map, layerenemybounds);       //setup all tiles with collisiongroups or materials    for (i=0; i<layermain_tiles.length; i++){        layermain_tiles[i].setCollisionGroup(groundCG);        layermain_tiles[i].collides([playerCG,fireballCG,powerupsCG,enemyGroundCG]);        layermain_tiles[i].setMaterial(groundMaterial);        }    for (i=0; i<layerenemy_tiles.length; i++){        layerenemy_tiles[i].setCollisionGroup(enemyGroundCG);        layerenemy_tiles[i].collides([playerCG,fireballCG]);        layerenemy_tiles[i].setMaterial(groundMaterial);    }    for (i=0; i<layerice_tiles.length; i++){        layerice_tiles[i].setCollisionGroup(groundCG);        layerice_tiles[i].collides([playerCG,fireballCG,powerupsCG,enemyGroundCG]);        layerice_tiles[i].setMaterial(iceMaterial);    }    for (i=0; i<layerenemybounds_tiles.length; i++){        layerenemybounds_tiles[i].setCollisionGroup(enemyboundsCG);        layerenemybounds_tiles[i].collides([enemyGroundCG]);    }}

that's it .. i swear :)

 

and it works ... here:   http://test.xapient.net/phaser/ALL/    (still with phaser 2.0.3  - this will be updated in the next 2 days when i sorted out the other problems i have with the update..

 

 

oh.. there comes the next question.. i think all the other problems have the same source

until now i could define several options for my objects in the mapeditor "tiled" ..    i create from objects and use the variables i've already set up in tiled to make my objects move or whatever..  

 

here an example from my json file:

{                 "gid":153,                 "height":0,                 "name":"horizontal",                 "properties":                    {                     "distance":"256",                     "velo":"100"                    },                 "type":"",                 "visible":true,                 "width":0,                 "x":2624,                 "y":640  }

this is my horizontal moving platform.

i know what distance it should move and how fast (velo) and when i initialize this platform i can do something like 

 

if (platform.name === 'horizontal') {}   //this still works

 

or

 

platform.body.velocity.x = platform.velo;    // here i use the variable assigned in tiled  - this does not work anymore and is responsible for a bunch problems in my demo game

 

did you disable this "feature" intended? are those variables still accessible in a different way now?

 

btw.  thx rich for your time and help here :)

 

 

 

 

 

 

 

 

 
Link to comment
Share on other sites

this is my horizontal moving platform.i know what distance it should move and how fast (velo) and when i initialize this platform i can do something likeif (platform.name === 'horizontal') {}   //this still worksorplatform.body.velocity.x = platform.velo;    // here i use the variable assigned in tiled  - this does not work anymore and is responsible for a bunch problems in my demo gamedid you disable this "feature" intended? are those variables still accessible in a different way now?

Nothing has changed with regard to Object properties and the way they are created.

 

The code doing this hasn't changed since it was first added in 2.0.0 (commit 1746afe477c8f0b6972333f55234c6c98637e49c)

 

re: collision - you're right, for some reason it was converting tiles into bodies. However it shouldn't have been, I'm afraid you were exploiting a bug - my intentions for the method are clear from the docs: http://docs.phaser.io/Phaser.Physics.P2.html#convertTilemap - you can see I always intended for you to HAVE to set the collision range first. The fact it allowed tiles through anyway was sadly not intended.

Link to comment
Share on other sites

haha.. sorry..    not everything works as expected..  

 

until now i could use the the postBroadphaseCallback to determine if my player was entering the alledged collision space from below and return false in that case..  (the mighty jump through from below platform)

 

for some reason this worked:

  if (body1.sprite.name === 'mario' && body2.sprite.key === 'movingplatforms'){return false; }

if body1 was mario it ALWAYS was moving upwards to the other object

in 2.0.5 if body1 is mario it ALWAYS approaches from the right  (and its body2 if coming from left/bottom/above)

 

so this (maybe accidental) "feature" is not usable anymore.. i now have to find out the velocity of mario to determine if he is moving upwards.. no problem? unfortunately not .. because:

mario lands on a moving platform ...  this platform moves vertically and therefore the equation if mario has a Y velocity upwards returns positive.. and it  (almost) falls through again..   :(

 

do you have any other idea how to solve this - it was working so well before with this nifty little trick.. 

Link to comment
Share on other sites

hey valueerror, 

 

Just wanted to let you know: You're really doing a great job keeping up with the phaser versions and making sure the p2-phaser engine is up to "jump & run".

 

My platformer is still on the backburner .. (since the engine trouble in 1.x before the switch to p2 and phaser version 2).

(But also because there is other fun stuff to code.)

 

I plan to pick it up again when there is native support for sloped tiles ;) - and looking forward to gathering all the great information that you put into your mario demo.

(Hope that is ok.)

Link to comment
Share on other sites

I have no control over the order bodies come back from the postBroadPhase sweep, it's down to P2. However what you could certainly do is set your Mario sprites name property and then check body.sprite.name in the callback.

Link to comment
Share on other sites

I have no control over the order bodies come back from the postBroadPhase sweep, it's down to P2. However what you could certainly do is set your Mario sprites name property and then check body.sprite.name in the callback.

hmm.. that's exactly what i do and demonstrated in the code above.. so i know which body is mario...but what next...

@jpdev.. that's exactly what my demo is for.. a playground for platformer ideas and if you could use some of them ..great! (but let me know when you found better solutions)

Link to comment
Share on other sites

Hey valueerror,

 

This kind of feels like a workaround.. what if there are multiple "pass through from below" platforms stacked above each other..

.. then you will fall through the lower one, since the sensor is touching the upper one.

 

Also, correct me if I am wrong, but the code reads like it disables all collision when the upper sensor is active.. so if there was a wall next to one of those platforms, then you could walk trough it, as long, as the platform is above your head (right?).

 

Makes me think, if the platform came down 50 pixels more, would mario fall through the ground?

 

That's what I mean it feels like a workaround, not a "correct" solution.

 

I would wish there was "real" support for this kind of interaction (that's pretty standard for any jump and run).

 

(A property where you could set the "path-through" direction for an object or something like that.)

Link to comment
Share on other sites

yeah.. you're right!  this is definitely a workaround...   in arcade physics i would write a custom collision handler just for these platforms and let the player through if his velocity is upwards..  better but not perfect..    in p2 there also seems to be no perfect solution..  

 

if the platform came down 50 more pixels you would fall down.. maybe..   at least as long as the platform is touching the upper sensor there would be a race between the lower and the upper sensor.. same goes for walls ... so as long as the wall or the ground are several pixels thick you wouldn't fall through but sink into the ground for a second...

 

i have another approach that is working quite well  (it is the same way i would do it in arcade physics but it's a bit tricky and unfortunately it is also quite buggy)

 game.physics.p2.setPostBroadphaseCallback(checkOverlap, this);function checkOverlap(body1, body2) {    if (body1 && body2){        if(body1.sprite && body2.sprite){           if( ( body1.sprite.name === 'mario' && body2.sprite.key === 'movingplatforms')||( body2.sprite.name === 'mario' && body1.sprite.key === 'movingplatforms') ){                    if (player.body.velocity.y > 10){return false;  }            }        }    }    return true;}

so for every 2 objects that are possibly colliding (postbroadphase) i check if the pair consists of my player and one of my moving platforms.. then i check the player velocity and return false if he is coming from below..  BUT  if  the velocity is getting lower than 10 it will collide again and shoot my player out of the platform in a random direction with high velocity..  if i would take a smaller velocity for the equation .. lets say 1 or even 0  the player would fall through the platform when it is going UP (because then the player has also suddenly a Y velocity higher than 1...     http://test.xapient.net/phaser/ALL/  (try this approach here.. try to jump into the platform slow enough so you won't pass it for a test)

 

 

 so  yes.. i also whish there was real support for this but rich also suggested to use sensors..

for now this seems to be the cleanest and most reliable solution..  i just have to make sure that those platforms won't trigger one of the mentioned special cases.. but that's easy to solve during leveldesign.. also the distance to the upper sensor could be much smaller..

 

BUT.. i'm not giving up.. maybe i need more sleep to come up with the perfect solution or rich implements the ability to turn of collision bounds on a specific side of a rectangular shape.. i think this is already working with tiles.. there is a "collideDown (boolean)"  property..   or you have an epiphany ?

Link to comment
Share on other sites

heya.. came up with a possible solution.. its a combination of both approaches.. the upper sensor switches the value of a custom var to true and the lower sensor to false.. in the postbroadphase callback, if this var is true and the other object is a platform it will return false.. that way collisions with everything else will remain active.. gotta try it tomorrow.. nexus7 not good for programming ;)

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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