Skip to main content
gamedev.net
🔒 Locked

Making camera jump??

Started by Anddos 22 replies 3.3k views
Original Post
Anddos
Anddos
Ive got a working Camera and the Y cordinate is set to sit on the terrain , but how do you make the camera Y go up and then down with a key press?, i cant figure it out and only made it go up slowly etc..and not back down.., can post camera code if requested..
:)
Maddius
Maddius
You have some options, for example to do a simple sin wave up and down motion you could increment your Y position by this function:

mAirTime += TIME_STEPmPosition.y += 4.25f * sin(PI / 4) - (gGravity * mAirTime);


Where mAirTime is a value that you increment while the player is jumping, then when the player hits the ground again set some states to say they are on the group and that you dont need to worry about jumping.

When the player hits the space bar you can set your relevant states to indicate that the player is not jumping and that you should increment the Y position again.

The above function will give a nice sin up and down motion, however this may not be desireable, for instance maybe you want to get to the peak of the sin wave then set the states so that the player falls as if the player walked off a ledge and is now falling which would cater for most all situations.

Also gGravity is just a value to simulate gravity in your game i.e. 9.81.

Hope that helps.
Anddos
Anddos
so what type would be gGravity?
:)
programci_84
programci_84
float, of course.

Also, the TIME_STEP value is the most important thing here.
There's no "hard", and "the impossible" takes just a little time.
Anddos
Anddos
so what would happen if i set it to cos instead , i am trying to get my head around sin and cos for a while now
:)
TomKQT
TomKQT
You can do it also without sin/cos, and in fact it will be more realistic (although you will hardly see the difference).

You can simulate a jump using the basic physics, just start with the object (player) having a defined vertical (upward pointing) velocity, which you then modify by acceleration (= gravity) every frame until the object reaches ground again. The curve you'll get by this is not sin but a parabola, which is what really happens in real life if you neglect air resistance.

You can compute it in vectors, which will kinda "automatically" solve the whole movement for you, you'll be surprised how well it works ;)

