• Advertisement
Sign in to follow this  

Bullet Firing

This topic is 4794 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm writing a basic game in C++ using GDI for now, until I pick up directX. So I have my rectangle player and my rectangle monster and the player can move around. Now I need to do monster shooting at player. So I get the x,y of the player, and then start a bullet (guess what - small rectangle!) at the monster x,y position. Then I test for x and y differences between the bullet's current position and the player position it was aimed at, and move it accordingly in each iteration of the game loop. Everything works, except the bullet's path - A BBBBB__________ ________B________ __________B_______ ____________B_____ ______________B____ ________________M__ A - 'aim point' M - monster B - bullet See? It travels diagonally at first, because both x and y are not the same as the aimed position, until the x is the same, then it just moves horizontally. What I want to do is a straight path evenwhen the path is not exactly diagonal, horizontal or vertical. Hopefully this makes sense :)

Share this post


Link to post
Share on other sites
Advertisement
The best thing to do is store the bullet position and velocity as 2D vectors. I assume you know some basic vector math and time-based movement.

The velocity of the bullet is calculated: Normalize(A-M)*Constant;

I don't really understand if you want the bullet to "follow" the player, or just follow a straigt path. In the first case, you update the velocity each frame, in the second, you calculate the velocity just once the bullet is fired.

And the position of the bullet is updated like this:
pos=pos+vel*dt;//dt=time that has elapsed since last update

Share this post


Link to post
Share on other sites
You have to find the delta y for each delta x.

float DifferenceX = FinalX - StartX;
float DifferenceY = FinalY - StartY;
float DeltaX = 1.0f;
float DeltaY = DifferencY / DifferenceX;

Share this post


Link to post
Share on other sites
Just to clarify, I want the bullet to just travel in a straight line towards the original aim point, rather than tracking the player.

Ironically, tracking the player seems easier than travelling in a straight line!

I haven't really done any vector stuff yet, but it looks fairly simple...

Share this post


Link to post
Share on other sites
Quote:
Original post by Pipo DeClown
You have to find the delta y for each delta x.

float DifferenceX = FinalX - StartX;
float DifferenceY = FinalY - StartY;
float DeltaX = 1.0f;
float DeltaY = DifferencY / DifferenceX;


That has some drawbacks. For instance, if (DifferenceX=0) we would have division by zero, the velocity is not the same for all directions(for directions almost vertical, the bullet would make a huge jump if we assume he always increases X by DeltaX=1.0), no support for time-based movement which he will need eventually... it's better for him to do this the right way from the start.

Share this post


Link to post
Share on other sites
If you want a diagnal between 2 points then you might want to look a a tutorial like this http://www.falloutsoftware.com/tutorials/dd/dd4.htm


Its a simple explanation, hope it helps.

Fud

Share this post


Link to post
Share on other sites
Quote:
Original post by LMRFUD
If you want a diagnal between 2 points then you might want to look a a tutorial like this http://www.falloutsoftware.com/tutorials/dd/dd4.htm


Its a simple explanation, hope it helps.

Fud


That helped. Thanks. although I now know I need to look into vectors etc in a bit more detail :)

Share this post


Link to post
Share on other sites
LMRFUD, that tutorial is for drawing lines. It has some connection, but moving a bullet is not exactly the same as plotting pixels.

Quote:
Original post by cornflake
Quote:
Original post by mikeman
Normalize(A-M)*Constant;


Getting lost here...


It's pseudocode.
Normalize() means you simply divide the (A-M) vector with its length, to come up with a vector with the correct direction, but with unit length(=1). You then multiply it by a constant to make the bullet travel faster/slower.

Ok, just a very simple code example to see how it works:




struct CVector2D
{float x,y};

CVector bullet_pos,bullet_vel;
CVector monster_pos,player_pos;


void Normalize(CVector2D &v)
{
float length;
length=sqrt(v.x*v.x+v.y*v.y);
v.x=v.x/length;
v.y=v.y/length;
}

void FireBullet()//Called when you want to fire a bullet
{
CVector2D temp;

temp.x=player_pos.x-monster_pos.x;
temp.y=player_pos.y-monster_pos.y;
Normalize(temp);

bullet_vel.x=temp.x*5.0;//Just some constant
bullet_vel.y=temp.y*5.0;
}

void MoveBullet(float dt)
{
bullet_pos.x=bullet_pos.x+bullet_vel.x*dt;
bullet_pos.y=bullet_pos.y+bullet_vel.y*dt;
}




This can easily extend to 3D as well.

Share this post


Link to post
Share on other sites
Thanks for the example. One more idiot question - I understand the code except for the use of the * characters...

Share this post


Link to post
Share on other sites
A²+B²=C² in a right-angled triangle. (Triangle with a 90 degree corner)
That's my own theorem.

So basically, that line is squarerooting the C², because A²+B² is put into the sqrt().

Share this post


Link to post
Share on other sites
Quote:
Original post by cornflake
Thanks for the example. One more idiot question - I understand the code except for the use of the * characters...

The * sign is multiplication.

In this instance

It's also used with pointers, but you'll get there, when you get there.

Share this post


Link to post
Share on other sites
Original post by mikeman


struct CVector2D
{float x,y};

CVector bullet_pos,bullet_vel;
CVector monster_pos,player_pos;


