Closed IkonOne closed 7 years ago
Does this not occur with the plugin disabled?
From a glance it might be because the plugin isn't really checking whether the body is moving into the tile on each axis, it's just checking for the shortest separating axis.
Depending on where your body ends up in the tile, it could affect separation and velocity differently, but I have indeed observed this problem myself and it bothers me, so it's something I will endeavour to fix.
Pure arcade physics works differently in the sense that it checks one axis before another, but SAT isn't quite the same.
No it doesn't happen without the plugin.
That was what I suspected the cause was. I'll get a pull request in later today once I get a test project up.
Cool, I'd be happy to look into a solution at some point. I think gravity that's higher than the player's X velocity is a good way to reproduce this.
This bit of code fixes the issue:
if (response.overlapN.x * body.velocity.x + response.overlapN.y * body.velocity.y < 0) {
return false;
}
Placed hereish:
https://github.com/hexus/phaser-arcade-slopes/blob/master/src/ArcadeSlopes/SatSolver.js#L613
All this is doing is checking the sign of the dot product of overlapN and velocity. A negative value means that the vectors are pointing opposite directions. There could be fringe cases where this breaks though.
Yeah, I actually considered keeping this check at one point, as I'd observed the same check in Metanet's code, but left it out for some reason.
I'll implement this properly soon using the SAT vectors. Thanks for looking into this. :+1:
I saw you left a TODO for it somewhere in your code actually.
Ah, sounds like something I'd do. :full_moon_with_face: There's always something for me TODO
.
Weird, applying that change breaks collisions for me. Using > 0
instead fixes collisions again, though I haven't verified if this still fixes your issue. This is most likely because I invert the overlap vectors for convenience.
if (response.overlapN.dot(body.slopes.velocity) > 0) {
return false;
}
Does this snippet in the same location work for your use case?
Edit:
Actually, I've noticed this does cause a lot of issues elsewhere unfortunately - slipping through tiles in rather strange ways. Unfortunate, because I thought this had also solved a similar issue I'd noticed when travelling past corners of sloped tiles.
Even inverting the overlap vector back will exhibit the same issue:
if (response.overlapN.clone().scale(-1).dot(body.slopes.velocity) < 0) {
return false;
}
Edit 2:
It does work with body.velocity
instead of body.slopes.velocity
, the latter of which isn't up to date at that point. Nice.
Hopefully the above commit should solve the issue now. :grin: :+1:
Yes this works great.
I would push back on the clone though. I think allocating memory for a single check is less than ideal.
Yeah, I totally agree. While it keeps the code "looking cleaner" I'm totally aware of the implication of cloning, which I do all over the place at the moment (sometimes unavoidably).
I'm planning to sweep the whole module for instantiations like this, among other things, for v0.3.0.
As seen in the example gif, the cowboy looking thing is moving at x speed and once it hits the corner, it is stopped and begins accelerating again. The expected behavior would be for it to continue without 'catching' the corner.
I haven't investigated the cause yet.