Easily said (let's talk just about the vertical movement now, so no vectors), you have the player's height, vertical velocity and gravity.

The start values are:
height = 0.0f //(on terrain)velocity = 0.0f gravity = -9.0f // Or anything what fits you, you don't have to maintain real world values of course (g = 9.81). It's negative because it's pointing downwards.


Now when the player gives command to jump, you immediately set the velocity to some choosen value (you'll find it by testing - this value together with gravity will define the curve of the jump), for example:
velocity = 10.0f 


And from this moment, you start doing the following calculation every frame (float dt is the time between this and the previous frame, in seconds):
velocity += gravity * dt;  // physics: dv = a * dt (change of velocity is given by acceleration times the time change) height += velocity * dt;  // physics: ds = v * dt (change of trajectory is given by velocity times the time change) 


The velocity starts with 10.0f and is "automatically" decreased because of the negative acceleration (gravity) so it reaches zero after some time (the peek of the jump, zero velocity) and then starts going into negative values (the falling phase of the jump).

You end the jump when the height is zero or below zero and the players was already falling:
if (height <= 0 && velocity < 0) {   height = 0;   velocity = 0;   // jump done}


(With the values chosen in this example the whole jump will take around 2.1 seconds and the peek height will be 5.0 units.)

As I said, you can make position (instead of "height"), velocity and gravity as vectors and it will work in 3D, also with forward jumps.
programci_84
programci_84
Quote:
so what would happen if i set it to cos instead , i am trying to get my head around sin and cos for a while now


Here's a sine wave:
sinevawe.png

If you look at the wave, you can see that it starts with 0 (zero) val at the beginning. And the first half-period (between 0 and T/2) has a shape like a jump. That's why we use sin() for simulating jumps. If you choose cos() instead of sin(), it wont't be true; because cos() is 90-degrees behind of sin(). That means, cos() starts with 1 (one) value at t=0 (beginning).
There's no "hard", and "the impossible" takes just a little time.
marius1930
marius1930
Quote:
Original post by programci_84
Quote:
so what would happen if i set it to cos instead , i am trying to get my head around sin and cos for a while now


Here's a sine wave:
sinevawe.png


Just to be helpful, the next time you can use Wolfram|Alpha instead of drawing your own in paint, it fixes all your math needs ;)

Evil Steve
Evil Steve
Moving to Game Programming, since this isn't DirectX specific.
TomKQT
TomKQT
Quote:
Original post by Anddos
so what would happen if i set it to cos instead , i am trying to get my head around sin and cos for a while now


If you still cannot figure out how sin works in Maddius's post, don't worry it's not your fault ;) It's just wrong.

Quote:
Original post by Maddius
You have some options, for example to do a simple sin wave up and down motion you could increment your Y position by this function:

mAirTime += TIME_STEPmPosition.y += 4.25f * sin(PI / 4) - (gGravity * mAirTime);



4.25f * sin(PI / 4) is a constant, it can be replaced with 3.005204f with the same meaning and suddenly the sin function is gone so there's no way how to achieve a sin wave.
So we get this:
mPosition.y += 3.005204f - gGravity * mAirTime;

which in fact works for this purpose, it just doesn't produce a sin wave but a parabola I was taking about in my long post. This time, however, with very well hidden meanings of the two constants (3.005204 and gGravity).

If you really wanted a sin wave for your jump (I recommend the parabola, it's much more natural), you could use something like this:
mPosition.y = JUMPAMP * sin(mAirTime * PI / JUMPTIME);

where JUMPAMP determines the max. height (amplitude) of the jump and JUMPTIME the length of the jump in seconds.
Maddius
Maddius
Yeah my fault for confusing matters, but atleast we get there in the end. Hope you get it sorted dude!
Anddos
Anddos
mPosW.y = terrain->getHeight(mPosW.x, mPosW.z) + offsetHeight + mPosition.y = JUMPAMP * sin(mAirTime * PI / JUMPTIME);


what is JUMPAMP , mAirTime and JUMPTIME all undeclared..

:)
mrchrismnh
mrchrismnh
A good way to start understanding sin/cos is to look at the unit circle.
"It's like naming him Asskicker Monstertrucktits O'Ninja" -Khaiy

TomKQT
TomKQT
Quote:
Original post by Anddos
mPosW.y = terrain->getHeight(mPosW.x, mPosW.z) + offsetHeight + mPosition.y = JUMPAMP * sin(mAirTime * PI / JUMPTIME);


what is JUMPAMP , mAirTime and JUMPTIME all undeclared..


I don't want to sound harsh or something, please take this just as an advise - it seems you don't have much experiences with programming, with general algorithms. I think it will be hard for you to solve more complicated tasks in Direct3D which usually require a lot of thinking, not just the knowledge of Direct3D functions etc.
It seem you are a beginner and beginning directly with Direct3D is not the right way to go, IMHO.

Anyway, to your question:
That was just a dummy code or a C++ pseudo code, JUMPAMP and JUMPTIME were just placeholders for a constant/macro defined by you and I explained their meaning (JUMPAMP determines the max. height (amplitude) of the jump and JUMPTIME the length of the jump in seconds). They can be constant and they can also be variables if you want to make different kinds of jumps under different circumstances.
Example:
#define JUMPAMP 0.2f
#define JUMPTIME 1.0f
will mean that jumps will be 0.2 units high and 1.0 seconds long.

mAirTime is a variable I took from some of the previous posts to keep it consistent and it means the current time in the jump. This is a variable, at the beggining of a jump you set it to zero and than you have to ensure its periodical updating by a real time.


Please try to solve it yourself from here. Not that we are not willing to help you, I personaly love to help people here, but in this case I think it will be more helpful for you to figure it out yourself because if we just give you the whole working code for something this easy, you'll never get familiar with basic algorithms.
Keep trying and you'll make it working finaly. If not, feel free to ask, but give it some effort before that.



Oh and btw, the code in the quotation is syntactically wrong, you cannot use two equals signs this way in one expression.
Anddos
Anddos
yes but if someone replys and pasts half of the source code , how do you expect me to know what those values was?, anyway thanks

this is my code now

if( gDInput->keyDown(DIK_SPACE) )
jump = true;


if(jump)
{
mPosW.y = terrain->getHeight(mPosW.x, mPosW.z) + offsetHeight + JUMPAMP * sin(dt * D3DX_PI / JUMPTIME);

}
else
{
mPosW.y = terrain->getHeight(mPosW.x, mPosW.z) + offsetHeight;
}

but nothing seems to happen
:)
TomKQT
TomKQT
Quote:
Original post by Anddos
yes but if someone replys and pasts half of the source code , how do you expect me to know what those values was?, anyway thanks


It was not pasted half of a code, it was just a pseudo code to show you the general direction which to go. We didn't copy-paste the codes from our applications, we made them up for you.
And everyone here explained in words what does every variable in the pseudo codes mean, their declaration is of course up to you ;)

