3
\$\begingroup\$

I am working on a 2D action platformer in Pygame, though my question is a general one.

The question concerns selective collision resolution. In short, I want certain collisions to be ignored while my player sprite is rolling.

My player sprite has a roll state during which a controlled force is applied, moving the sprite forward until the roll animation finishes and the sprite's state changes to idle.

The sprite's bounding box doesn't change during this animation, since, as a rule, you don't want a sprite's bounding box to change size from frame to frame (see this answer).

My sprite is 64 pixels tall and I want him to be able to roll through 32 pixel gaps. Here's a diagram:

enter image description here

Currently, I do collision resolution during updates to my sprite's position. I first change his y-position according to his y-velocity, then check if there is rectangular overlap between my sprite and objects of a wall class. If there is, I place him flush with the wall. Then I update his x-position according to his x-velocity and do a similar collision check and resolution.

I was thinking I might be able to achieve my desired goal (rolling under walls) by flagging certain walls as "passable_while_rolling". The wall under which I'm rolling could be thus flagged. In my collision code, these walls would be ignored if the sprite was in the rolling state.

A problem would occur, however, if the sprite finished rolling while intersecting one of these walls. In that case, the collision code would kick in and resolve the sprite to one side of the wall in an unattractive manner.

Another option would be to just keep the sprite in the rolling state until he no longer intersects any flagged wall (similar to how you can't shift out of morph ball until you have overhead space in Metroid). I don't want to do this since I think looping the roll animation is ugly and unrealistic.

So, my questions are: What are my other options? How do other games deal with collision while rolling under walls?

I am open to drastically changing my collision resolution system.

\$\endgroup\$
  • \$\begingroup\$ I would use smaller bouncing box only when you roll. \$\endgroup\$ – furas Nov 25 '17 at 13:25
1
\$\begingroup\$

I implemented a solution I am happy with.

I flagged certain walls as "passable_while_rolling" and told my collision code to ignore these walls if the player was rolling.

To prevent the ugly scenario where the player stops rolling while clipping the wall, resulting in ugly resolution, I only start ignoring collision if the player is very near the wall on the first or second frame of his roll animation. I reinstate collision at the end of the animation, when the player sprite has safely cleared the wall. This way, if the player starts to roll from too far away, his roll animation will be on a later frame when he meets the wall, and the wall will simply block him from rolling any farther, preventing the ugly clipping.

The resulting gameplay feels good.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.