This might sound like a very elementary question, i've been working on a
small personal project making a top down shooting game where the player
controls a character(sprite) using the mouse, the player's character should
be able to shoot from its current location, in a straight line in at the
cursor.
The problem i'm having is that I can't seem to get the player's character to
shoot anywhere near the cursor and also, it won't shoot at a constant speed,
i've tried a couple of different approaches which each seemed to end in
disaster. Most of the time the character can move around and do what hes
told but when the character is instructed to shoot the bullets fly off in
any direction apart from the one hes supposed to be aiming at, and at random
speeds.
So basicly what i'm looking for is a little short algorythym to calculate
the coordinates for each frame when a bullet is shot from the position of
the players character e.g: coordinates 50,50 to where ever the cursor is
aiming e.g (200,250) at a constant speed. The bullet terminates and is
destroyed when it reaches the boundarys of the screen(already have this
done).
I've virtually everything else working except this. The program is laid out
in a simple enough manner with the following functions(amongst others).
UpdateSprites()
Update the position of all the sprites on screen whenever anything moves
CheckCollide()
Check whether a bullet has hit another player/enemy/tree/game boundaries.
UpdateScreen()
When all sprite drawings/updates are done, redraw the screen.
I'm working under WinXP and using C/C++ under VS2k3. I decided to go against
the 3D glitsy approach and am using GDI.
-
Con
Keep in mind that screen cordinates look like this:
-y
+y
-x +x
While mathematical coordinates look like this:
+y
-y
-x +x
Also note that 0° in math is pointing along the X axis and 90° is along
the Y -- this is very different from the compass, where North is along
the Y and 90° is along the X.
So you'll need a couple of routines to convert those. qed.
The gist of getting a bullet to go at constant speed is:
* Make sure the bullet has systemTime() of last movement stored.
(initialize this when fired.)
* At every frame...
- Get system time
- distance to move = (prevTime - currentTime) * speed
- new locationX = old locationX + (cos (direction) * distance to move)
- Similar for Y, use sin().
Remember to do the X/Y translations, and also to adjust the
direction-fired accordingly. Again:
Compass:
0
|
270 --+-- 90
|
180
Math functions:
90
|
180 --+-- 0
|
270
(Most math functions are in radians, also -- so you'll want to not
forget to do THAT conversion...!)
--
Please take off your pants or I won't read your e-mail.
I will not, no matter how "good" the deal, patronise any business which sends
unsolicited commercial e-mail or that advertises in discussion newsgroups.
> This might sound like a very elementary question, i've been working on a
> small personal project making a top down shooting game where the player
> controls a character(sprite) using the mouse, the player's character should
> be able to shoot from its current location, in a straight line in at the
> cursor.
Let (bx,by) be the coordinates of the bullet. Then you have a bullet
velocity which is (bdx,bdy). This assumes that each frame represents
a constant timeslice. So, each frame, you have:
bx=bx+bdx
by=by+bdy
Simple enough; presumably you already have something like this
implemented. The remaining question is, what should bdx and bdy
be initialized as? Okay, let's assume (bx,by) is initialized at the
player's position, and (mx,my) is the mouse position. Let's SPEED
be the desired bullet speed in pixels. Then you can calculate
(bdx,bdy) using this algorithm:
bdx = mx-bx
bdy = my-by
distance = sqrt(bdx*bdx+bdy*bdy)
if distance = 0
bdx = 0
bdy = -SPEED
else
bdx = bdx*SPEED/distance
bdy = bdy*SPEED/distance
endif
To a first approximation, the bullet velocity is in the correct
direction if we simply subtract the current position from the
destination position. However, the speed will be wrong.
So we calculate the distance using the Pythagorean
formula, and scale (bdx,bdy) to a new length of SPEED.
We have to check for distance=0 so we don't divide by
zero when the mouse is exactly on top of the player. In
that case, we apply an arbitrary direction (in this case,
straight up).
Isaac Kuo