Jump to content
  • Advertisement
Sign in to follow this  
glopen

Vectors and bullet aiming. [Getting inconsistent results :( ]

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

The bullet that I'm using has a constructor like this:
bullet(float xx, float yy, float zz, float x1, float y1, float z1,..) {

		x=xx, y=yy, z=zz;                    //sets origin
		t[0]=x1-xx, t[1]=y1-yy, t[2]=z1-zz;  //sets vec toward target i.e. r=r1-r2?
		norm(t);                             //normalize
//other stuff
}
When I shoot I do: bullet *p = new bullet(player.x,player.y,player.z,player.x-player.f.x,player.y-player.f.y,player.z-player.f.z,...); Note that f is player's forward vector and I'm sending (player.x MINUS player.f.x) because for whatever reason my forward vector is opposite to my direction of motion. As far as the player is concerned, this works perfectly. But I get super inconsistencies when it comes to having other object aim at player: bullet *p = new bullet(x,y,z,player.x,player.y,player.z,...); Shouldn't this code work? What I'm getting is the enemies hitting player only when it is in certain areas around the enemy. Otherwise it's pretty hopeless. I tried it without normalizing the vector t and it showed a line from the enemy to the player which at least suggests that something is working right. Where am I going wrong with this? Thanks. [Here's how I update bullet position, in case there's something wrong here: x+=(speed*t[0]); y+=(speed*t[1]); z+=(speed*t[2]); ]

Share this post


Link to post
Share on other sites
Advertisement
I think your problem is probably not in the code you have posted. Try to find a specific example where the code doesn't do the right thing, and check by hand if all the computations make sense. You can post the specific example if you need help understanding it.

Share this post


Link to post
Share on other sites
Well, as I said I don't understand why the enemies are shooting at random directions for few seconds (I made it so that it shoots continuously) most of the time and at the target for the rest. I tried some alterations and it seems that it is not moving in the direction that it should with the x+=speed*t[0] etc. code. Shouldn't ray tracing just be about getting a normalized vector and multiplying a scalar with it?

Share this post


Link to post
Share on other sites
you should really use a vector class, that would help you a lot and make the code more bearable to read.

here's an example


inline void myDebugBreak(const char* assertString, const char* file, int line)
{
char buff[512];
sprintf_s(buff, sizeof(buff), "file \"%s\", line(%d) : assert(%s) failed.\n", file, line, assertString);
fprintf(stderr, buff);
DebugBreak();
}

#define myAssert(A) { if(!(A)) { myDebugBreak(#A, __FILE__, __LINE__); } };

class Vector
{
public:
union
{
float coord[3]; // coords as an array
struct { float x, y, z; }; // coords are a triple
};

Vector()
{}

Vector(float ix, float iy, float iz)
: x(ix)
, y(iy)
, z(iz)
{}

Vector(const float* icoord)
: x(icoord[0])
, y(icoord[1])
, z(icoord[2])
{}

Vector(const Vector& other)
: x(other.x)
, y(other.y)
, z(other.z)
{}

float operator[](int i) const { myAssert(i >= 0 && i < 3); return coord; }
float& operator[](int i) { myAssert(i >= 0 && i < 3); return coord; }

Vector& operator+=(const Vector& other) { x += other.x; y += other.y; z += other.z; return *this; }
Vector& operator-=(const Vector& other) { x -= other.x; y -= other.y; z -= other.z; return *this; }
Vector& operator*=(float k) { x *= k; y *= k; z *= k; return *this; }
Vector& operator/=(float k) { myAssert(fabs(k) > 1.0E-8f); float ik = 1.0f / k; return (*this) *= ik; }

Vector operator+(const Vector& other) const { Vector temp(*this); return temp += other; }
Vector operator-(const Vector& other) const { Vector temp(*this); return temp -= other; }
Vector operator*(float k) const { Vector temp(*this); return temp *= k; }
Vector operator/(float k) const { Vector temp(*this); return temp /= k; }

Vector operator-() const { return Vector(-x, -y, -z); }
friend Vector operator*(float k, const Vector& v) { return v * k; }

Vector scaleProduct(const Vector& other) const { return Vector((x*other.x), (y*other.y), (z*other.z)); }
Vector crossProduct(const Vector& other) const { return Vector((y*other.z) - (z*other.y), (z*other.x) - (x*other.z), (x*other.y) - (y*other.x)); }
float dotProduct(const Vector& other) const { return (x*other.x) + (y*other.y) + (z*other.z); }

Vector operator&(const Vector& other) const { return crossProduct(other); } // cross product operator
Vector operator^(const Vector& other) const { return scaleProduct(other); } // scale product operator
float operator*(const Vector& other) const { return dotProduct(other); } // dot product operator

float lengthSquared() const { return (x*x + y*y + z*z); }
float length() const { return sqrt(lengthSquared()); }

Vector normalised() const
{
float l = length();
if(fabs(l) < 1.0E-8f)
{
myAssert(!"zero-length vector cant be normalised");
return Vector(1, 0, 0);
}
return (*this) / l;
}

float normalise()
{
float l = length();

if(fabs(l) < 1.0E-8f)
{
myAssert(!"zero-length vector cant be normalised");
x = y = z = 0.0f;
return 0.0f;
}
(*this) /= l;
return l;
}
};


your code would look like


bullet::bullet(const Vector& origin, const Vector& target, ...)
{
m_position = origin;
m_direction = (target - origin);
m_direction.normalise();
}

bullet::update()
{
m_position += m_direction * m_speed;
}

bullet *p = new bullet(player.m_position, player.m_position - player.m_forward, ...);

// or...



Otherwise, it looks like it's somewhere else in the code. maybe the normalisation is wrong?

[Edited by - oliii on June 17, 2008 8:02:52 AM]

Share this post


Link to post
Share on other sites
Wow! What an awesome post! Yeah I guess I'll have to switch to a vector class sometime. Not quite my question but thanks!

As I went over the normalization function I sort of found this:
v[0]=v[0]/mag(v);
v[1]=v[1]/mag(v);
...

I should really be kicking myself for being such a dolt.

Either way, however, the aiming is still off and I'm positive there's no more mistakes in the code. Only after increasing the bullet speed and some quick and dirty motion planning can I hit the target. What bothers me is that my previous efforts ditching vectors and using angles (atan2()) instead gave way better results. Anyway, thanks for info.

Share this post


Link to post
Share on other sites
yep, that normalisation is wrong :)

Using a vector class is not only more efficient and easier on the eye, it makes it easier to catch bugs like these, it's easy to get a sign wrong and not notice.

One word of caution with operators, be careful of their precedence.

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!