hexus / phaser-arcade-slopes

:triangular_ruler: A Phaser CE plugin that brings sloped tile collision handling to the Arcade Physics engine
MIT License
126 stars 16 forks source link

Player falling through tiles when moving quickly #8

Closed iCodeForBananas closed 7 years ago

iCodeForBananas commented 8 years ago

For whatever reason I fly up and gravity appears to bring me down through the ground.

It's hard to reproduce but tends to happen repeatedly when I fall very quickly.

screen shot 2016-07-04 at 12 20 17 am

http://www.youtube.com/watch?v=F_SRvUVgpWo

I tried adding the below code but to no avail:

//  We need to enable physics on the player
this.physics.arcade.enable(this.player)
this.player.body.setSize(GameConsts.PLAYER_BODY_WIDTH, GameConsts.PLAYER_BODY_HEIGHT, 105, 10)
this.game.slopes.enable(this.player)

// Add a touch of tile padding for the collision detection
this.player.body.tilePadding.x = 10
this.player.body.tilePadding.y = 10
hexus commented 8 years ago

I've had this issue and this is simply unavoidable with sprites too small that move too fast, especially with tiles that small. I frequently encounter this using the down control in the demo for the plugin (with and without the plugin enabled).

Phaser disables collision checking for internal faces (tiles surrounded by other tiles). It's optimal and ensures that there isn't any weird separation in the case that a player does get wedged in. Instead they just fall through, like the video demonstrates. Arcade Slopes follows suit, only checking the surface (outer-most) tiles for collisions. The rest have collision disabled.

If you're absolutely certain this a problem with the plugin, and not Phaser, feel free to share a demo and I'll look into it. I've tried to replicate the Arcade Physics collision behaviour as closely as possible so that adding the plugin to a project feels natural and unobtrusive; an addition rather than a full on change.

iCodeForBananas commented 8 years ago

Do you think if I lowered the gravity to slow the player down it would fix this? Maybe if the player overlaps push them back up a couple pixels?

hexus commented 8 years ago

Slowing the gravity would definitely help the situation yeah, because that's what causes the problem.

The player moves so far through the tile in one frame that the collision solvers push it out the wrong side (if they find it overlapping with a tile at all, they could be completely on the other side). If you increased the speed of the bullets they'd have the same problem; it's called tunnelling.

Look up continuous collision detection. It's an attempt to counteract this problem by checking multiple steps per frame/tick between the current and projected location.

http://gamedev.stackexchange.com/questions/34198/when-to-use-collision-detection-methods

iCodeForBananas commented 7 years ago

@hexus I have been doing a ton of testing trying to figure this out and I found that this also happens when framerate drops regardless of how fast you are moving.

iCodeForBananas commented 7 years ago

@hexus You wouldn't happen to have an example of Swept volumes are a way of using discrete detection that you mentioned in the attached stackoverflow answer?

hexus commented 7 years ago

Interesting. Does the same happen with regular arcade physics if framerate drops? If so, the plugin isn't missing anything.

I'm not fully aware of how to implement swept volumes, but it sounds interesting.

What I would attempt in this situation, personally, is multiple collision tests with the object position interpolated between it's previous and current position, between each frame. As soon as you collide with something you can bail out.

iCodeForBananas commented 7 years ago

Would you happen to have an example of this? I sort of understand what you're getting at but have no clue how to implement that.

iCodeForBananas commented 7 years ago

Would I be able to write this in the processCallback? http://phaser.io/examples/v2/arcade-physics/process-callback

iCodeForBananas commented 7 years ago

This wouldn't be what's need to fix this would it? http://phaser.io/examples/v2/arcade-physics/quadtree-collision-infos

hexus commented 7 years ago

I don't have an example to hand yet.

processCallback would run for each collision. Quadtrees are just a spatial partitioning technique used to narrow down candidates for collision detection.

Google is giving me smarter answers than I could ever give you. I was going to suggest a naive approach using a loop but there are better ways.

https://www.google.co.uk/search?q=swept+collision+detection

I might even build something into the plugin that solves this, eventually, perhaps using raycasts from each vertex of a body between each frame.

hexus commented 7 years ago

Is there a reason you re-opened this? It isn't an issue with the plugin. It should happen regardless of using this plugin or not.