Closed dibu28 closed 10 years ago
You're right, will look at that later. Used to work fine, so probably something really small :)
Have dug into this a bit more and will get a patch rolled out early next week.
Thank you. Waiting for patch.
Just to say that I've been looking in to this and it's quite a bit more complex than I thought. It's actually nothing to do with tilemaps themselves, but actually how fixedToCamera sprites work (and also sprites that follow the camera), that causes their bodies to go out of sync. Still digging...
I've digged a little bit. And find out that sprite.body.x, sprite.body.y and body.hullX.x, body.hullY.y (in separateTileX and separateTileY) contain screen coordinates. But should they contain coordinates of game world and not screen for tilemaps to work properly?
I actually made a lot of progress on this last night and the current implementation seems to be working great. Certainly fixed the tilemap demos I had previously and all the collision tests still work too. Please grab the latest dev branch release and test for yourselves.
Ok. Just tested on the last commit in dev. And Collisions with tilemap seems to be working now.
But there is a small bug appeared: if I press two buttons simultaneously and my sprite is moving diagonally (like sprite.body.velocity.x = 150; sprite.body.velocity.y = 150;) it can go through the tile if it collides exactly on the corner of a tile.(corner of sprite collided with corner of tile) While collisions set to true on every side (tileset.setCollisionRange(0, tileset.total - 1, true, true, true, true);).
Tested a little more. Moving sprite diagonaly I can even get through walls if I set "velocity" on x and y to big numbers like 500 or 1000.
That doesn't surprise me, you've basically just tunnelled through the wall. There's no ray casting implementation in Phaser yet, so tunnelling will be common if you allow too high velocities for your tile sizes.
I've thought about tunnelling, but if I move sprite only in one direction X or Y axis it stops at walls and not going through walls.
I'll experiment some more today, what size tiles are you using?
In "fill tiles.js" example it's 32x32 and today I've tried "sci fly.js" it's 16x16 px.
I've debugged a little bit today and found that the problem was in functions separateTileX and separateTileY in those cases this._maxOverlap is smaller then this._overlap (for example this._maxOverlap was 13 and this._overlap was 18) and adjustment of sprite position and velocitie was not executed for the first tile. But on the next step this._maxOverlap was 13 and this._overlap was 2 so the sprite stopped at the next tile.
I was just playing with this eariler and came to the same conclusion - that for tile separation max overlap isn't actually needed at all. I've just removed it, am pushing a new dev branch build now - please could you test against your samples and let me know if it works better for you.
I'm happy this is sorted now so I'm going to close it, but if you do find issues please open a new report (or re-open this if you like) and throw some sample code at me.
I'll test this couple of weeks later on my dev rig. For now it seems working fine.
I've tested a little more and there is one of the bugs still present. If (for example) I move sprite to the right and it hits the wall and I continue to press button to move right for a couple of seconds, sprite can jump through one or couple of bricks. I've debugged and find out that in this case DeltaX can change like this (-3, -5 ,-2, -150) and the DeltaX = this.x - this.preX; Where preX = 320 (which is correct) but this.x = 170 (which is wrong, the sprite inside the tiles).
The problem is in the folowing: It seems that the coordinates of the sprite are updated in some loop inside phaser which is not tied to RAF or timer. But collision detection is executed inside update method in the "sci fly.js" (game.physics.collide(sprite, layer);) which seems to be tied to RAF or timer. And if there is some frame drops or low fps occure then sprite continue to move (velocity continue to be added) but collision detection is not executed(becouse it is tied to RAF) and sprite gets far away through tiles.
The problem is hard to reproduce on desktop. I've used virtual machine with 2 cores to see it. And I think it can appear on some mobiles.
The question is: should the collision detection be executed right after coordinates of sprites are changed or am I missing some callback or method which can help to set this.
In the main (raf controlled) loop the Sprite positions and motion is updated during the world.update call. This is what runs updateMotion on a sprite body.
After this runs the state.update runs. This is when any calls to collide, changes in velocity etc are applied to the sprite.
Then there is a world.postUpdate call. This tells the sprite body to adjust the sprites position (just in time for rendering) based on its delta value.
All of this happens via a single raf loop.
I think you are on to something here though, i.e. you're getting very close to the source of a problem, but I'm not sure it's to do with code being executed out of sync unless it's possible for the core game loop to be called by raf while it's is already running which I'm pretty certain can't happen.
Just tested against 1.1.6 releaase and every thing seems working fine now.
Error: Collision in tilemaps doesn't work in dev branch.
In examples ("sci fly.js" and "fill tiles.js") if you try to scroll the tilemap then the tilemap is scrolling but it seems like it's collisions are not scrolling.