# Thread: Firing bullets from rotating ship???

1. ## Firing bullets from rotating ship???

I'm trying to get bullets to fire from the ship in the direction it is rotated. I've tried using the following, but it keeps firing long, weird lines to the top left corner of the screen. I have to admit that triggonometry stuff is vague to me...any tips?

Code:
```double bvx,bvy,bpx,bpy;
void Bullet::InitObject(void)
{
dAngle = pSpaceship->getShipsAngle();

bvx = 10 * sin(dAngle) + pSpaceship->getShipsVelocity().XValue;
bvy = 10 * cos(dAngle) + pSpaceship->getShipsVelocity().YValue;

bpx = pSpaceship->getShipsPosition().XValue;
bpy = pSpaceship->getShipsPosition().YValue;

v2dVelocity = Vector2D(bvx,bvy);
v2dPosition = Vector2D(bpx,bpy);
}
///////////////////////////////////////////////////////////////////////////

void Bullet::DrawObject(void)	//Draw the bullet as per coordinates
{
bvx = 10 * sin(dAngle);
bvy = -10 * cos(dAngle);
v2dVelocity += Vector2D(bvx,bvy);

pTheDrawEngine->LockBackSurface();	//Lock back surface

pTheDrawEngine->DrawLine(v2dPosition, v2dVelocity,
MyDrawEngine::YELLOW32);

pTheDrawEngine->UnlockBackSurface();//Unlock back surface

}```

2. bvx = 10 * sin(dAngle) + pSpaceship->getShipsVelocity().XValue;
bvy = 10 * cos(dAngle) + pSpaceship->getShipsVelocity().YValue;

is dAngle in radians? Should sin and cos be swapped (in trigonometry cos(angle) is the x-value of the unitycircle)

bvy = -10 * cos(dAngle);

Why is 10 negative here? And same here, shouldnt cos and sin be swapped (Im assuming this is a topdown game you are doing?)

Have you tried to step through this in a debugger to make sure you get the correct values set? IE use input and set variables according and see if the values you get are the ones you expect to get.

3. is dAngle in radians? Yes I'ts converted to radians in the spaceship class.

bvy = -10 * cos(dAngle); I got this from a website, which i was trying out.

I could try stepping through it - I'm just hacking - I don't really fully understand how the triggonometry works. Just vaguely.

4. Here is a good page on trigonometry:
Trigonometry -- from Wolfram MathWorld

5. or you make a vector struct, that has member variables x and y
then you place two of these on your ship (in middle and end of cannon would be smart)
Lets call the vector vPoint...
Bare with me that I just forgot how to instantise(?) structs, thus am doing this as if vPoint was a class
Code:
```vPoint mid(0,0);
vPoint cannonEnd(5,5);

vPoint velocity(cannonEnd.x - mid.x, cannonEnd.y - mid.y); // making velocity (5, 5)
// To make this calculation easier and more stable, you should have a Normalize function in vPoint

// Now you'll have to continue on yourself, but I'll show how it works

//This probably makes a curve... Can anyone confirm this?
for(int i = 0; i < 6; ++i) velocity += velocity;

// This should work flawlessly
vPoint temp = velocity;
for(int i = 0; i < 6; ++i) velocity += temp;```
Please, if I'm wrong correct me before this guy uses my algorithm...

EDIT: Remember not to use loops to do this!

6. Cheers guys, I've got something kinda working now with the following...

The only trouble I'm having now is that the angle of the ship does not appear to be updating until I press the thrust key. Hmmmmm...
Code:
```void Bullet::InitObject(void)
{
dAngle = pSpaceship->getShipsPosition().angle();//>getShipsAngle();
v2dPosition = pSpaceship->getShipsPosition();

v2dVelocity = Vector2D(cos(dAngle),sin(dAngle)) + pSpaceship->getShipsVelocity() * 5;
}

void Bullet::DrawObject(void)	//Draw the bullet as per coordinates
{
v2dPosition += v2dVelocity  * pTheGameTimer->mdFrameTime;

pTheDrawEngine->LockBackSurface();	//Lock back surface
pTheDrawEngine->DrawLine(v2dPosition, v2dPosition, MyDrawEngine::YELLOW32);
pTheDrawEngine->UnlockBackSurface();//Unlock back surface

}```

7. The sinf() and cosf() functions can be swapped in your function to get the desired results you need. If you want mathematical zero degrees to face straight up the screen then I believe what you have is correct.

As to why it works it is just the parametric form of a line. You are moving some distance along a line where the slope of the line is defined by your sin and cos functions.

Akkernight's code will not work unless you normalize the result. But that example is more along the lines of firing a projectile along a path created by a vector from the ship to the target of the ship. However this is not good for continual rotation since you must have a target to compute the vector. Your sin/cos example is exactly how you should do it and Akkernight's example (save for the for loops with the hard-coded 6) is what you would do for targeting another craft.

Code:
```void Ship::FireAt(const D3DXVECTOR2 &target,float bulletVelocity)
{
D3DXVECTOR3 toTarget = target - m_Position;
float length = D3DXVec3Length(&toTarget);

float nx = toTarget.x / length;
float ny = toTarget.y / length;

}```

8. ok, I didn't consider his many rotations... but still, it fires from the mid to the cannon end, and then goes further... So it shouldn't be doing unnecessary calculations?
What I like by my method (not claiming it's the best or any other 'ego' proposal) is that I know that the bullet gets its assigned path to 'fly'... Ofc this doesn't give easy chances of wind and such world stuff calculation, but I think of it as getting its path, and then all other projects have nothing to worry about... Dunno how to explain xD

9. You do not have a path to fly when you are just rotating. The path is defined by sin and cos of the angle the ship is pointing. Your hard-coded 6 value is something I really do not like and it is not clear from the code what this arbitrary value does or why it was selected.

And your code that says it should make a curve is not a curve at all. It is sampling 6 points along the line defined by your vector. No curve.

For a curve you could do a bezier curve via 3 linear interpolations along a line. Given 3 control points A,B and C you linearily interpolate between A and B by coef X and call it AB. You then linearily interpolate between B and C by coef X and call it BC. Then you linearily interpolate between AB and BC by X. This is the final point. If this is done for all X between 0.0f and 1.0f you will trace out a curve defined by the control points A,B and C.

10. Bubba, the reason I thought it might end like a curve was more specialized on if both values weren't equal, but still it was a question!
And the For loops where a mere explanation of what I meant...
And I was talking about the projectiles, they get one specified path to fly, end of story for them... It's the simplest way I'd say..