Sign in to follow this  

Shooting in Asteroids

This topic is 4581 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

So i'm making an asteroids type of game. I can fly around with my ship and have a velocity in one direction, and can rotate the ship to another direction, without affecting its velocity. Me problem is that I have a problem calculating the components of the velocity vector for my bullets. Here's a scenario: I accelerate in upwards, then I rotate my ship 90 degrees to teh right and then I shoot. The shot right now seems to go to the right and down. That is because of the ship's velocity, getting it further and further away from the bullet. I calculate the components of the velocity vector of the bullet like this: vel_x=20*Math.cos(angle); vel_y=20*Math.sin(angle); where angle is the angle of the ship and 20 is a constant. I guess I have to take in account the velocity of the ship and include that in teh calculations, but i have no clue how. Anyway have any ideas?? Thanx a lot

Share this post


Link to post
Share on other sites
I tried that and it didn't work..instead it looked like it was going the other way..to the right and upwards...

then I tried this:

vel_x=20*Math.cos(angle)+ship_vel_x/2;
vel_y=20*Math.sin(angle)+ship_vel_y/2;

and this was actually very close but when I turned only 45 degrees and then tried to shoot, it looked ok and was giving the illution that it was going straight, but it looked like the bullet was created just a few pixels to the left of the ship. actually sometimes it was to the right, depending on which way i rotated before i shot.

Share this post


Link to post
Share on other sites
Are you sure your cos/sin functions take the same kind of angle you're giving them? It sounds like you're using degrees, but sin and cos generally work on radians.
To convert from degrees to radians, multiply by π(pi) and divide by 180.

Share this post


Link to post
Share on other sites
Have you tried swapping your sin/cos around?

so,
vel_x=20*Math.sin(angle)+ship_vel_x;
vel_y=20*Math.cos(angle)+ship_vel_y;

It's how I do it in my game (I also negate the sin return value, but that just depends on your coordinate system).

Share this post


Link to post
Share on other sites
I'd recomend coding in a text output function, that draws text and variables on to the screen (if you don't have one already)

Then output real time on the screen your sin and cos for the bullet.

The reason for this is it will let you see what your game is calculating for the bullet vector.

Another idea, is the bullet vector should = ship vector in your game. So instead of calculating just use that.

Another trick is to reverse either the sin or the cos, so multiply one of them by *-1 (sounds like this one might solve your problem)

Share this post


Link to post
Share on other sites
Try just drawing a line in the direction you want your bullet to shoot. Debugging helps a lot when figuring out such things.

Also, having a vector class helps a lot. This is what I'm using:

vector2d.h

#if !defined(_VECTOR2D_H_INCLUDED_)
#define _VECTOR2D_H_INCLUDED_


namespace System{
namespace Math{


//class Vector2D;


/// 2d vector class
class Vector2D {
protected:
double m_x, m_y, m_length, m_direction; // USES RADIANS
public:
Vector2D(const Vector2D& other) :
m_x(other.m_x),
m_y(other.m_y),
m_length(other.m_length),
m_direction(other.m_direction){ /* nothing */ }
Vector2D(double x = 0, double y = 0){ SetPoints(x,y); }
double x(double x);
double y(double y);
double Direction(double d);
double Length(double m);
void SetPoints(double x, double y);
void Reset();

void ReflectAngle(int NormalAngle);
double x(){ return m_x; }
double y(){ return m_y; }
double Direction(){ return m_direction; }
double Length(){ return m_length; }

// Vector arithmetic operators
Vector2D& operator+= (Vector2D& v);
Vector2D& operator-= (Vector2D& v);
Vector2D& operator*= (Vector2D& v);
Vector2D& operator/= (Vector2D& v);

// scalar operators for speed and resolving ambiguity problems
// with implicit constructor calls
Vector2D& operator+= (double f);
Vector2D& operator-= (double f);
Vector2D& operator*= (double f);
Vector2D& operator/= (double f);
};

}
}
#endif





