|
-
March 27th, 2012, 12:20 PM
#1
Still Some Trouble Creating Gravity
Hi, I've been having trouble working on this physics engine of mine. Right now I'm having trouble adding gravity.
The game is a spaceship--which you control--flying around in space with asteroids and eventually the ability to shoot bullets. There should be a wrap on the edges of the screen and gravity for each object depending on their mass.
I'm creating a forceX and forceY for each force put onto each object, and then computing that force into a velX and velY which will determine the direction of each object and at which speed.
Where my problem arises:
Code:
//add gravity pulls to forces
for(int i = 0; i <= pushCount; i++) //add gravity pulls for each object
{
for(int u = 0 ; u <= pushCount; u++) //each object should add a force for every other object
{
if(i != u)
{
switch(id[i])
{
case ASTEROID_ID:
switch(id[u])
{
case ASTEROID_ID: //m1 = ASTEROID_MASS, m2 = ASTEROID_MASS
tempForce = ( (GRAV_CONST * ASTEROID_MASS * ASTEROID_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case SPACESHIP_ID: //m1 = ASTEROID_MASS, m2 = SPACESHIP_MASS
tempForce = ( (GRAV_CONST * ASTEROID_MASS * SPACESHIP_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case BULLET_ID: //m1 = ASTEROID_MASS, m2 = BULLET_MASS
tempForce = ( (GRAV_CONST * ASTEROID_MASS * BULLET_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
}
break;
case SPACESHIP_ID:
switch(id[u])
{
case ASTEROID_ID: //m1 = SPACESHIP_MASS, m2 = ASTEROID_MASS
tempForce = ( (GRAV_CONST * SPACESHIP_MASS * ASTEROID_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case BULLET_ID: //m1 = SPACESHIP_MASS, m2 = BULLET_MASS
tempForce = ( (GRAV_CONST * SPACESHIP_MASS * BULLET_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
}
break;
case BULLET_ID:
switch(id[u])
{
case ASTEROID_ID: //m1 = BULLET_MASS, m2 = ASTEROID_MASS
tempForce = ( (GRAV_CONST * BULLET_MASS * ASTEROID_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case SPACESHIP_ID: //m1 = BULLET_MASS, m2 = SPACESHIP_MASS
tempForce = ( (GRAV_CONST * BULLET_MASS * SPACESHIP_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case BULLET_ID: //m1 = BULLET_MASS, m2 = BULLET_MASS
tempForce = ( (GRAV_CONST * BULLET_MASS * BULLET_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
}
break;
}
tempAngle = atan2( ( (x[i]-x[u]) / tempForce ), ( (y[i]-y[u]) / tempForce ) );
if( (tempAngle * 180 / PI) > 0 && 90 > (tempAngle * 180 / PI) ) //sin +, cos +
{
forceX[i] += cos(tempAngle);
forceY[i] += sin(tempAngle);
}
else
if( (tempAngle * 180 / PI) > 90 && 180 > (tempAngle * 180 / PI) ) //sin +, cos -
{
forceX[i] += -cos(tempAngle);
forceY[i] += sin(tempAngle);
}
else
if( (tempAngle * 180 / PI) > 180 && 270 > (tempAngle * 180 / PI) ) //sin -, cos -
{
forceX[i] += -cos(tempAngle);
forceY[i] += -sin(tempAngle);
}
else
if( (tempAngle * 180 / PI) > 270 && 360 > (tempAngle * 180 / PI) ) //sin -, cos +
{
forceX[i] += cos(tempAngle);
forceY[i] += -sin(tempAngle);
}
}
}
}
And then my entire engine.cpp code, if necessary:
Code:
#include <vector>
#include <string>
#include <math.h>
#include <valarray>
#include "constants.h"
using namespace std;
void crunchCommand(string command, int pushCount, vector<int> id, vector<float> & x, vector<float> & y, vector<int> & angle, vector<float> & velX, vector<float> & velY, vector<float> & forceX, vector<float> & forceY)
{
float
tempForce,
tempAngle,
ratio;
if(command == "right")
{
if(angle.front() + 1 <= 71) //if a turn right doesn't overflow the 72 limit, turn right one.
angle.front() = angle.front() + 1;
else //else it does overflow, so wrap back to the first angle.
angle.front() = 0;
}
else
if(command == "left")
{
if(angle.front() - 1 >= 0) //if a turn left doesn't go below 0 (the first angle), turn left one.
angle.front() = angle.front() - 1;
else //else it does go below 1, so wrap back to the last angle (72)
angle.front() = 71;
}
else
if(command == "space")
{
//shoot a bullet.. pause for now
velX[0] = 0;
velY[0] = 0;
forceX[0] = 0;
forceY[0] = 0;
}
else
if(command == "up")
{
if(angle[0] == 0)
forceY[0] = -1;
else
if(angle[0] == 36)
forceY[0] = 1;
else
if(angle[0] == 18)
forceX[0] = 1;
else
if(angle[0] == 54)
forceX[0] = -1;
else
{
forceX[0] = sin(angle[0] * 5 * (PI / 180)); //force of 1 per tick
forceY[0] = -cos(angle[0] * 5 * (PI / 180)); //force of 1 per tick.. negative cosine to account for the reversed y-axis
}
}
//add gravity pulls to forces
for(int i = 0; i <= pushCount; i++) //add gravity pulls for each object
{
for(int u = 0 ; u <= pushCount; u++) //each object should add a force for every other object
{
if(i != u)
{
switch(id[i])
{
case ASTEROID_ID:
switch(id[u])
{
case ASTEROID_ID: //m1 = ASTEROID_MASS, m2 = ASTEROID_MASS
tempForce = ( (GRAV_CONST * ASTEROID_MASS * ASTEROID_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case SPACESHIP_ID: //m1 = ASTEROID_MASS, m2 = SPACESHIP_MASS
tempForce = ( (GRAV_CONST * ASTEROID_MASS * SPACESHIP_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case BULLET_ID: //m1 = ASTEROID_MASS, m2 = BULLET_MASS
tempForce = ( (GRAV_CONST * ASTEROID_MASS * BULLET_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
}
break;
case SPACESHIP_ID:
switch(id[u])
{
case ASTEROID_ID: //m1 = SPACESHIP_MASS, m2 = ASTEROID_MASS
tempForce = ( (GRAV_CONST * SPACESHIP_MASS * ASTEROID_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case BULLET_ID: //m1 = SPACESHIP_MASS, m2 = BULLET_MASS
tempForce = ( (GRAV_CONST * SPACESHIP_MASS * BULLET_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
}
break;
case BULLET_ID:
switch(id[u])
{
case ASTEROID_ID: //m1 = BULLET_MASS, m2 = ASTEROID_MASS
tempForce = ( (GRAV_CONST * BULLET_MASS * ASTEROID_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case SPACESHIP_ID: //m1 = BULLET_MASS, m2 = SPACESHIP_MASS
tempForce = ( (GRAV_CONST * BULLET_MASS * SPACESHIP_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
case BULLET_ID: //m1 = BULLET_MASS, m2 = BULLET_MASS
tempForce = ( (GRAV_CONST * BULLET_MASS * BULLET_MASS) / ( (float)sqrt( (x[i]-x[u])*(x[i]-x[u]) + (y[i]-y[u])*(y[i]-y[u]) ) ) );
break;
}
break;
}
tempAngle = atan2( ( (x[i]-x[u]) / tempForce ), ( (y[i]-y[u]) / tempForce ) );
if( (tempAngle * 180 / PI) > 0 && 90 > (tempAngle * 180 / PI) ) //sin +, cos +
{
forceX[i] += cos(tempAngle);
forceY[i] += sin(tempAngle);
}
else
if( (tempAngle * 180 / PI) > 90 && 180 > (tempAngle * 180 / PI) ) //sin +, cos -
{
forceX[i] += -cos(tempAngle);
forceY[i] += sin(tempAngle);
}
else
if( (tempAngle * 180 / PI) > 180 && 270 > (tempAngle * 180 / PI) ) //sin -, cos -
{
forceX[i] += -cos(tempAngle);
forceY[i] += -sin(tempAngle);
}
else
if( (tempAngle * 180 / PI) > 270 && 360 > (tempAngle * 180 / PI) ) //sin -, cos +
{
forceX[i] += cos(tempAngle);
forceY[i] += -sin(tempAngle);
}
}
}
}
//compute force to velocity
velX[0] += (forceX[0] / SPACESHIP_MASS) * ACCEL; //scaler of ACCEL .. makes objects obtain force slower
velY[0] += (forceY[0] / SPACESHIP_MASS) * ACCEL; //scaler of ACCEL
for(int i = 1; i <= pushCount; i++)
{
velX[i] += (forceX[i] / ASTEROID_MASS);
velY[i] += (forceY[i] / ASTEROID_MASS);
}
//limit the speed of every object pushed into the game. (will need to make special case for bullets)
for(int i = 0; i <= pushCount; i++)
{
if(sqrt(velX[i]*velX[i] + velY[i]*velY[i]) > MAX_VELOCITY)
{
ratio = MAX_VELOCITY / sqrt(velX[i]*velX[i] + velY[i]*velY[i]);
velX[i] = velX[i] * ratio;
velY[i] = velY[i] * ratio;
}
}
//change position of x and y
for(int i = 0; i <= pushCount; i++)
{
if((x[i] + velX[i]) > SCREEN_WIDTH) //if x gets bigger than maxX, wrap
x[i] = velX[i] - SCREEN_WIDTH - x[i];
else
if(x[i] + velX[i] < 0)
x[i] = SCREEN_WIDTH + velX[i] + x[i]; //if x gets smaller than minX, wrap
else
x[i] += velX[i];
if((y[i] + velY[i]) > SCREEN_HEIGHT) //if y gets bigger than maxY, wrap
y[i] = velY[i] - SCREEN_HEIGHT - y[i];
else
if(y[i] + velY[i] < 0)
y[i] = SCREEN_HEIGHT + velY[i] + y[i]; //if y gets smaller than minY, wrap
else
y[i] += velY[i];
}
}
Any help would be very much appreciated. This has cost me countless hours of headache, and is due Wednesday (extended from Monday).
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|