Log In  


Cart #rotating_triangle-0 | 2020-05-10 | Code ▽ | Embed ▽ | No License
1

Hello

I'm in the process of making a triangle-based game. I'm looking for some advice on how to achieve this as I have been banging my head off a wall with it for about a week now. I'm probably doing this a really dumb way.

I've posted a small cart with an extrapolation of the sections I'm having difficulty with.

I'm trying to get the triangle in the centre of the screen to rotate towards the player (in this case the player is a green cross moved with the arrow buttons). The rotation should not be instantaneous - the enemy triangle in the centre must turn towards the player at the speed defines as enemy.turnspeed - I have some (quite messy) code that turns the triangle towards the player but it breaks down at a couple of points.

The main problem is when the player passes the enemy's y-coordinate on the left side the triangle starts turning the other way. This seems to be due to the way the angles are calculated as this seems to be the point where the target angle wraps past 0.

The other problem is probably related - if the player object goes around the enemy quickly enough it will continue turning one direction even if it would be more optimal to turn the other direction.

This all seems to be stemming from my use of the target angle and calculating whether it is greater or less than the enemy's aim direction.

So in short, I am trying to work out a better way to do this that actually works.

Apologies if this seems vague or messy - I'm pretty new to all of this stuff and there's no doubt a bunch of stuff that's pretty wrong with what I'm doing...

1


1

That's a common issue. You want to use the signed angle between current and target, rather than the smallest absolute angle between them, so you know in which direction to turn. So you want an angle between -180 and 180 deg (in PICO-8, -0.5 and 0.5).

You use atan2 which returns a value between 0 and 360 deg, i.e. [0.0, 1.0). You just need to remap this to [-0.5, 0.5) (round bracket means excluded, but it doesn't matter here, as 180 and -180 turns are both the shortest).

There are a few ways to do this:

a. You could manually check for angle > 0.5 and subtract 1.0 to remap [0.5, 1.0) to [-1.0, -0.5)
if angle > 0.5 then
  shortest_angle = angle - 1.0
else
  shortest_angle = angle
end

b. Use a float modulo on the offset value, then offset back:

shortest_angle = (angle + 0.5) % 1 - 0.5

Thank you so much, it looks like I've got it working correctly now!



[Please log in to post a comment]