vector2d.cpp

#include "vector2d.h"

#include <cmath>
#include "math.h"

namespace System{
namespace Math{

void Vector2D::Reset(){
m_x = 0;
y(0);
}

double Vector2D::x(double x)
{
m_x = x;
m_direction = atan2(m_y, m_x);
m_length = sqrt((m_x * m_x) + (m_y * m_y));
}
double Vector2D::y(double y)
{
m_y = y;
m_direction = atan2(m_y, m_x);
m_length = sqrt((m_x * m_x) + (m_y * m_y));
}
double Vector2D::Direction(double a){
m_direction = a;
m_x = cos(m_direction) * m_length;
m_y = sin(m_direction) * m_length;
}
double Vector2D::Length(double m){
m_length = m;
m_x = cos(m_direction) * m_length;
m_y = sin(m_direction) * m_length;
}
void Vector2D::SetPoints(double x, double y){
m_x = x;
m_y = y;
m_length = sqrt((m_x * m_x) + (m_y * m_y));
m_direction = atan2(m_y,m_x);
}


void Vector2D::ReflectAngle(int NormalAngle)
{
int NormDiffAngle; //difference between the inverted angle & the BoundaryNormal angle
int angle = (int)RAD2DEG(m_direction); // new angle
int OppAngle = (angle + 180) % 360; // Inverted angle
if( NormalAngle >= OppAngle ){
NormDiffAngle = NormalAngle - OppAngle;
angle = (NormalAngle + NormDiffAngle) % 360;
} else {
NormDiffAngle = OppAngle - NormalAngle;
angle = NormalAngle - NormDiffAngle;
if( angle < 0 ) angle += 360;
}

this->Direction(DEG2RAD(angle));
}


// scalar operators for speed and resolving ambiguity problems
// with implicit constructor calls

/// Componentwise addition
Vector2D& Vector2D::operator+= (double f) {
SetPoints(m_x + f, m_y + f);
return *this;
}

/// Componentwise subtraction
Vector2D& Vector2D::operator-= (double f) {
SetPoints(m_x - f, m_y - f);
return *this;
}

/// Componentwise multiplication
Vector2D& Vector2D::operator*= (double f) {
SetPoints(m_x * f, m_y * f);
return *this;
}

/// Componentwise division
Vector2D& Vector2D::operator/= (double f) {
SetPoints(m_x / f, m_y / f);
return *this;
}


// Vector arithmetic operators

Vector2D& Vector2D::operator+= (Vector2D& v) {
SetPoints(m_x + v.x(), m_y + v.y());
return *this;
}

Vector2D& Vector2D::operator-= (Vector2D& v) {
SetPoints(m_x - v.x(), m_y - v.y());
return *this;
}

Vector2D& Vector2D::operator*= (Vector2D& v) {
SetPoints(m_x * v.x(), m_y * v.y());
return *this;
}

Vector2D& Vector2D::operator/= (Vector2D& v) {
SetPoints(m_x / v.x(), m_y / v.y());
return *this;
}


}
}






Share this post


Link to post
Share on other sites
Are you sure you have a problem? You state that you shoot to the right, and your ship is moving up, which would make the bullet move down and right relative to the ship. This seems right. To verify, as soon as you fire the shot, zero out the ship's velocity and see if the bullet is flying right.

As other's have said, you need the ability to output text on the screen. You could then dump the bullet's velocity and hopefully see that it is (x,0)

Share this post


Link to post
Share on other sites
Quick question: Does your camera stay centered on your ship? (Your ship is always in the center of the screen?) If the camera was moving with it it could make it harder to visualize the actual trajectory of the bullet.

One other thing: Let's assume you're using OpenGL or Direct3D for the drawing. Are you setting the transformation matrix to the identity after drawing the ship? Again, if not you can get some unexpected results.

Sorry if neither of those help. Just throwing out ideas.

Share this post


Link to post
Share on other sites

This topic is 4581 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this