-
Augh!
Okay, I'm sorry for dumping alot of code on you guys... but I'm at wit's end about this.
I'm writing a 2D Space Shooter, in SDL. But that's not the problem. It has nothing to do with the SDL API.
Everything works perfectly, my little ship rotates fine, moves perfectly, except under strange circumstances. When I start up the game, and start rotating to the right and moving immediately forward, after about a half a second, the ship's x and y values both jump to -2147483648, and moving does nothing to change those values. Even saying x = 0 doesn't do it.
Vectoring conversions just use basic trig, they're not the problem.
Code:
void Object::ForceAct(double degrees, double power)
{
VECTORSTRUCT vector;
VECTORSTRUCT newvector;
vector.degrees = direction;
vector.power = speed;
newvector.degrees = degrees;
newvector.power = power;
DegreesToVector(&vector);
DegreesToVector(&newvector);
vector.x += newvector.x;
vector.y += newvector.y;
VectorToDegrees(&vector);
speed = vector.power;
if (speed > maxspeed)
speed = maxspeed;
direction = vector.degrees;
}
void Object::RotateAct(int degrees)
{
rotation += degrees;
if (rotation > 359)
rotation -= 360;
if (rotation < 0)
rotation += 360;
}
void Object::MoveObject()
{
VECTORSTRUCT vector;
vector.degrees = direction;
vector.power = speed;
DegreesToVector(&vector);
x += vector.x;
y += vector.y;
}
void StateObject::Step(SDL_Surface* buffer)
{
int count;
DetectKeyStrokes();
for (count = 0; count < SCREEN_WIDTH*SCREEN_HEIGHT; count++)
((unsigned int*)screen->pixels)[count] = RGB(0,0,0);
for (count = 0; count < MAX_SHIPS; count++){
if (ShipPointers[count] == NULL)
break;
else{
ShipPointers[count]->MoveObject();
ShipPointers[count]->DrawObject(buffer);
}
}
}
void StateObject::DetectKeyStrokes()
{
if (GetAsyncKeyState(KEY_RIGHT))
CurrentStateObject->ShipPointers[PlayerNumber]->RotateAct(5);
if (GetAsyncKeyState(KEY_LEFT))
CurrentStateObject->ShipPointers[PlayerNumber]->RotateAct(-5);
if (GetAsyncKeyState(KEY_UP))
CurrentStateObject->ShipPointers[PlayerNumber]->ForceAct(CurrentStateObject->ShipPointers[PlayerNumber]->rotation,CurrentStateObject->ShipPointers[PlayerNumber]->thrust);
if (GetAsyncKeyState(KEY_DOWN))
CurrentStateObject->ShipPointers[PlayerNumber]->speed = 0;
}
Now... that's everything that has any relevance with moving. Can anyone find any fault with it, and why it might do that?
-
I don't see anything wrong, perhaps in the code for DegreesToVector(), post it
-
Here's the whole vector.h file.
Code:
typedef struct {
double degrees;
double power;
double x;
double y;
} VECTORSTRUCT, *PVECTORSTRUCT;
inline double DegreesToRadians(double radians)
{
return ( radians * ( M_PI / 180 ));
}
inline double RadiansToDegrees(double degrees)
{
return ( degrees / ( M_PI / 180));
}
void VectorToDegrees(PVECTORSTRUCT structure)
{
structure->power = sqrt((structure->x*structure->x)+(structure->y*structure->y));
if (structure->x == 0){
if (structure->y > 0)
structure->degrees = 180;
else if (structure->y < 0)
structure->degrees = 0;
}
else if (structure->y == 0){
if (structure->x > 0)
structure->degrees = 90;
else if (structure->x < 0)
structure->degrees = 270;
}
else{
if (structure->x > 0){
if (structure->y < 0)
structure->degrees = structure->x/structure->power;
else
structure->degrees = structure->y/structure->power;
}
else{
if (structure->y < 0)
structure->degrees = structure->y/structure->power;
else
structure->degrees = structure->x/structure->power;
}
structure->degrees = RadiansToDegrees(asin(structure->degrees));
if (structure->degrees < 0)
structure->degrees *= -1;
if (structure->x > 0){
if (structure->y > 0)
structure->degrees += 90;
}
else{
if (structure->y > 0)
structure->degrees += 180;
else
structure->degrees += 270;
}
}
}
void DegreesToVector(PVECTORSTRUCT structure)
{
double x = 0;
double y = 0;
double temp = 0;
if (structure->degrees != 0 && structure->degrees != 90 && structure->degrees != 180 && structure->degrees != 270){
y = structure->degrees;
y = sin(DegreesToRadians(y));
y *= structure->power;
x = structure->power;
x *= x;
x -= y*y;
x = sqrt(x);
if (structure->degrees < 90 || structure->degrees == 360){
temp = x;
x = y;
y = temp*-1;
}
else if (structure->degrees < 180){
temp = x;
x = y;
y = temp;
}
else if (structure->degrees < 270){
temp = x;
x = y;
y = temp;
}
else{
temp = x;
x = y;
y = temp*-1;
}
}
else if (structure->degrees == 0)
y = structure->power*-1;
else if (structure->degrees == 90)
x = structure->power;
else if (structure->degrees == 180)
y = structure->power;
else if (structure->degrees == 270)
x = structure->power*-1;
structure->x = x;
structure->y = y;
}
It works in a console app, I've tested it, and it works visually... I don't know why it would be crazy like this..
Oh and X and Y are Double Values, not Ints. That might have something to do with it.
-
if (rotation > 359)
rotation -= 360;
This will yield -1 when rotation is 360. Since it's a double it should handle it, but rotating from 359 to -1 might cause some issues.
-
Hmm...
I changed it to >= 360, and the problem still occurs...
-
> x *= x;
> x -= y*y;
> x = sqrt(x);
How about roots of negative numbers?
> if (structure->degrees < 90 || structure->degrees == 360)
This tells me your modulo arithmetic isn't up to scratch.
Also, floats and doubles are approximations. You should never test them using == or !=
Something might easily pass a != 0 test, but be so stupidly close to zero to be as good as zero as far as some other calculation (say a division) to blow up in your face.
-
Aha! I typecasted them, and it's working. Sorry, I wrote that code a while back, and didn't bother to check it again, and didn't want to bother writing a new one. I know it's kind of inefficient. I think I have a more up to date version on another comp... anyway. Thanks.