Sign in to follow this  
lodoss118

Simple character JUmp

Recommended Posts

hi i got my character to jump in my 3d game when u press the key J, but it doesn't increment it by it self so u have to hold J key to get the effect, My character starts at Y = 19, so i want to jump higher than that and come back to initial position which is y = 19. Basically the below code works but u have to hold on the J button to get the effect, i just want to goto y = 50 then back to y= 19 just by pressing the j button once, thanks for your help :). void Object3D::Jump() { static int dir=1; if(y<=50&&dir==1){ y++; } else { dir=0; y--; } if (y==0&&dir==0){ dir=1; y++; } else if(y<=19&&dir==0){ dir=1; } }

Share this post


Link to post
Share on other sites
Add gravity to your code. Basically accelerate your character downwards every frame. So somewhere in your main have something like, from an older post of mine:

Quote:
Original post by Daerax
... Ill point out that a relatively simple physics based handling is the easiest and tidiest way to handle this.

Velocity is the rate of change of displacement. v = xf - xi/tf - ti. It basically says how much you have changed position in a certain amount of time. This is unlike speed, which is how much distance you covered in a certain amount of time, s = d/t.

Acceleration tells you how quickly and in what direction your velocity is changing, a = Δv/Δt (where Δv = vf - vi). Acceleration and velocity, unlike mass and speed are vectorial quantities and so aught to be represented as such. I will recycle the definition of a vector I used in an old post:

-------------

A vector is simply a quantity which can be described with a magnitude and a direction. For example, the players speed is not a vector because it is not possesed of a direction (you could only represent it with a float or int etc.). The players velocity is, however, a vector, since it will have a direction (you can go v.x and v.y etc.). The players position is a vector because it is defined in terms of x and y and thus has a direction. The magnitude of this vector would be the distance of the player from the origin. So for velocity the vector points in the direction of motion and gives the amoiunt of this change. For position the vector points to some location a certain distance away from the origin. A vector is not a point, a vector can point at a point however.

So if the player is at Point (10,10) then it can be said that a vector exists which points from the origin at him or her.


_____________
|\
| \
| _\/
| (10,10)
|


Vectors can also be posessed of different (local) coordinate systems. For example the velocity vector (in one timestep) can be thought of to have an origin in the Players position and point to a point speed (per time step) distance away. This is a loose explanation but gets the point across, I hope.

__________
|\ _ (13,7)
| \ /\ <-------Velocity Vector, Say it is (3 ,-3) Points at players new position, so northeast key..
| _\/
| (10,10)
|

We know that on earth most people experience a gravitational acceleration of about 9.8m/sec^2. This quantity is commonly called g. So whenever you jump you experience an acceleration of g = 9.8. The reason you simply dont fall straight through the ground is because the ground pushes back up at you with the same amount of force that you are placing on it. In the Newtonian Limit, Force is proportional to mass and acceleration, F = ma, using this fact we can obtain a method for acceleration. It takes a force to change an objects state of motion or velocity, so we adjust our position based on the amount of impulse, or instance of force experienced. I'll provide a basic frame work from which you can work from.


while(...){
if(The_Tick + 17 < GetTickCount())
{

if(event_space_key_down)
{
jump_force+=10;

if(jump_force > FORCE_MAX) //limit the amount of max force
jump_focre = FORCE_MAX;
}
else if(event_space_key_up)
{
v.y = jump_force / mass_guy; //an instanse of force
jump_force = false;
jumping = TRUE; //we are jumping
}
if(event_right_key_right)
{
v.x = 10*cos(turned_angle);
v.z = 10*sin(turned_angle);

}

if(jumping) //every frame we adjust our position if we are jumping
{
v.y += g; //g = -9.8
p.y+=v.y;
p.x+=v.x;
p.z+=v.z;

if(SomethingAbove() || SomethingBelow())
{
v.x = 0;
v.z = 0
p.y -= v.y;
jumping = false;
}
}
The_Tick = GetTickCount();
}
}




Some improvements to the code might be a method which draws a ray from the player to the destination to check if it intersects with any solid objects in a jump, if so then stop jump at PoI, or perhaps even a time based approach?

I hope that was of aid.

Note thast this is just to give you a general idea and not the best way to implement such. Also have you considered a physics engine?

EDIT: That post was for originlly 2D, edited for 3D. Note in 3D to move forward (assuming frame based thus ignoring Δt) , you do something similar to : p.z += mov_vec*sin(turned_angle); p.x += move_vec * cos(turned_angle); //where mov_vec is the magnitude [root of the sum of square of sides) of the velocity vector and turned_angle is like pitch or y rotation angle or something.

[Edited by - Daerax on March 26, 2005 11:43:38 PM]

Share this post


Link to post
Share on other sites
I haven't gotten this far in my programming yet, but I am assuming that when you press the J key that Object3D::Jump() is called. This seems to directly change the y value but you haven't shown us any code to loop it. So I have 2 thoughts.

1) call this every frame/tick

2) have this function call another function to create another thread that simply loops for 1 to 100 and moves y up 1 for the first 50 and down 1 for the second 50.

My thought is that like you said this only happens once, but if you hold the button it preforms correctly. So, you need a way to automatically preform this through the jumping process.

Another thought is that you might already have a function to check the objects position every tick, so why not have a boolean that says object is jumping. Then every tick you set the position accordingly.

Share this post


Link to post
Share on other sites
For a nice jump what you need is player velocity. Every frame your take the player position and add the velocity times the time thats passed like so:

pos += vel * timePassedSinceLastFrame;

For gravity every frame you do something like this:

vel.y -= 0.8;

Then to create a jump all you need todo is set your up velocity quite high in your j key press event:

vel.y += 5;

I'm making these numbers up, just experiement to find values that work nicely for what your after. Both position and velocity are vectors, and time passed is usually measured in miliseconds, but again whatever works for you. This also works for walking - when you press the forward key you set the forward velocity, and when you press the strafe key you set the strafe velocity etc and it will all work out. Also if you do it this way and then run your game on a different computer it will still run at the same speed. With key-repeats it'll run differently on different machines. If your really up for it have a look at this tutorial.

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