void Normalize(CVector2D &v)
{
float length;
length=sqrt(v.x*v.x+v.y*v.y);
v.x=v.x/length;
v.y=v.y/length;
}

void FireBullet()//Called when you want to fire a bullet
{
CVector2D temp;

temp.x=player_pos.x-monster_pos.x;
temp.y=player_pos.y-monster_pos.y;
Normalize(temp);

bullet_vel.x=temp.x*5.0;//Just some constant
bullet_vel.y=temp.y*5.0;
}

void MoveBullet(float dt)
{
bullet_pos.x=bullet_pos.x+bullet_vel.x*dt;
bullet_pos.y=bullet_pos.y+bullet_vel.y*dt;
}



[/quote]

I don't think it's right that you dis other people for their answers. You're basically being arrogant, but hey, look what I found, mr. I-Know-It-Better? If length in Normalize() is 0, you're dividing to 0 also.

So please have a kind attitude if you're helping, but if you're showing off, go elsewhere.

Share this post


Link to post
Share on other sites
Quote:

So please have a kind attitude if you're helping, but if you're showing off, go elsewhere.


You might want to take your own advice. Can you give me one example when I wasn't kind? I was just trying to show the OP what is IMO the most right way to do this, and if I remember correctly, you posted after I had posted my answer. And I posted the code because the OP himself said he wanted to look into vectors with more detail and asked what Normalize() meant.

Anyway, I don't really understand why you're offended, what is this, a pissing contest? Geez. And keep the "go elsewhere" comments to yourself. I don't have to answer to you about anything. Grow up a little, okay?

-PS: And if the length of the vector is 0, that means the player and the monster have the exact same position. Not going to happen if the game is correctly implemented.

[Edited by - mikeman on January 4, 2005 4:36:46 PM]

Share this post


Link to post
Share on other sites
Don't worry mikeman, those of us with some sense can see that you were actually being very helpful. I think you were being quite nice. Some people can't take criticism well at all.

Pipo's replies were simply inadequate and thus not very helpful, lacking any explanation whatsoever. Bamboozling people with pythagoras theroem, without any explanation of how to apply it here, certainly counts as showing off in my book. His comments were certainly uncalled for, and he should know better!

Share this post


Link to post
Share on other sites
Quote:
Original post by mikeman
void Normalize(CVector2D &v)
{
float length;
length=sqrt(v.x*v.x+v.y*v.y);
v.x=v.x/length;
v.y=v.y/length;
}

You said that I was coding dangerously, but hey, I was using pseudo-code too! WOW!!
And look here, you're making the EXACT SAME mistake. But this time, it doesn't really look like it's pseudo-code, does it?


Quote:
Original post by mikeman
And if the length of the vector is 0, that means the player and the monster have the exact same position. Not going to happen if the game is correctly implemented.

Well, you gave me a correct argument in this one, but I can just copy your argument in the case where I divided by zero. Errm.. ?

Share this post


Link to post
Share on other sites
Quote:

Well, you gave me a correct argument in this one, but I can just copy your argument in the case where I divided by zero. Errm.. ?


Not really. You divide by (DifferenceX), which means divizion by zero will happen if the player is completely vertical with the monster. There's no reason why that can't happen in the game, in fact, it probably will happen. And I already gave a bunch of reasons on why working with vectors is better.

Pipo, what's wrong with you? I mean seriously. I pinpointed some drawbacks in the method you proposed to protect the OP from further problems. You act like it was a personal attack to you or something, and you turned this thread into a piece of crap, trying desperately to find errors in a method that nearly everyone uses, just to get back at me. And the only thing you accomplish is to confuse the OP even more with your ignorance. It's not like I invented vector math, I just know how to use them. If you don't, then you could benefit and learn from this thread. Instead, you're acting like a stupid 12yrold(unless you are indeed one).

Share this post


Link to post
Share on other sites
Pipo DeClown, keep yourself civil and non-confrontational in this forum. I don't think I need to point out the consequences of ignoring a warning from me, and that goes for everyone. Don't take this thread off topic into a personal dispute. If you really are 6 years old, use email or PMs for your playground arguments.

Share this post


Link to post
Share on other sites
So, cornflake wanted to find a way to compute a bullets path and then you two needed to jump into a pissing war. Beautiful! I didn't read the tutorial but if helped then good. I would have just computed slope and left it at that.

Share this post


Link to post
Share on other sites
i agree with think all you have to do is compute the slope for example

TempRect = MonsterRect
TempPlayerRect = PlayerRect
TempRect .y - TempPlayerRect .y
M = ------------------------------ //this just means divided by but this is how you would code it
TempRect .x - TempPlayerRect .x

if(bullet.x != TempPlayerRect .x || bullet.y != TempPlayerRect .y)
{
bullet.x += 1
bullet.y = M* bullet.x
}

the equation im going by here is Y= MX + B
this works without the B because were assuming the position of the monster to be the origin and there for there is no B and X just gose up by a constant rate unless you want the bullet to have a really funky curve so you would implement it like this. Im pretty sure my math is right here just let me know other wise
also the asignment of the rects in the begining is so that if either one moves the trajectory isnt screwed up (otherwise you would have an ever homming bullet i think ;)) make sure if you use this method that the TempRects are NOT updated every cycle make sure you only set them one when the bullet is fired
once the bullet has collided i would set the TempRects to -1 indicating that i can be used again

hope i helped
i figured this wasnt as complicated as vector math

[grin]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement