#65654 - christosterone - Wed Jan 04, 2006 7:59 pm
hi i have the following projectile struct
Code: |
typedef struct projectile
{
bool active;
u16 x;
u16 y;
u16 angle;
u8 type;
};
|
and i need to know what code i should have to move the projectile 1 unit at a time in my game loop.
ex.
Code: |
//somewhere in main game loop
if( projectiles[0].active )
{
// move projectile
}
|
thanks
chris
#65655 - keldon - Wed Jan 04, 2006 8:42 pm
Having data as u8 or u16 will most likely not do you any favours.
Angle can often be better conveyed with a vector (direction and magnitude). Vectors are usually stored only as x and y. Magnitude is calculated by sqrt(x^2 + y ^2). You can then use your vector to move using its x and y and also use its vector for collision detection too when moving.
Using a vector also allows you to easily apply gravity and physics if need be with ease. For example a physics implementation (minus collision) of the soda world in about 30 lines of code.
#65657 - thegamefreak0134 - Wed Jan 04, 2006 8:47 pm
What we really need to know is what the projectine needs to do. Actually moving the projectile is a simple matter of updating it's position and re-copying the OAM. I don't know if that differs with devkits though...
_________________
What if the hokey-pokey really is what it's all about?
[url=http:/www.darknovagames.com/index.php?action=recruit&clanid=1]Support Zeta on DarkNova![/url]
#65664 - sajiimori - Wed Jan 04, 2006 9:59 pm
Agreed that vectors are the way to go. You'll also need to use fixed-point math because there's no way to move 1 unit at an angle without moving a fraction of a unit in each direction.
If you've got any questions about fixed point math, vectors, or how to make a vector that's 1 unit long, we can help with that.
#65707 - christosterone - Thu Jan 05, 2006 2:44 am
yea all i need is the code that will move vector by one incrament (vector length) at a time. i should probably make my x and y doubles. i can convert to u16s when im making the screen sprites later but i need precision now.
so i think this would be a better struct
Code: |
typedef struct projectile
{
bool active;
double x;
double y;
u16 angle;
u8 type;
u8 speed;
};
|
now i believe this code would find the next position
Code: |
projectile bullet;
//assume i set values to the struct...
//moving bullet, included SIN[] and COS[] tables in header file
void moveBullet()
{
double newx = bullet.x + SIN[ bullet.angle ];
double newy = bullet.y + COS[ bullet.angle ];
bullet.x = newx;
bullet.y = newy;
}
|
now i would incorporate the speed function so i can check for collisions at every step (instead of moving the bullet in lengthy bursts)
Code: |
u16 loop;
for( loop=0; loop<bullet.speed; loop++ )
{
moveBullet();
checkCollisions(); // assume i made this somewhere
}
|
would it be better to move the bullet in steps then check for collisions (as depicted above) or to just make it move in bullet.speed bursts like this:
Code: |
void moveBullet()
{
double newx = bullet.x + bullet.speed * SIN[ bullet.angle ];
double newy = bullet.y + bullet.speed * COS[ bullet.angle ];
bullet.x = newx;
bullet.y = newy;
}
|
#65713 - sajiimori - Thu Jan 05, 2006 3:30 am
If you're set on using angles instead of velocity vectors, it looks like you already have some code.
I agree that you need fractional precision, but the GBA doesn't have floating point hardware so it's emulated in software. Use fixed point math.
Move bullets in big jumps if you don't mind missing collisions between the start and end positions. Move bullets a unit at a time if you don't mind that it's slow. Move bullets using vector collision if you want speed and accuracy.
#65715 - keldon - Thu Jan 05, 2006 3:52 am
Why the u8's and u16's? They are slower to access than u32's.
Note:
Cos = Adjacent / Hypotenuse
Sin = Opposite / Hypotenuse
I'm positive that your use of sin and cos is the wrong way around. It is probably working properly because Y is upside down in GB screen space and your direction 0 is facing up.
So your line should read:
Code: |
double newx = bullet.x + COS[ bullet.angle ] |
Remember when writing your LUT that the Y plane is inverted so your COS table should be inverted too.
Other than that your code is workable although you would benefit from using vectors for collisions rather than integration which is innacurate and slow anyway.
Quote: |
yea all i need is the code that will move vector by one incrament (vector length) at a time. i should probably make my x and y doubles. i can convert to u16s when im making the screen sprites later but i need precision now. |
To do this you can either store your table as SIN[i] = Sin(i) * length. Or by multiplying Sin[i] by length;
#69889 - christosterone - Thu Feb 02, 2006 8:20 pm
edit: nvm i got it to work. thanks for all the trig code
#73391 - greenllll - Sat Feb 25, 2006 7:00 am
I've taken math up to Calculus and Discrete Mathmatics, and I do not remember learning how to do any real work with vectors. I remember hearing something about it being taught in Physics. Where did you guys learn how to work with vectors? The concept fascinates me. I love math, but mostly trig. Calculous is very tough for me. I love this thread too.
#73401 - waruwaru - Sat Feb 25, 2006 9:47 am
greenllll wrote: |
Where did you guys learn how to work with vectors? |
I remember studying lots of matrix math in "Linear Algebra". Some schools also offer classes in Computer Graphics.
#73711 - Miked0801 - Mon Feb 27, 2006 7:19 pm
In truth, the basics that we use here are covered in Physics 101 (201). Whenever I need a quick refresher, I pull out my college text and look at chapter 2 and 3 :)
The actual applications of vectors (projections, collision detections, etc.) are covered sort-of in Linear Algebra, but I found that game programming books describe what is needed better. That and asking lots of questions and getting lots of answers.
Trust me. Once you start using vectors and discover just how powerful they are, you will never go back to angle math again if you can at all help it.
#73717 - sajiimori - Mon Feb 27, 2006 8:11 pm
We use angles a lot, but maybe that's a result of working in 3D. Things need to be rotated pretty often.
#73729 - christosterone - Mon Feb 27, 2006 9:25 pm
sajiimori wrote: |
Move bullets using vector collision if you want speed and accuracy. |
i know a lot about vectors mathematically, but im wondering how i would use vector colissions instead of angles and speed or whatever it is that im doing.
im not sure if i want vector math, though, because the moving projectiles are the only things moving in a uniform direction. the tank units etc will move sparatically. the angle and speed might be the better for this project. however, i would like to see alternatives just in case im wrong.
also, you stated i needed to use fixed point math. how would one go about doing that? bitshifting, right?
thanks chris
#73739 - tepples - Mon Feb 27, 2006 11:39 pm
christosterone wrote: |
also, you stated i needed to use fixed point math. how would one go about doing that? bitshifting, right? |
Yes. Go to Google and look for some fixed point arithmetic tutorials.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#73750 - keldon - Tue Feb 28, 2006 12:29 am
Fixed point section on wikipedia
A selected on fixed point arithmetic on wikipedia
Maybe you might want to add the wikipedia search engine to your browser if you have mozilla. It is quite useful; by far the most powerful of the browsers.
#73762 - sajiimori - Tue Feb 28, 2006 1:21 am
Choosing between angles and vectors for physics is unrelated to how sporadic your motion is.
As far as how to do collision detection, it depends on what kinds of things you want to collide: fast moving versus slow moving, point-sized objects or objects with volume, collision against static world geometry or other moving objects...
#73812 - shen3 - Tue Feb 28, 2006 5:51 am
Hi;
I figured I would post a quick description of how I move the bullets in my game.
My struct is something like this
bullet {
int x;
int y;
int dx;
int dy;
}
all of these are stored as fixed point where dividing by 256 (or >> 8) will get the pixel on the screen.
This means bullets can move a fraction of a pixel per turn. eg dx = 256+128 moves the bullet 1 and a half pixels in the x direction per turn.
I was worried that this sort of thing was going to look jerky, especially if you picked values like 200 for dx, so the bullet would move 1 pixel, move 1 pixel, then not move at all the next turn.
In reality this looks very smooth.
moving the bullet is done as follows
bullet.x = bullet.x + bullet.dx;
bullet.y = bullet.y + bullet.dy;
The only tricky parts is making sure you shift >> 8 before using the x and y as pixel locations.
Setting up dx + dy can be easily done using a sin or cos look up table.
Shen
#75396 - christosterone - Sun Mar 12, 2006 6:17 pm
dx and dy are 256x the size of a pixel. are the normal X and Y the same way? so it would be
Code: |
bullet.x = bullet.x + dx;
screenx = (bullet.x)>>8
|
thanks,
chris
#75428 - sajiimori - Sun Mar 12, 2006 9:12 pm
Yeah, otherwise a motion of 1.4 pixels would be truncated to 1.0 pixels and it would be no faster.