0
\$\begingroup\$

My players position is stored in a world matrix and I want to make him jump. Can I do this just by creating a translation from the matrix? I want the player to be able to jump while moving in a direction also. I've looked on google but didn't find any tutorials on jumping with a matrix

\$\endgroup\$
  • \$\begingroup\$ By matrix do you mean vector? (Vector being a matrix where one of the dimensions in 1, so 3x1 maxtrix is a 3D vector/Vector3). Also do you want to use a physics engine? Or just a simple add/subtract position? Either way this question has been answered a million times. Try to just Googling XNA Character Jump. First two results are flatformer.blogspot.com/2010/02/… and gamedev.stackexchange.com/questions/8492/… which are both useful. \$\endgroup\$ – mobo Jun 30 '13 at 21:43
  • \$\begingroup\$ I guess it could be a Vector3. I'll need to use a physics engine eventually but for now adding or subtracting position will work. Would the easiest way be to just create a translation from a Vector3 (0, -1, 0) while falling or (0, 1, 0) while jumping? \$\endgroup\$ – Christian Frantz Jun 30 '13 at 21:51
2
\$\begingroup\$

Simply adding or removing a vector to the translation will be insufficient on its own. You don't want to press jump and then instantly be 10 pixels higher.

You need to apply some very basic form of physics. At the simplest, you can use velocity and nothing else. When the player jumps, add a decent upward velocity, say (0,10,0). This velocity is in units/second. That is, each frame, take the elapsed time dt and multiply it with the velocity to get a change in position, e.g.

velocity = (0,10,0)
dt = 1/60 // whatever your frame time is if you're not using a fixed timestep
position = dt * velocity

You can then set the velocity back to a negative amount after detecting that some fixed amount of time has passed or that a certain height has been achieved in the jump. Set it back to zero once the player contacts the ground.

Having only velocity will give you linear movement. It will look "wrong" and feel bad to players. To make it "right," you need to include some form of acceleration, which will make the player's movement have more "curve" to it (this is all in terms of continuity, curvature, and other topics you would have learned in Calculus I). Velocity is the first derivative with respect to time of position. Acceleration is the first derivative with respect to time of velocity, and hence the second derivative of position with respect to time.

The simplest form of acceleration to use is to just add gravity. Each frame, before applying velocity to position, first apply acceleration using much the same formula. Let's say that the best gravity for your game is (0,-10,0)

gravity = (0,-10,0)
velocity += dt * gravity;
position += dt * velocity;

Note that this is a very simplistic form of Euler numeric integration. You may want to use a better (and more complex) form of integration in your game, though the simple methods works perfectly fine for many.

Now you jump and get that initial high upward velocity. The player shoots upward but slows down automatically, eventually falling back downward. Zero out the vertical velocity while in contact with the floor.

Another benefit of gravity is that it makes falling automatic and smooth. If a player walks off a ledge he'll accelerate downward until landing. You can use the magnitude of the velocity when landing to determine damage from falling, too, if that's part of your game.

This jumping will still not feel super smooth. Getting really good jumping requires acceleration when going upward and lots of other small tweaks to "feel right." It's somewhat common to want to apply a constant upward velocity for a small amount of time (unaffected by gravity) before letting gravity kick in to feel better. Getting a "perfect jump feel" can be somewhat difficult and depends on your specific game.

You can do further from just acceleration and model force or even impulses as well. These are typically less useful for standard platformers, though.

Note that horizontal movement can benefit from velocity and acceleration as well. It can feel a bit nicer and more "Mario-like" if the player accelerates to and from rest when moving horizontally, giving a very slight slide effect when stopping and a very small "start" effect when starting to move. In these cases, you'll want to model horizontal movement with a velocity (which is capped at your maximum horizontal speed), an acceleration from input (+/-X for right/left respectively), and a damping effect to remove horizontal movement over time. For example,

damping = 0.1
velocity.x -= velocity.x * damping * dt
velocity += acceleration * dt
clamp(velocity.x, -max_speed, +max_speed)

That formula removes 1/10th of the horizontal velocity every second. You can play with the numbers to find the right values for your game.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

The world matrix is just a convenient way to store position and orientation. Within the matrix will be your x,y,z translation values (distance from the origin).

You really have two options when it comes to jumping:

1) Use or create a physics system in which you have velocity and acceleration values. Your position (stored in the world matrix) is modified by those values for each physics update. To initiate a jump, provide an initial velocity in the Y direction, which will eventually be overcome by acceleration due to gravity in the -Y direction. A simple psuedo-code would look something like this:

On Update: velocity += (acceleration * timeStep); position += (velocity * timeStep);

In each of these cases you can use a translation matrix to store your positions (or you can just use a Vector3).

But this means you have to know when to stop jumping (as in, the player has collided with the floor). Assuming there are no other objects in the game, a simple solution is to limit prevent the y-value from going below zero. As in:

if (position.y < 0) position.y = 0;

Anything beyond this simple example, you'll need to start thinking about using a more robust physics engine.

2) A second really simple solution to the jump problem is to just create a second matrix that is a "jump offset". During the "jump" have the offset move from 0 to jumpHeight and back to 0. You could even do this using a SIN value if you wanted something that looked more fluid. Your calculated position will always be:

realPosition.Y = groundPosition.Y + jumpOffset;

Or if you're instead using matrices, you'll write something like:

playerTransform = playerMatrix * jumpOffsetMatrix;

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.