Walking-Animation based on angle between character and destination

Started by
4 comments, last by Manuel Berger 6 years, 1 month ago

Hello fellow devs!

Once again I started working on an 2D adventure game and right now I'm doing the character-movement/animation. I'm not a big math guy and I was happy about my solution, but soon I realized that it's flawed.

My player has 5 walking-animations, mirrored for the left side: up, upright, right, downright, down. With the atan2 function I get the angle between player and destination. To get an index from 0 to 4, I divide PI by 5 and see how many times it goes into the player-destination angle.

In Pseudo-Code:
angle = atan2(destination.x - player.x, destination.y - player.y) //swapped y and x to get mirrored angle around the y axis
index = (int) (angle / (PI / 5));
PlayAnimation(index); //0 = up, 1 = up_right, 2 = right, 3 = down_right, 4 = down

Besides the fact that when angle is equal to PI it produces an index of 5, this works like a charm. Or at least I thought so at first. When I tested it, I realized that the up and down animation is playing more often than the others, which is pretty logical, since they have double the angle.

What I'm trying to achieve is something like this, but with equal angles, so that up and down has the same range as all other directions.

I can't get my head around it. Any suggestions? Is the whole approach doomed?

Thank you in advance for any input! :)
 

Advertisement

Okay, the answer for this case is
index = (int) |((angle / (PI / 4))| + .5f);
 

Moderator note: we prefer not to mark threads as solved on these forums. It gives others a chance to chime in with their own solutions.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Normally when dealing with animations like this just use an array to hold the sprites. That way your first line of code would have work with 2PI and /8.

The array looks like this [0: Up45 , 1: right, 2: Down45, 3: Down ,4: Down45,5: right,6: Up45,7: UP]. The last 4,5,6 will be mirrored.

Then it's just:

int Index = (Angle / (Circle/8)) -1;                     // (2PI)/8 or 360/8

What happens is that Circle/ 8  = 45 degrees. So if your half way (180 / 45) = 4 -1 = 3 the down sprite. 360/45 = 8 -1 = 7 the up sprite.

The nice thing here is that it's easy to understand and works with both PI and Degrees. The other nice thing is that if you wanted to use it for aiming at the mouse you can just use an array of 16.

MouseAimExample.jpg.77d27210654cf7c86e34b348c4937e52.jpg

Or just - 22.5 //((circle/amount)/2);

Vectors can also be used here as it has all the the info packed inside. In fact when working with an axis input like Up and Down vectors are often smoother.

Thank you very much Scouting Ninja! Great solution, I did't think about that :) I also thought about doing it with vectors, but I didn't know how, so this was the best I could come up with xD Again, thanks for a quick and elaborate reply.

@swiftcoder Makes sense! I won't do it again :)

This topic is closed to new replies.

Advertisement