Quote:

if( gDInput->keyDown(DIK_SPACE) )
jump = true;

if(jump)
{
mPosW.y = terrain->getHeight(mPosW.x, mPosW.z) + offsetHeight + JUMPAMP * sin(dt * D3DX_PI / JUMPTIME);

}
else
{
mPosW.y = terrain->getHeight(mPosW.x, mPosW.z) + offsetHeight;
}

It's not that simple.
You are not dealing with the beginning of the jump (you must detect when the space button goes from up state to down state, not just whether it is still down or not).
You are not dealing with the end of the jump. You never set jump to false.
"dt" is the time between frames? If yes, it will be almost constant, it will still have similar values depending only on the current FPS - and this means that sin(dt * D3DX_PI / JUMPTIME) will also return always similar values and you won't get sin wave from it. The argument of sin() must be increasing over time. Something like:

actualTimeInTheJump += dt;
.... sin(actualTimeInTheJump * D3DX_PI / JUMPTIME) .....

(Where you have to put actualTimeInTheJump = 0 at the beginning of the jump, which is only when you detect that the space key changed from up state to down state.)



I would really recomment the version with parabola, described in my long post in this thread. It is really easy to get working, belive me ;)
There are again just pieces of code, but together with the verbal description around the code snippets you could try to make a whole code from it.
If you won't be able to get it working, post what you have and I'll help you.

Oh and small advise - it's not recommended (also by Microsoft itself) to use DirectInput to handle mouse and keyboard inputs. It's better to use just the window messages (WM_KEYDOWN, WM_KEYUP etc.)
Anddos
Anddos
its working but when it falls back down it goes right through the terrain and back up again and dosent stop is this because i dont use wm_keydown etc?

video



dunno whats happening to the quality of it

if(jump)		{			timeadded += dt;			mPosW.y = terrain->getHeight(mPosW.x, mPosW.z) + offsetHeight + JUMPAMP * sin(timeadded * D3DX_PI / JUMPTIME);			//MessageBox(NULL,"jump","",0);		}		else		{		mPosW.y = terrain->getHeight(mPosW.x, mPosW.z) + offsetHeight;		jump = false;		timeadded = 0;		}


[Edited by - Anddos on June 21, 2010 12:17:32 PM]
:)
empirical2
empirical2
Quote:
Original post by Anddos
its working but when it falls back down it goes right through the terrain and back up again and dosent stop is this because i dont use wm_keydown etc?


No its because you dont stop.

Look at your code and follow what it is saying in your head

if(jump){//This is code that is executed ONLY if jump is true}else{//this is code that is executed ONLY if jump is falsejump = false;//^^You have the above line that makes no sense. jump will only be set to false if jump is already false}


If you think about the problem logically you will be able to understand what you need to code.

1. When do I want the jump to stop?
2. How can I test for that condition? (The condition being the moment to stop)
3. When that condition is met how do i stop the jump?



Anddos
Anddos
ok so i have removed the jump = false but it will jump up then like reset it self back on the terrain without moving back down etc...
:)
szecs
szecs
Seriously, if you can't solve your problems (These kinds of things are quite trivial), then you will never become a game developer/programmer.
If you can't solve these things at all, even with a lots of help, pseudocode, real code, etc. (I bet that's the reason of your low rating), frankly: you are not up to it, programming is not for you.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.