Calculating angles and angular velocity?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Calculating angles and angular velocity?
by on (#215378)
RECCA is probably the best example of all that I'm going to ask here. Normally most of this stuff is really easy, but taking how limited the NES, is you don't have access to trigonometric functions which makes things a lot more complicated.

1. Aimed shots. I know a lot of games do this but I never understood how they do this. As a side thing, I'd also like to know how to add angular offset (as shown by the enemies in the picture below by shooting a 3-way shots).
Attachment:
Summer Carnival '92 - Recca (Japan)-18.png
Summer Carnival '92 - Recca (Japan)-18.png [ 4.21 KiB | Viewed 2309 times ]


2. Homing shots. Somewhat common, but still a mystery in to me.
Attachment:
Summer Carnival '92 - Recca (Japan)-20.png
Summer Carnival '92 - Recca (Japan)-20.png [ 7.42 KiB | Viewed 2309 times ]


3. Angular velocity. RECCA also has an enemy that has other objects spinning around it, which I know for a fact that creating such movement requires changing the angle x amount of degrees every frame to make it seem like its turning.
*no pucture for this one :c

4. Bonus! I don't even know how to explain this. I'm talking about that 'hand' in the top left corner. It starts retracted(?) and starts to extend out and reach out towards the player. I can't even figure out how to program something like that with the mathematical capabilities modern languages have...
Attachment:
Summer Carnival '92 - Recca (Japan)-19.png
Summer Carnival '92 - Recca (Japan)-19.png [ 7.85 KiB | Viewed 2309 times ]
Re: Calculating angles and angular velocity?
by on (#215380)
Have you looked in the source code of Thwaite to see how it does aiming? The getAngle subroutine in math.s does the equivalent of atan2 to find the approximate angle of a vector from (x1, y1) and (x2, y2). Then once you have the angle, you can use sine/cosine tables with one entry for each angle to set a bullet's velocity.

A homing shot just repeats the aiming process for a bullet every 6 or 12 frames or whatever.
Re: Calculating angles and angular velocity?
by on (#215389)
For aiming, I use a formula I'd like to remember where I got it from (sorry). It's FAR (and I mean FAR) from perfect, but it seems to get the job done, at least in the instances I've used it:

Code:
dx = DELTA (x0, x1);
dy = DELTA (y0, y1);
aux = MIN (dx, dy);
distance = dx + dy - (aux >> 1) - (aux >> 2) + (aux >> 4);

aux = (V * dx / distance); vx = ADD_SIGN (x1, x0, aux);
aux = (V * dy / distance); vy = ADD_SIGN (y1, y0, aux);


Macros are roughly as follows:

Code:
#define MIN(a,b)                   ((a)<(b)?(a):(b))
#define DELTA(a,b)                  ((a)<(b)?(b)-(a):(a)-(b))
#define ADD_SIGN(a,b,v)            ((a)==(b))?(0):(((a)>(b))?(v):(-(v)))


All are signed fixed point variables.
Re: Calculating angles and angular velocity?
by on (#215402)
The basic idea is that the ratio between the horizontal and vertical distances (deltas) between two objects will tell you the angle between them. That's what the atan2 function is for (there are a few implementations of it in 6502 ASM, using look-up tables or approximations). Once you have the angle, you can use sines and cosines to move in that angle. You can also use the angle to draw the correct sprite for the object/projectile moving in that angle.
Re: Calculating angles and angular velocity?
by on (#216284)
So in other words to aim a projectile at something I need to make a lookup table that contains all possible X and Y distances between the two objects? If you'd simply take X and Y coordinate distances and use those as a pointer to where to read the angle, that would make a very large table if you account every possible pixel on screen. Once you have the angle I'm assuming you can simply use another table to extract the correct X and Y speeds from the angle that was returned from the other table. The size of the table is kinda worrying if I'd were to use this method. There has to be some other way to create the table that is smaller in size.
Re: Calculating angles and angular velocity?
by on (#216289)
Having a table indexed by every possible delta X/Y combination is not really feasible, the table would be huge. Instead, we normally we use a table to translate DeltaX divided by DeltaY (i.e. the ratio between the deltas) into an angle, which's a much smaller table. Divisions are slow on the 6502 though, and a common "trick" to speed this up is to use a log table and do a logarithmic division of the vales, which is just a subtraction, and use that result to lookup the angle in another table. You also need some extra logic to handle the different quadrants/octants.

Here's an example of such a routine: http://codebase64.org/doku.php?id=base: ... -bit_angle