I would hope that we have all played Zelda: A Link to the Past, please correct me if I'm wrong, but I want to emulate that kind of 2D, top-down character movement with a touch of correction. It has been done in other games, but I feel this reference would be the easiest to relate to. More specifically the kind of movement and correction I'm talking about is:
- Floating movement not restricted to tile based movement like Pokemon and other games where one tap of the movement pad moves you one square in that cardinal direction. This floating movement should be able to achieve diagonal motion.
- If you're walking West and you come to a wall that is diagonal in a North East/South West fashion, you are corrected into a South West movement even if you continue holding left (West) on the controller. This should work for both diagonals correcting in both directions.
- If you're a few pixels off from walking squarely into a door or hallway, you are corrected into walking through the hall or down the hallway, i.e. bumping into the corner causes you to be pushed into the hall/door.
I've hunted for efficient ways to achieve this and have had no luck. To be clear I'm talking about the human character's movement, not an NPC's movement. Are their resources available on this kind of movement? Equations or algorithms explained on a wiki or something?
I'm using the XNA Framework, is there anything in it to help with this?
Answer
Well, the first bullet point is easy. You simply store and manipulate the character's position in world or pixel coordinates instead of tile-based coordinates. If you were having an issue with this, it might be due to a a confusing choice of representation for your world and tile space, so perhaps you should post more details about it / ask a separate, specific question.
For the second point, the most direct approach would be to take the player's (normalized) movement vector and add it to the wall's normal vector, then renormalize. The sign of the components of the resulting vector will indicate how the wall relates to the player's motion while the vector itself indicates which direction the player may now move.
For the third point, assuming you have collision rectangles for both the wall and the player, you should be able to determine how much of the player's collision rectangle contacts with the wall's collision rectangle. If, for example, the player is moving to the right and hits a vertical wall, you compare the Y axis extents of the collision rectangles -- if if the player's extent exceeds the wall's extent by some threshold, say 75% of the player's Y axis extent, then you "cheat" the player towards the door.
I've made a fair number of assumptions here in how your object model looks in your code and what techniques you've chosen -- largely due to the generality of your question. I've tried to suggest approaches that are simple (although perhaps not optimal) for the same reason. If you can provide more specific information, either in this question or in a new one, I can try to provide more details or a better idea.
No comments:
Post a Comment