ID:2074614
 
(See the best response by Popisfizzy.)
#define center_x(O) (O:x*TILE_WIDTH + (ismovable(O) ? O:step_x + O:bound_x + O:bound_width/2 - 1 : floor(TILE_WIDTH/2)-1))
#define center_y(O) (O:y*TILE_HEIGHT + (ismovable(O) ? O:step_y + O:bound_y + O:bound_height/2 - 1 : floor(TILE_HEIGHT/2)-1))

proc
atan2(x,y)
return (x||y)&&(y>=0 ? arccos(x/sqrt(x*x+y*y)) : 360-arccos(x/sqrt(x*x+y*y)))

get_angle(atom/a,atom/b)
. = atan2(center_x(b) - center_x(a), center_y(b) - center_y(a))

get_angle_projectile(atom/a,atom/b)
. = atan2(center_y(b) - center_y(a), center_x(b) - center_x(a))


I cannot explain why, but my projectiles only shoot correctly with the x, y values reversed in atan2(), hence the two separate angle retrieving procs. I've tried many modifications and no luck.

Here's a video of the problem in action.

Is anyone willing to point out what the problem is and why?

Thanks.
Well then, the obvious answer is that your atan2 method is wrong somewhere. Try this instead, perhaps?
proc
arctan(x)
return arcsin( x / sqrt(x*x + 1))

atan2(x, y)
if(x > 0)
. = arctan(y / x)
else if(y > 0)
. = 90 - arctan(x / y)
else if(y < 0)
. = -(90 + arctan(x / y))
else if(x < 0)
. = arctan(y / x) + 180
else
. = 0

if(. < 0)
. += 360
In response to Popisfizzy
I get the same result.
Then the obvious answer is wrong! That's interesting. What happens if you get rid of the center_x and center_y stuff and just use this?
get_angle(atom/a,atom/b)
. = atan2(b.x - a.x, b.y - a.x)

I assume that those are to get things to look better visually. Have you ruled out they aren't the problem?
In response to Popisfizzy
I didn't consider trying that, but again I get the same result.

Then almost certainly the problem is converting from the angle you have into the direction you want the projectile to move (i.e., the Δx and Δy you're adding to x and y at each step). How are you computing those?
vel_x = sin(angle)
vel_y = cos(angle)

// ...

del_x = (vel_x * step_size) + rdel_x
del_y = (vel_y * step_size) + rdel_y
rdel_x = del_x - round(del_x, 1)
rdel_y = del_y - round(del_y, 1)

// ...

Move(loc, dir, step_x + round(del_x, 1), step_y + round(del_y, 1))


Where angle comes from get_angle() or get_projectile_angle() and the latter produces the correct movement.
Are you, by chance, computing the angle from the target to the source instead of the source to the target? Those two angles are different (specifically, arctan(x,y) = 360° - arctan(y,x)).
In response to Popisfizzy
Nope.

angle = ((target) ? (get_angle(src, target)) : (dir2angle(dir)))


And just for good measure, I reversed src and target to see how it acted and it was still incorrect.

My brain's officially wracked for the day. Going to sleep on it and see if I can come up with something when my mind is fresh.

Appreciate the effort, BTW.
Best response
Ah, shit, I think I see the problem
vel_x = sin(angle)
vel_y = cos(angle)

The cosine of an angle is the x coordinate of a point on the unit circle that has a ray with that angle passing through it (and likewise for the sine of an angle and the y coordinate). Thus, you want
vel_x = cos(angle)
vel_y = sin(angle)

That should fix your problem.
Look closely at your get_angle_projectile() function. You are feeding the arguments wrong to atan2. You are feeding y,x rather than x,y.

This is probably a symptom of using a combination of my functions and Kaiochao's functions. He and I fundamentally disagree on the orientation of angular components in games.

I obey the unit circle, he doesn't. So that's where your problem is likely coming from.

Also there's this:

vel_x = sin(angle)
vel_y = cos(angle)


cos() is used for x components and sin() for y components. You are doing them backward here too.
Look closely at your get_angle_projectile() function. You are feeding the arguments wrong to atan2. You are feeding y,x rather than x,y.

This is probably a symptom of using a combination of my functions and Kaiochao's functions. He and I fundamentally disagree on the orientation of angular components in games.

Very funny, this situation.

I was initially using Kaiochao's stuff, and at some point recently I decided to switch to yours, as it's easier to work with (personally). It was during that switch that I discovered I had been passing the arguments backwards for who knows how long.

At that moment I made the correction, but failed to consider the full scope of this change. So during my rewrite of projectiles yesterday, I largely referenced an older version of mine, which had everything backwards. This explains why the backwards get_angle() proc worked and the correct one didn't.

I'm not sure why I never considered vel_x/y to be the problem. Looking at it in hindsight, the fact that the backwards proc worked is a clear hint. This situation will remind me come the next problem to work from outside the box, in.

But I digress. I appreciate you both and thanks a lot.