Jump to content
  • Advertisement
Sign in to follow this  
os3330

Angle Shooting

This topic is 3855 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 trying to figure out how to shoot based on the character's angle. Every time a player or enemy shoots, a bullet is created right in front of them and then moves off on its own. Right now, I'm only checking for 0 and 180 (up and down). And the code on that is pretty long (one for X and Y). Is there a mathematical function to do this easily?

Share this post


Link to post
Share on other sites
Advertisement
Trig isn't my specialty, but I'll take a shot.

I got this (the Bullet class takes care of positioning):
offset.x = ( character->get_x_pos() ) - static_cast<Sint16>( ( offset.w / 2 ) * sin( angle ) );
offset.y = ( character->get_y_pos() ) - static_cast<Sint16>( ( offset.h / 2 ) * cos( angle ) );
It's a bit off (at 315 degrees, it shows up lower than the firing point). I have to incorporate this into the shooting function.

Share this post


Link to post
Share on other sites
Now I have to calculate the bullet's trajectory based on angle. I plan to go by 45 degree increments.

Here's the code. Correct me if anything is wrong.
// Sets the X and Y velocity based on angle.
void set_velocity( int newVel )
{
// If the angle is a multiple of 180, the Y velocity is zeroed.
if ( angle % 180 == 0 ) {
yVel = 0;
xVel = newVel;
}

// If the angle is only a multiple of 90, the X velocity is zeroed.
else if ( angle % 90 == 0 ) {
xVel = 0;
yVel = newVel;
}

// If it's any other angle, set both velocities.
else {
xVel = newVel;
yVel = newVel;
}
}

Share this post


Link to post
Share on other sites
Look into vector math. What you're doing can be simplified a lot. Besides, your code is only correct for 0/90/180/270-degree angles. You really should investigate vector math as it can save you a lot of time and hassle later on.

Anyway:
void set_velocity(int newVel)
{
float factor = newVel / sqrt(xVel * xVel + yVel * yVel);
xVel *= factor;
yVel *= factor;
}
What happens here is that you divide your x and y components by the current velocity (the length of this vector) and you then multiply it by the new velocity. In other words, you first set the length of your velocity to one - it keeps it's angle but not it's length - and then it's as easy as multiplying both by the new velocity - so the length will be newVel, because 1 * newVel is newVel.

Share this post


Link to post
Share on other sites
Ah, vector math. Unfortunately, my velocity has to be in whole number integers (because a velocity of one means one pixel per frame).

So if I had xVel = 2 and yVel = 3, using your formula would yield a factor of 6. Thus, the newVel parameter has to be bigger than or equal 12 to make any real difference.

Is there a way to move every few or so frames so I can get a more accurate velocity calculation?

Share this post


Link to post
Share on other sites
why does it have to be an integer? If it's for rendering then you can round the floats to an integer if that's necessary.

http://en.wikipedia.org/wiki/Unit_circle

See the vector produced from an angle. (cos(angle), sin(angle)) that's a unit vector. To get velocity for a bullet you can multiply it by a scalar like:
(cos(angle) * speed, sin(angle) * speed)

Depending on how you set things up if the y is reversed then:
(cos(angle), -sin(angle))
and
(cos(angle) * speed, -sin(angle) * speed)

Share this post


Link to post
Share on other sites
Quote:
Unfortunately, my velocity has to be in whole number integers (because a velocity of one means one pixel per frame).

No it doesn't. The screen is not the game world, the screen is a view of the game world; there's nothing wrong with your object being at (0.6, 1.4) and your display showing it at (1, 1) ... although with most graphics libraries you could draw it at (0.6, 1.4) anyway.

I can only second the 'look at vector maths'. Object motion, particularly if you start modifying velocities in flight (gravity, homing missiles, air resistance, force fields etc etc), is extremely well described by simple vector operations.

Share this post


Link to post
Share on other sites
And of course I can use vector math to determine the distance of the player through the enemy and shoot a bullet there.

It's a shame that SDL_Rect doesn't take decimals.

Share this post


Link to post
Share on other sites
Okay, I've encountered another problem. Using my new velocity function, the objects jerk around or don't move at all. Nothing else has changed except the velocity functions.

Here's the code that changes the velocity:
// Sets the X and Y velocity based on angle. //
void Character::set_x_vel( float newVel )
{
// Calculates the unit vector. //

// Checks if lower denominator is zero.
float normal = sqrt( pow( xVel, 2 ) + pow( yVel, 2 ) );

if ( normal == 0 ) {
xVel = static_cast<float>( newVel * cos( to_radians( angle ) ) );
}

else {
float factor = newVel / normal;
xVel *= static_cast<float>( factor * cos( to_radians( angle ) ) );
}
}

void Character::set_y_vel( float newVel )
{
// Calculates the unit vector. //

// Checks if lower denominator is zero.
float normal = sqrt( pow( xVel, 2 ) + pow( yVel, 2 ) );

if ( normal == 0 ) {
yVel = static_cast<float>( newVel * sin( to_radians( angle ) ) );
}

else {
float factor = newVel / normal;
yVel *= static_cast<float>( factor * sin( to_radians( angle ) ) );
}
}
Is there anything wrong with my calculation of the unit vector?

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!