SOLVED Four directional facing in a Zelda 1 type game

I have sprites with four facing directions, up right down left. I want them to be set when an instance is moving in those directions. This kind of code has a problem:

if yprevious > y {objFace = facing.up};
if yprevious < y {objFace = facing.down;}
if xprevious> x {objFace = facing.left;}
if xprevious< x {objFace = facing.right;}

It sets the facing correctly most of the time but I think it only does left and right directions when it's not moving diagonally at all. Moving up and right registers the same as moving right and up. I've tried a lot of solutions but they all run into the same problem. Maybe I need to measure the the angle of the movement?

The way I want it to work: Imagine a square with an X in it. The object is moving in the top triangle, it faces up. If it's moving in the right triangle, it's facing right, etc.

Thanks for any help with this.
 

Nidoking

Member
You'll want to check point_direction between the two points against odd multiples of 45 degrees, and make a special case for the right direction because that's anything less than 45 or greater than 315.
 

CMAllen

Member
Since you can move in eight directions but only have sprites for four of them, you're going to have to decide which of those sprites takes priority for the angles that don't have their own sprites. Right now, you're doing it by the order you're checking for position changes. From what you've said, your vertical movement checks happen after your horizontal movement checks, so they take priority. If you want to be able to move at those off-angles and keep the existing facing direction -- say you start moving in up and then add moving to the right to it -- you need code to account for an existing moving direction. You'll want the previous move angle and the current move angle. If the angle difference is greater than 45 degrees, then you set the facing direction.

Hope this helps.
 

NightFrost

Member
I think you'll want the sprite to change even when walking against an obstacle. In which case you'd use the movement speed variables calculated from your controls to get the direction, hspd and vspd or whatever you're calling them. Compare them against neutral position: point_direction(0,0, hspd, vspd) and you'll get direction angle of your current keypress. You're using keyboard movement I assume, so there's eight possible results: 0, 45, 90, 135, 180, 225, 270, 315. So you can safely divide by 45 to get a value from 0 to 7, each indicating a specific movement direction. You can then pick an appropriate sprite based on this number.

Of note: in computing angles start from the right and increase counterclockwise.
 
Thanks everyone. I assigned each angle in divisions of 45 degrees and decided which should be which. Because of the pathfinding, the enemies follow a stairstep pattern sometimes and there's a flickering issue that appears sometimes on diagonals when the angle is between two directions. The second one I think I can fix but the first one I don't think so. The first problem is not that big of a deal since it's supposed to look like a semi-authentic NES / Sega Master System game. I don't expect it to be super smooth.
 

NightFrost

Member
Sprite flicker is an effect of target direction rapidly flipping back and forth across the angle threshold where sprite changes. For example with sprites for eight-way movement the threshold between east and north-east would be at 22.5 degrees. One way to deal with this is to expand switch thresholds outward from all directions by several degrees, and track current sprite direction as an angle. So, if your current sprite is east facing (direction of zero degrees) and next step target switches more towards north-east, you change the sprite to one associated with that direction only if new heading is over 22.5 degrees plus 2, or 24.5 degrees. Conversely, when current sprite is north-east facing (direction of 45 degrees) and next step target is more towards east, you change the sprite for east facing only if new heading is less than 22.5 degrees minus 2 degrees, or 20.5 degrees. Or to put it shortly, you change sprite only if new target direction is over 24.5 degrees off from sprite's current facing direction. This ensures rapid, tiny directional flicker does not register visually. It would need to flicker across a 4-degree angle to be visible (and you could set the threshold even higher).
 
Sprite flicker is an effect of target direction rapidly flipping back and forth across the angle threshold where sprite changes. For example with sprites for eight-way movement the threshold between east and north-east would be at 22.5 degrees. One way to deal with this is to expand switch thresholds outward from all directions by several degrees, and track current sprite direction as an angle. So, if your current sprite is east facing (direction of zero degrees) and next step target switches more towards north-east, you change the sprite to one associated with that direction only if new heading is over 22.5 degrees plus 2, or 24.5 degrees. Conversely, when current sprite is north-east facing (direction of 45 degrees) and next step target is more towards east, you change the sprite for east facing only if new heading is less than 22.5 degrees minus 2 degrees, or 20.5 degrees. Or to put it shortly, you change sprite only if new target direction is over 24.5 degrees off from sprite's current facing direction. This ensures rapid, tiny directional flicker does not register visually. It would need to flicker across a 4-degree angle to be visible (and you could set the threshold even higher).
Thanks I'll do this at some point. It happens pretty rarely right now so I can live with it. Sometimes I spend too much time on very small things instead of adding more features. That said, sometimes you have to fix a small thing if it becomes a bigger problem down the road.
 
Top