Sign in to follow this  
CodeBox

Qbasic Gorilas/Worms physics, 10 pound for grabes

Recommended Posts

Hi I am doing a program in C++ and OpenGL. My program Is based on the old classic Qbasic Gorilas! This is basically a simple verson of worms! Basically you have two gorilas that throw a banana when the banana hits the gorila loses a life and the envirement changes. there is 10 building and each gorila is randomly placed on the building! I have done this bit! Then the player types in the angle and verlocity/strength/force they wish to throw the banana (this is all based in a 2d enviroment). I can't for the life of me work out the maths to get the banana to fall at a gravity of 9.81 and am not sure how vectors work is it just like a grapth (x,y). Am basically looking for some one to help me with the physics side! So when I type angle 60 and strength 100. Banana goes up arcs and hits or misses gorlia, I can do collistion ditection points and that just strugling on physics! Thanks for your help in advance! I would also be willing to give X person £10 to a paypal Account If they answer with in 3 hours of this post and I understand what they mean!

Share this post


Link to post
Share on other sites
This is basic vector math.

A vector or point in 2d has two members, an x and a y value. So your banana will have a position point {x, y} and a velocity {vx, vy}. Your game world will excert an acceleration in the form of gravity {ax, ay}, whose value will be {0, -9.81}. With me so far?

Lets assume that your banana starts out at {0,0}. You are trying to throw it at 60 degrees up from horizontal, at 100 speed/strength. What we have to do is build a velocity vector from that information. This needs trigonmetry. Your x value will be strength*cos(angle) and y will use the sin, so the vector will be {100*cos(60), 100*sin(60)}

All this information adds together like this: each time interval the position will be updated by the velocity, and the velocity updated by the acceleration. So after 1 time interval, the banana will have:
Position: {100*cos(60), 100*sin(60)}
Velocity: {100*cos(60), 100*sin(60) - 9.81}
Acceleration: {0, -9.81}

And after 2 time intervals:
Position: {100*cos(60)+100*cos(60), 100*sin(60)+100*sin(60) - 9.81}
Velocity: {100*cos(60), 100*sin(60) - 9.81 - 9.81}
Acceleration: {0, -9.81}


I think that's right. Basically, you have to read up on trig and vectors.

Share this post


Link to post
Share on other sites
Hi,

I understand so far and have that, If you can tell me what I to do this in real time do I just * it by my time?

This is what I have at the moment this is updated every frame what am I doing wrong?

//this is suppost to work out what angle the banana is at at each iteration
bananaX= strength * cos( angle );
bananaY= strength * sin( angle );

//this is suppose to add the gravity and wind accelaration on these angles
bananaX += wind;
bananaY += gravity;

//this adds the gorilas postion so the banana sets off from right place
bananaX += CurrentMonkey2CoX;
bananaY += CurrentMonkey2CoY;

I donno whats wrong I did the following

wind is a constant of 1 at moment not fused about that, I timesed my graphity by the seconds past and it just goes up and up now? :S


Thanks

Edit*
I will give you the money if you can explain to me the answer before the end of this hour, it's 6.21am here so 40mins! [Edited by - CodeBox on November 25, 2005 12:43:44 AM] If you so this then 1:30am.
*

[Edited by - CodeBox on November 25, 2005 12:43:28 AM]

Share this post


Link to post
Share on other sites
I'll try to help:

Quote:
Original post by CodeBox
//this is suppost to work out what angle the banana is at at each iteration
bananaX= strength * cos( angle );
bananaY= strength * sin( angle );

Shouldn't this be

bananaX+= strength * cos( angle );
bananaY+= strength * sin( angle );

Quote:

//this is suppose to add the gravity and wind accelaration on these angles
bananaX += wind;
bananaY += gravity;


Edit: ok the acceleration code isn't going to work because those need to operate on your (strength, angle) vector and NOT directly on the banana's position. That is the problem here, my suggestion on how to fix it is below.

Quote:

//this adds the gorilas postion so the banana sets off from right place
bananaX += CurrentMonkey2CoX;
bananaY += CurrentMonkey2CoY;

This code should be:

bananaX = CurrentMonkey2CoX;
bananaY = CurrentMonkey2CoY;

except executed ONLY ONCE when the throw starts and not every frame. Good luck...

Share this post


Link to post
Share on other sites
Try this. It is an excpet from my particle class.

void particle::gravMove(unsigned long tTime){

double currentTime, t;
t = (double)(1.0/1000);
currentTime = (double)((tTime - this->oldTime) * t);

this->oldX = this->x;
this->oldY = this->y;
this->x = this->x0 + ((this->velocity * cos(this->theta))* currentTime);
this->y = this->y0 + (((this->velocity * sin(this->theta))* currentTime) + (9.81 *(currentTime*currentTime))/2);

}


Theta is the angle that the particle was launched at.
Velocity can be related to strength in your case.
x0 and y0 are coordinates that the particle was launched from.
oldX, and oldY are the previous coordinates of the particle.
However you manager time in your game I am sure you can ada[t my time calculations pretty easily to it.

I hope that helps. And I don't want any money if it does.

Share this post


Link to post
Share on other sites
Here is the easiest way I think to fix your code: don't operate with strength and angle directly. Just do this ONCE when the banana is thrown:
veloX = strength * cos(angle);
veloY = strength * sin(angle);

Then
bananaX += veloX;
bananaY += veloY;

and finally
veloY += gravity;
veloX += wind;


I think that is easier.

Share this post


Link to post
Share on other sites
I'll try to make this as simple as possible. I'm not sure that this is what your after, but it's my best guess.

//On fire:
BananaPosX = GorillaPosX;
BananaPosY = GorillaPosY;
BananaVelX = cos(angle) * strength;
BananaVelY = sin(angle) * strength;
if (GorillaFacingLeft)
BananaVelX = -BananaVelX;

//In game loop:
t = timeSinceLastUpdate;
BananaPosX += BananaVelX * t;
BananaPosY += BananaVelY * t;
BananaVelX += (windSpeed - BananaVelX) * t;
BananaVelY -= 9.81 * t;
//Check for collision.



EDIT: Improved wind formula

[Edited by - RAZORUNREAL on November 25, 2005 1:29:30 AM]

Share this post


Link to post
Share on other sites
Hi razo!

That seems to be working the only problem is I chuck it and about a second after the banana starts going down! It also shacks and only goes straight up depending on the angle it goes higher!

Can you see whats wrong?

.....double angleDouble=angle;
.....if (GotThrowTime1==false){
...........timeOfThrow=runTime;
...........bananaVelX = cos(angleDouble) * strength;
...........bananaVelY = sin(angleDouble) * strength;
...........if (Player_1_turn==true) {
...............bananaX = CurrentMonkey1CoX;
...............bananaY = CurrentMonkey1CoY;
...........} else {
...............bananaX = CurrentMonkey2CoX;
...............bananaY = CurrentMonkey2CoY;
...........}
...........GotThrowTime1=true;
......}

......double SecondsSinceThrow=(timeOfThrow-runTime)/100;
......double wind=0,gravity=9.81;

......bananaX += bananaVelX * SecondsSinceThrow;
......bananaY += bananaVelY * SecondsSinceThrow;
......bananaVelX += ((wind-bananaVelX) * SecondsSinceThrow);
......bananaVelY -= (gravity * SecondsSinceThrow);
......if (Player_2_turn=true){
..........bananaVelX = -bananaVelX;
......}

Coz am daft I called my gorilas monkeys because they look like monkeys not gorilas!

I noticed my bool had one = at bottom, it looks better now but only one problem it does not seem to be going in the right direction?

[Edited by - CodeBox on November 25, 2005 3:08:29 AM]

Share this post


Link to post
Share on other sites
I can't understand it I type in:

angle=45;
strength=45;

the banana goes

.....................................ban
...................................ban
.................................ban
.............................ban
.......................ban
..............ban
.....ban

gone what the hell am I doing wrong?

By the way am starting banana at 0,0 so I can work out if it looks like its working or not!

Edit*
By the way I checked to see if I changed the angle to -180 each time but the banana does not slow down just speed up!
*

[Edited by - CodeBox on November 25, 2005 3:45:35 AM]

Share this post


Link to post
Share on other sites
If your aschi art is not on it's side, then perhaps you should swap cos and sin... I don't know. Positive Y is up right?

Quote:
Original post by CodeBox
timeOfThrow=runTime;
...
double SecondsSinceThrow=(timeOfThrow-runTime)/100;


That's not quite what I meant. Your using the time since it was thrown, where I was using the time since it was last updated. So you'd go like this:

//global (outside your game loop anyway)
double lastTime;

//start of game loop
double time = runTime; //if your runtime variable will stay the same throughout the loop just use that
double tick = (time - lastTime);
//at the very end of game loop, outside of any if's and everything:
lastTime = time;


Quote:
Original post by CodeBox
if (Player_2_turn=true){
....bananaVelX = -bananaVelX;
}


You're not doing that every frame are you? You should only do it when you create the banana.

Quote:
Original post by CodeBox
Coz am daft I called my gorilas monkeys because they look like monkeys not gorilas!


Easier to spell anyway. [smile]

EDIT: Oh, I see you've made another thread. Oh well.

Share this post


Link to post
Share on other sites
in very badly described physics:

velocity is change in position over time
acceleration is change in velocity over time

force is proportional to acceleration, acceleration is change in speed over time, gravity is a constant force (at least for our purposes it is), so the change in speed is going to be a constant. Thus on every frame add on a constant to the velocity and you'll get a pretty good approximation to gravity.

Have the velocity as a vector, on every game frame add on a constant (e.g. -0.1). Dont bother trying to work-out exact real-life values, or take into account mass etc. it wont buy you anything particularly.

so if the velocity of the banana starts out at 45 degrees : ( 0.2, 0.2 ), add this on to the position of the banana every frame. But also subtract your gravity constant (e.g. 0.01) every frame from the velocity vector, (so in vector form, (0,-0.01) from the second element of the velocity every frame.

If you use a vector for acceleration each time, you could easily add a wind-like effect by doing something like (0.01, -0.01) - then your banana well get 'blown' to the right as well as pulled down by gravity. (you could make the wind random each time a new frame starts,

so the velocity will go:

( 0.2, 0.2 ) // its shooting up at 45-degrees
( 0.2, 0.19 )
( 0.2, 0.18 ) // its gradually slowing
( 0.2, 0.17 )
...
( 0.2, 0.01 )

( 0.2, 0 ) // its reached the peak of its flight

( 0.2, -0.01 ) // now its falling
( 0.2, -0.02 )
( 0.2, -0.03 )
( 0.2, -0.04 ) // now its falling faster...

If you want a firmer understanding, there should be a section on it in any basic (high school) maths book - it'll be under something like mechanics: acceleration / gravity on a free-body etc.

Remember that in games you are trying to create a believable approximation to real-world behaviour, not produce a precise physical model - that is, you never need to worry about constants etc. too much, just find some that look about right, and never bother differentiating/integrating values - just accumulate or take differences between values between two successive frames etc. - its not physically accurate, but it is physically approximate, and thats good enough to give a very realistic feel.

Share this post


Link to post
Share on other sites
//The *starting* velocity of the banana is this (it will change):
BananaVelX = strength * cos( angle );
BananaVelY = strength * sin( angle );

Gravity = -0.01; // dont worry about 9.81 - find what feels good
Wind = 0;

// now the came loop
while( Your-Game-Loop )
{
// apply velocity to banana position (velocity is change in place / time )
BananaX += BananaVelX;
BananaY += BananaVelY;

// apply acceleration to velocity - (acceleration is change in velocity/time)
BananaVelY += Gravity;
BananaVelX += Wind;
}




thats it.

Share this post


Link to post
Share on other sites
ok this is what I have now!

 

double angleDouble=angle;
if (GotThrowTime1==false){

bananaVelX = (cos(angleDouble) * strength);
bananaVelY = (sin(angleDouble) * strength);
if (Player_1_turn==true) {
bananaX = CurrentMonkey1CoX;
bananaY = CurrentMonkey1CoY;
} else {
bananaX = CurrentMonkey2CoX;
bananaY = CurrentMonkey2CoY;
}
if (Player_2_turn==true){
bananaVelX = -bananaVelX;
}
GotThrowTime1=true;
}

double wind=0,gravity=9.81;

bananaX += bananaVelX * timeSinceLastUpdate;
bananaY += bananaVelY * timeSinceLastUpdate;

bananaVelX += (wind) * timeSinceLastUpdate;
bananaVelY -= (gravity * timeSinceLastUpdate);

glBegin(GL_POLYGON);
glColor3d(1,1,0);
glVertex2f(bananaX,bananaY);
glVertex2f(bananaX,bananaY-5);
glVertex2f(bananaX-5,bananaY-5);
glVertex2f(bananaX-5,bananaY);
glEnd();
timeSinceLastUpdate=runTime/100;



Whats wrong with it? it's ok when I put in 5, 20, 40, 45, 60, 80.

But numbers like 10,30,50,70 make it go the wrong way am completely confused on what the hell is going on?

Share this post


Link to post
Share on other sites
Quote:
Original post by CodeBox
ok this is what I have now!

*** Source Snippet Removed ***

Whats wrong with it?


Well, as far as I can tell your still using the entire time. Your just setting a timeSinceLastUpdate variable to what the time is every frame, not the difference in time from 1 frame to the next. Try this:


double timeSinceLastUpdate = runTime/100 - lastUpdateTime;
lastUpdateTime = runTime/100; //lastUpdateTime must be created outside the loop, so it keeps its value.
double angleDouble=angle;
if (GotThrowTime1==false){

bananaVelX = (cos(angleDouble) * strength);
bananaVelY = (sin(angleDouble) * strength);
if (Player_1_turn==true) {
bananaX = CurrentMonkey1CoX;
bananaY = CurrentMonkey1CoY;
} else {
bananaX = CurrentMonkey2CoX;
bananaY = CurrentMonkey2CoY;
}
if (Player_2_turn==true){
bananaVelX = -bananaVelX;
}
GotThrowTime1=true;
}

double wind=0,gravity=9.81;

bananaX += bananaVelX * timeSinceLastUpdate;
bananaY += bananaVelY * timeSinceLastUpdate;

bananaVelX += (wind) * timeSinceLastUpdate;
bananaVelY -= (gravity * timeSinceLastUpdate);

glBegin(GL_POLYGON);
glColor3d(1,1,0);
glVertex2f(bananaX,bananaY);
glVertex2f(bananaX,bananaY-5);
glVertex2f(bananaX-5,bananaY-5);
glVertex2f(bananaX-5,bananaY);
glEnd();

Share this post


Link to post
Share on other sites
I think I will give RAZORUNREAL £5 if he wants it as he gave me most the answer and I think he deserves it!

I just added the degress by haegarr which Metorical said would work I wondered if it was something todo with the angle input it's self but did not know!

Metorical I will give you £5 too as I would of worked this out from your post to get ys money just send me a private message with your paypal address!

Thanks for all your help!

Share this post


Link to post
Share on other sites
Haha!!!!

U! is! funny!

The reason I use explaintion marks is when it's important and I think every one should hear it like it's been shouted out, but generally it's when am desperate for an answer!

And NO you can't have a fiver you should give me a fiver for been rude!

But thanks for the advice i'll try not to use it as much when I am desperet for an answer.

Thanks

Ps. If you want ya money guys post on here to let me know u have send your pm to me!

Share this post


Link to post
Share on other sites

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