Hey everyone. I'm having some trouble coming up with a simple set of rules to implement decent floor collision. The problem is mainly about slopes, and I'll present it with a series of sketches.
This is how the regular hitbox of the player would collide with a slope. This is not the desired behavior, as the art for the character would appear to not be standing on the floor (not without special angled sprites, at least).
In order to fix the problem above, we can shift the collision data to the left by half the character's width when a slope is detected (slopes can be detected when one of the edges of the hitbox is on the ground but the other is not) in order to center it and make it look more stable:
Now, although the hitbox is colliding with the displaced version of the ground at the exact same point as before, because it is displaced it looks more correctly placed than before. This is great because every object, regardless of it's width, will seem to have it's central point colliding with the ground, as opposed to the quick fix of using art that differs from the collision data in hopes to compensate the bad positioning (but this would only work well for objects of a certain width).
Now, the fix proposed above should work well for slopes, but there are a couple of problems caused by it. Look at this:
In this case, we do not want the character to fall yet, because it'd have half of it' body stuck into the wall while doing this. So we must find a way to tell slopes and pits apart, so that the collision data is not displaced on pits. This can probably be detected by looking at the sudden height decrease, so it's not such a big deal. Also, pits must be detected anyway to make the character start falling.
Now here's one thing I have no idea how to deal with:
If the slope ends directly in a pit, there seems to be no way to make sure the character has the whole hitbox out of the wall before falling. I've been looking at some games, and Mega Man X on the SNES seems to handle this last case pretty well. On the Armadillo stage, there are some quite good slopes to try this stuff on. When you reach the end of the slope, instead of falling down you keep moving in a straight horizontal line until the whole hitbox is completely free to fall.
This means that Mega Man X behaves exactly as I'd like the characters in my project to. To only problem is that I can't seem to find a decent rule to fix this last problem that will be compatible with the other rules. Does anyone have any ideas? Can anyone think of a different set of rules to make this whole thing work?
This is not for my NES project, but for an ActionScript 3 game I'm making for college. The game doesn't really need to behave like this, but I'll have to deal with this kind of thing anyway later for my personal projects, so I decided I'd use this game as a testing ground. If anyone has anything to contribute, I really appreciate it.
Code:
\
\
\ +---+
\ | |
\ | |
\ | |
\ | |
\o---+
\
\
\
\
\
\ +---+
\ | |
\ | |
\ | |
\ | |
\o---+
\
\
\
\
This is how the regular hitbox of the player would collide with a slope. This is not the desired behavior, as the art for the character would appear to not be standing on the floor (not without special angled sprites, at least).
In order to fix the problem above, we can shift the collision data to the left by half the character's width when a slope is detected (slopes can be detected when one of the edges of the hitbox is on the ground but the other is not) in order to center it and make it look more stable:
Code:
\
\
\ +---+
\ | |
\ | |
\ | |
+-> \ | |
| \+-o-+
| \ \
displaced \
collision map \
\
\
\ +---+
\ | |
\ | |
\ | |
+-> \ | |
| \+-o-+
| \ \
displaced \
collision map \
\
Now, although the hitbox is colliding with the displaced version of the ground at the exact same point as before, because it is displaced it looks more correctly placed than before. This is great because every object, regardless of it's width, will seem to have it's central point colliding with the ground, as opposed to the quick fix of using art that differs from the collision data in hopes to compensate the bad positioning (but this would only work well for objects of a certain width).
Now, the fix proposed above should work well for slopes, but there are a couple of problems caused by it. Look at this:
Code:
\
\ +---+
\ | |
\ | |
\ | |
\ | |
\---------o-+-+
|
|
|
|
\ +---+
\ | |
\ | |
\ | |
\ | |
\---------o-+-+
|
|
|
|
In this case, we do not want the character to fall yet, because it'd have half of it' body stuck into the wall while doing this. So we must find a way to tell slopes and pits apart, so that the collision data is not displaced on pits. This can probably be detected by looking at the sudden height decrease, so it's not such a big deal. Also, pits must be detected anyway to make the character start falling.
Now here's one thing I have no idea how to deal with:
Code:
\
\ +---+
\ | |
\ | |
\ | |
| |
+-o-+
|
|
|
|
|
|
\ +---+
\ | |
\ | |
\ | |
| |
+-o-+
|
|
|
|
|
|
If the slope ends directly in a pit, there seems to be no way to make sure the character has the whole hitbox out of the wall before falling. I've been looking at some games, and Mega Man X on the SNES seems to handle this last case pretty well. On the Armadillo stage, there are some quite good slopes to try this stuff on. When you reach the end of the slope, instead of falling down you keep moving in a straight horizontal line until the whole hitbox is completely free to fall.
This means that Mega Man X behaves exactly as I'd like the characters in my project to. To only problem is that I can't seem to find a decent rule to fix this last problem that will be compatible with the other rules. Does anyone have any ideas? Can anyone think of a different set of rules to make this whole thing work?
This is not for my NES project, but for an ActionScript 3 game I'm making for college. The game doesn't really need to behave like this, but I'll have to deal with this kind of thing anyway later for my personal projects, so I decided I'd use this game as a testing ground. If anyone has anything to contribute, I really appreciate it.