View Full Version : help from you math geniuses!
Jack Norton
11-27-2004, 01:57 AM
Ok I am bad at math and physics but I've decided to make games anyway :)
Now I need a hand on this problem... I have a shoot'em up game, I'm making circle collisions and it's ok, but I have a problem with bullets positioning.
The ship can rotate on the battlefield.
It has the following structure:
//fight ship variables
struct AShip_t
{
double x,y; //coordinates on screen
double d; //direction (angle)
double s; //speed positive (forward) or negative (backward)
short wr[3]; //weapon recharge, if zero can fire
short power; //for powerup
short speed;
short defence;
};
extern AShip_t AShip[2];
Now the problem is: if the ship shoots at angle 0 the bullets appear correctly, but if the ships rotates, the bullets appear in wrong position.
To calculate the position of ship on screen, and also of bullets I use:
AShip[t].x+1*cos(AShip[t].d/(360/6.28f))
AShip[t].y+1*sin(AShip[t].d/(360/6.28f))
but as you can see from this screenshot (http://www.g-generation.com/temp/screenshot.jpg), doesn't work if the angle rotation isn't 0 or 180 :(
matibee
11-27-2004, 02:14 AM
Converting to radians involves multiplying by pi/180 :)
/edit.. Ooops :o d/(180/pi) == d*(pi/180)
sorry Jack
To add something a bit more constructive.. (but what you have should work). Does your direction (angle) 'd' go from 0 = 3o'clock anticlockwise to 180 = 9o'clock? That's probably how your coordinate system will require it.
Jack Norton
11-27-2004, 02:39 AM
I tried to change them to:
AShip[t].x+1*cos(AShip[t].d*(3.14f/180))
AShip[t].y+1*sin(AShip[t].d*(3.14f/180))
but don't work (ehm I am very ignorant so you should write me exactly how I should write the thing)...
Angle is 0 when ship is facing 12 o'clock and 180 when ship is 6 0'clock, going anticlockwise...
Wayward
11-27-2004, 03:05 AM
Degrees = Radians x 180/pi
Radians = Degrees x pi/180
// angle = 0 is at 3 o'clock. Increasing angle rotates clockwise.
BulletX = ShipX + Cos(angle) * Offset
BulletY = ShipY + Sin(angle) * Offset
// angle = 0 is at 6 o'clock. Increasing angle rotates anti-clockwise.
BulletX = ShipX + Sin(angle) * Offset
BulletY = ShipY + Cos(angle) * Offset
// Blitz3D angle test (complete program)
Graphics3D 640,480,0,2
ShipX = 320
ShipY = 240
degrees# = 0
Offset = 100
Repeat
Cls
BulletX# = ShipX + Sin(degrees) * Offset
BulletY# = ShipY + Cos(degrees) * Offset
Line ShipX, ShipY, BulletX, BulletY
Text 8,8,degrees
Flip
degrees = degrees + 1
If degrees > 360 Then degrees = degrees - 360
Until KeyHit(1)
End
Jack Norton
11-27-2004, 03:49 AM
Wayward: Using your method I'm getting better results, however the position is still different :(
maybe because I'm not plotting a single pixel but an image with width and height? bah this is really complex!!
svero
11-27-2004, 04:23 AM
Wayward: Using your method I'm getting better results, however the position is still different :(
maybe because I'm not plotting a single pixel but an image with width and height? bah this is really complex!!
Probably. You need to use the center of your object.
svero
11-27-2004, 04:23 AM
as well.. the center of the thing you're firing.
yanuart
11-27-2004, 05:21 AM
okay first you need to be sure what type of degree that your sin & cos function accept.. usually (AFAIK every math lib accept radian degree, prove me wrong)
so u need to do the conversion first, infact.. try to store degree in rads only.. that way if you do a linear increment on the degree it'll provide a smooth rotation (if you ask me why.. hmm.. this is why kids shouldn't skip math :D)
anyway.. I assume that this is what you want :
you want a ship and a bullet that can rotate and move to every direction according to its facing right?
I suggest you take vector approach in making the movement and you can use rotation matrix to rotate it.
before I begin to tell you how it works first we need to agreed on a few things first.
A. The zero degree always start at X positive axis
B. The degree movement is counter clockwise so for ex. if I say 180 what do you get ?? yup.. X negative axis.. what about 90 ??
This is how it works :
1. You need a 2D vector and make it normal (the unit size always 1), let's say the vector is [dx,dy] and we shall name it "Dnormal" (notice the familiar use of dx,dy). Now this is important that you initiate dx=1, dy=0 (see A above).
2. In case you're wondering what the vector is used for, the vector is used to increment your ship position every time your ship move.
It's as simple as
NewPosShip.X=PosOld.X + D.dx;
NewPosShip.Y=PosOld.Y + D.dy;
So where our ship is facing at the moment ?? zero degree which mean it's facing RIGHT (as in left right).. and when it moves we add xpos with 1(dx), and ypos with 0(dy). got it ??
3. Now what happen if we rotate the ship let's say 90 degree, where it should be facing now ? TOP !!! so you probably guess the value of vector D now.. yup dx= 0 & dy = -1. How do we calculate this ?? Simple.. I'll spare you the rotation matrix and you can have this :
D.dx=Dunit.dx*cos(rdeg) + Dunit.dy*sin(rdeg);
D.dy=Dunit.dy*cos(rdeg) - Dunit.dx*sin(rdeg);
now since this works with our first D vector (1,0) as Dunit now you can make the formula a lot simpler :
D.dx=cos(rdeg); // alot simpler since our vector is always relative to the ship position
D.dy=-sin(rdeg); // it's just like rotating with 0,0 pivot
there you have it, btw, this only work if you calculate rdeg as a difference between zero degree and your current degree..
This is a fool proof vector movement math.. have speed issue ?? simple multiply vector D with a scalar value (a.k.a speed) before, what if speed is negative... well.. your ship just shift its gear to reverse !!!!
What about bullets.. well incase you haven't notice a bullet is just a ship but alot smaller and can cause damage :D
About the misplacement of the ship and bullet.. you need to make sure first that usually when a graphic lib try to flip some sprite they usually do it from the top left of the sprite, meanings that if you flip a sprite at 10,10 you can see that your sprite is actually at 10,10 in screen but calculated from the topleft position.
if you want to flip a sprite (a.k.a ur ship) on screen calculated from the sprite's middle posisition.. well u can always rewrite ur graphic library :D or you can just move ur sprite a bit according to its offset
so your code now should be like this :
struct AShip_t
{
double x,y; //coordinates on screen
double offsetX,offsetY; // an offset value to make your coordinates behave the way you want it
double dx,dy //our vector D
double d; //direction (angle)
double s; //speed positive (forward) or negative (backward)
short wr[3]; //weapon recharge, if zero can fire
short power; //for powerup
short speed;
short defence;
};
AShip_t::AShip_t(){
dx=1;dy=0;drad=0;
offsetX=getSpriteWidth()/2;
offsetY=getSpriteHeight()/2;
}
AShip_t::Rotate(ddeg){// + means rotating CCW - rotating CW
drad+=ddeg;
dx=cos(drad);dy=-sin(drad)
}
AShip_t::UpdatePerFrame(){
x=x + dx*s;
y=y + dy*s;
}
AShip_t::FlipToScreen(){
SomeFunctionToFlip(pSomeSprite, x-offsetX,y-offsetY);
}
anyway... i hope you get it and i hope it helps.. english it's not my mother language so if you find my explanation hard to understand, just ask..
laterrrr.....
Jack Norton
11-27-2004, 05:42 AM
Thanks all, I've solved my problems :)
So maybe I'll finish this game before end of december! :D
RedKnight
11-27-2004, 11:55 AM
Finished at the end of december.
Man.
You're sure fast.
I think I can finished mine shmup at January or february. :D
Jack Norton
11-27-2004, 01:17 PM
Well my goal is to make a new game every 2 months and release it... then update them :p
Anyway mine is a particular shoot'em up. It requires less graphic than a conventional one for sure... you'll see :)
EpicBoy
11-27-2004, 01:55 PM
Well my goal is to make a new game every 2 months and release it... then update them
So rush them out the door and finish them later? Why does this sound familiar...
*ducking*
Sorry!
RedKnight
11-27-2004, 02:09 PM
Well I'm trying to do the "Blizzard" approached.
:D
Is my first ever indie game. :p so I wanted to code it with care.
My second project is going to be a Horizontal shmup with 360 rotating weapons. :D
Jack Norton
11-27-2004, 02:32 PM
So rush them out the door and finish them later? Why does this sound familiar...
Ehm, no :eek:
UBM when launched was already well complete... there were just some small bugs but nothing serious. The updates added new elements to the game, weren't only bugfixes.
With the goalkeeper game things weren't a bit worse, but wasn't really rushed out. Also because games like those two would need a full team of testers...when I made my puzzle game and my trivia game I tested them in one week alone, those are simple games!!
BTW I'm very curious to see your game Redknight ;)
RedKnight
11-27-2004, 03:27 PM
BTW I'm very curious to see your game Redknight ;)
Well It's not 110% done yet.
But there's allready a demo (not playable yet) you can download it Here (http://forums.digitalthinker.org/index.php?act=Attach&type=post&id=1966)
:D I hope I can finally play with the BIG indies boys.
Jack Norton
11-29-2004, 10:35 AM
I tried to run demo today, but crashed :eek:
RedKnight
11-29-2004, 12:15 PM
arg.
Do you have Opengl installed? are you running it on XP?
Jack Norton
11-29-2004, 12:30 PM
You bet I have OpenGL installed... all the games I develop are OpenGL only ;)
Yes on XP.
RedKnight
11-29-2004, 03:52 PM
XP service pack 2?
DirectX version?
A friend of mine also had the same problem.
I don't know what the causes are, since most computer I
checked worked fine.
Jack Norton
11-30-2004, 04:05 AM
No, simple XP without service pack 2.
DirectX 9.0b.
Note: all other opengl games I've tried works well... :(
RedKnight
11-30-2004, 04:25 AM
weird.
This is the second time that I have this kind of error.
you can try download the updated version.
and check the log for errors.
http://forums.digitalthinker.org/index.php?showtopic=200&view=getnewpost
vBulletin v3.6.0, Copyright ©2000-2009, Jelsoft Enterprises Ltd.