Jump to content
  • Advertisement
Sign in to follow this  

[XNA/C#] Method for jumping

This topic is 2440 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi people,

I'm a noob in C# and XNA and just started with it. I'm having trouble with the following problem: I'm writing a method that let a object jump, bu I can't get it working. The parameters are an y position (a reference) and the jump spring hight. Down under my code so far:

static void jump(ref float charPosY, float jumpHeight)
{
//Temporary vars
float charStartPosY = charPosY;
float jumpStartHeight = jumpHeight;
bool goDown = false;

//Check if character is not going down, let the man jump!
while (!goDown)
{
for (float i = 0; i <= jumpStartHeight; i++)
{
charPosY -= jumpHeight;
jumpHeight--;
if (i >= jumpStartHeight)
{
//If the man finished jumping, set goDown true
goDown = true;
jumpHeight = 0;
}
}
}

//If our man jumped high enough, let him fall down again
if (goDown)
{
for (float i = 0; i <= jumpStartHeight; i++)
{
charPosY += jumpHeight;
jumpHeight++;
}
}
}



The first part - the jump part of this method - works fine if I comment the "goDown" part (the object jumps then) and also the "falling down"-part works if I comment the jump part. Together it won't work; it looks like the two parts are canceling each other. I think that is a strange thing, because the boolean "goDown" will be activated when the first part is done with the for loop...

I hope anybody have a glue or an answer for me!

Thanks a lot!!


(Sorry if my English isn't that good, I'm Dutch rolleyes.gif)

Share this post


Link to post
Share on other sites
Advertisement

Hi people,

I'm a noob in C# and XNA and just started with it. I'm having trouble with the following problem: I'm writing a method that let a object jump, bu I can't get it working. The parameters are an y position (a reference) and the jump spring hight. Down under my code so far:

static void jump(ref float charPosY, float jumpHeight)
{
//Temporary vars
float charStartPosY = charPosY;
float jumpStartHeight = jumpHeight;
bool goDown = false;

//Check if character is not going down, let the man jump!
while (!goDown)
{
for (float i = 0; i <= jumpStartHeight; i++)
{
charPosY -= jumpHeight;
jumpHeight--;
if (i >= jumpStartHeight)
{
//If the man finished jumping, set goDown true
goDown = true;
jumpHeight = 0;
}
}
}

//If our man jumped high enough, let him fall down again
if (goDown)
{
for (float i = 0; i <= jumpStartHeight; i++)
{
charPosY += jumpHeight;
jumpHeight++;
}
}
}



The first part - the jump part of this method - works fine if I comment the "goDown" part (the object jumps then) and also the "falling down"-part works if I comment the jump part. Together it won't work; it looks like the two parts are canceling each other. I think that is a strange thing, because the boolean "goDown" will be activated when the first part is done with the for loop...

I hope anybody have a glue or an answer for me!

Thanks a lot!!


(Sorry if my English isn't that good, I'm Dutch rolleyes.gif)

First of all, this code is WRONG
you cant add altitude in a for loop because this operation is made in a nanosecond
second I dont see you using any physics laws, this is useful for objects to jump or fall in the way in the real world happen.

here is a code for a misile launch that goes up and then down i hope you can use it, see in the update function is when you change the altitude and update is done 30 times per second

using System;
using Xengine;
using NavalBattleship.GameCode;
using NavalBattleship.Screens;
using NavalBattleship.Particles;
using Microsoft.Xna.Framework;

namespace NavalBattleship.Models
{
class Misile : ModelClass , IModel
{
#region Private atributes

float time;
float cTime;
Coordenada2D cFinal, cInicial;
char player;
static bool locked;
float angleX, angleY;
float distanceTarget;
float speed;
static float x, y, z;
static float cX, cY, cZ;
static float vX, vY, vZ;
double angleRotVert, angleRotHorz;
float AngleRotMisil;
PlayerShoot shoot;
static bool misilCamera;
static Manager manager;

#endregion

#region Properties

public static Manager GameManager
{
get { return Misile.manager; }
set { Misile.manager = value; }
}

static public bool Locked
{
set
{
locked = value;
}
get
{
return locked;
}
}

public static bool MisilCamera
{
get { return misilCamera; }
set { misilCamera = value; }
}

#endregion

public Misile(Coordenada2D inicial, Coordenada2D final, char pPlayer, PlayerShoot shoot)
{
this.shoot = shoot;
this.file = "misil";
this.cInicial = inicial;
this.cFinal = final;
this.player = pPlayer;
locked = true;
x = 0; y = 0; z = 0;
CalculateCoord();
Camara.MisileLocked = true;
if (misilCamera)
{
manager.Camara.SaveCamaraPos(1);
Camara.LockedMisileCamera = true;
}
else
{
manager.Escena.AddGenerator(new MisilSmokeGenerator(cInicial, cFinal, player, vX, vY, vZ));
manager.Escena.AddParticle(new MisileFire(new Vector3(cInicial.X, 0, cInicial.Y)));
}
}

public void CalculateCoord()
{
angleRotHorz = Helper.RadToDegree(Math.Atan2(cFinal.Y - cInicial.Y, cFinal.X + Game.BoardSeparation - cInicial.X));
float result1 = cFinal.Y + 0.5f - (cInicial.Y + 0.5f);
float result2 = Game.BoardSeparation + cFinal.X + 0.5f - (cInicial.X + 0.5f);
angleX = Helper.RadToDegree(Math.Atan2(result1, result2));
distanceTarget = (float)Math.Sqrt(Math.Pow(result1, 2) + Math.Pow(result2, 2));
if (distanceTarget < 7)
angleY = 75;
else
angleY = 65;

result1 = distanceTarget * Game.Gravity;
result2 = (float)Math.Sin(Helper.DegreeToRad(angleY * 2));
speed = (float)Math.Sqrt(result1 / result2);
vX = speed * (float)(Math.Cos(Helper.DegreeToRad(angleY)) * Math.Cos(Helper.DegreeToRad(angleX)));
vY = speed * (float)Math.Sin(Helper.DegreeToRad(angleY));
vZ = speed * (float)(Math.Cos(Helper.DegreeToRad(angleY)) * Math.Sin(Helper.DegreeToRad(angleX)));
}

public new void Create()
{
this.textureID = EngineContent.GetTextureByName("misil");
base.Create();
}

public void Update()
{
if (canDispose == false)
{
x = vX * time + cInicial.X + 0.5f;
y = vY * time - (0.5f * Game.Gravity * (float)Math.Pow(time, 2));// here i update the altitude (this is a phisics law y = Vot + 1/2(g*square(t)))
z = vZ * time + cInicial.Y + 0.5f;
float dist1 = x - cInicial.X + 0.5f;
float dist2 = cFinal.X + Game.BoardSeparation - cInicial.X + 0.5f;
angleRotVert = (150 * dist1 / dist2) + 5;
AngleRotMisil += 3.5f;
if (!misilCamera )
{
time += 0.02f;
}
if (misilCamera)
{
time += 0.01f;
cTime = time - 0.12f;
cX = vX * cTime + cInicial.X + 0.5f;
cY = vY * cTime - (0.5f * Game.Gravity * (float)Math.Pow(cTime, 2));
cZ = vZ * cTime + cInicial.Y + 0.5f;
Camara.Yaw = (float)angleRotHorz;
Camara.Pitch = (float)angleRotVert;
Camara.LocateCamara(new Vector3(cX, cY, cZ), new Vector3(x, y, z));
}
if (y < -0.3f)
{
if (misilCamera)
{
manager.Camara.RestoreCamaraPos(1);
}
Camara.LockedMisileCamera = false;
Camara.MisileLocked = false;
base.canDispose = true;
locked = false;
shoot.Invoke(cFinal.X, cFinal.Y, Player.Person);
}
}
}

public new void Draw()
{
if (canDispose == false )
{

Camara.PushMatrix();
Camara.View = Matrix.CreateTranslation(0,0.5f,0) *
Matrix.CreateRotationY(Helper.DegreeToRad(AngleRotMisil)) *
Matrix.CreateRotationZ(Helper.DegreeToRad(-angleRotVert)) *
Matrix.CreateRotationY(Helper.DegreeToRad(-angleRotHorz)) *
Matrix.CreateTranslation(x, y, z) *

Camara.View;
base.Draw();
Camara.PopMatrix();
}
}
}
}

Share this post


Link to post
Share on other sites

Hi people,

I'm a noob in C# and XNA and just started with it. I'm having trouble with the following problem: I'm writing a method that let a object jump, bu I can't get it working. The parameters are an y position (a reference) and the jump spring hight. Down under my code so far:
...




The first part - the jump part of this method - works fine if I comment the "goDown" part (the object jumps then) and also the "falling down"-part works if I comment the jump part. Together it won't work; it looks like the two parts are canceling each other. I think that is a strange thing, because the boolean "goDown" will be activated when the first part is done with the for loop...

I hope anybody have a glue or an answer for me!

Thanks a lot!!


(Sorry if my English isn't that good, I'm Dutch rolleyes.gif)





You're moving the character all the way up in the jump and all the way back down without drawing him anywhere along the way.


Share this post


Link to post
Share on other sites
Like I said, I'm a noob in C#/XNA Haha. The first reply is a little too much now, the second is better to understand mellow.gif. I thought that the character would be drawn automaticly. So if I understand you, I have to draw him when he is on the top of his jump... But how do I do that? As far as I know, you cant draw anyting in a method?!

Share this post


Link to post
Share on other sites
The character gets drawn when you call the Draw method. In a loop, your game should play out as you calling update then you calling draw then update then draw and continually repeating.

During the update is where you'll want to do things like handle key presses and adjust the character's location (physics).




Right now you're having jump be a method that runs the whole jump process from beginning to end at once. Instead, you'll want it to take one step of the jump process at a time.




Is this jump method being called when you press the jump button? (I can help a bit more if I know how you're handling jumps)


Share this post


Link to post
Share on other sites
Yes, if I press the right shift, my character has to jump: if (keyboardState.IsKeyDown(Keys.RightShift))

Now I understand that a update is drawn after a method call. So now I split the function in two seperated methods and call the second one if the first one had finished:

if (keyboardState.IsKeyDown(Keys.RightShift))
{

if (jumpUp(ref sjefkePosition.Y, ref jumpHeight))
jumpDown(ref sjefkePosition.Y, jumpHeight);
}


And down under:

static bool jumpUp(ref float charPosY, ref float jumpHeight)
{
//Temporary vars
float charStartPosY = charPosY;
float jumpStartHeight = jumpHeight;
bool goDown = false;

//Check if character is not going down, let the man jump!
while (!goDown)
{
for (float i = 0; i <= jumpStartHeight; i++)
{
charPosY -= jumpHeight;
jumpHeight--;
if (i >= jumpStartHeight)
{
//If the man finished jumping, set goDown true
goDown = true;
jumpHeight = jumpStartHeight;
}
}
}

return goDown;
}

static void jumpDown(ref float charPosY, float jumpHeight)
{
float jumpStartHeight = jumpHeight;

//If our man jumped high enough, let him fall down again
for (float i = 0; i <= jumpStartHeight; i++)
{
charPosY += jumpHeight;
jumpHeight++;
}
}


So I thought I got it now, but... This isn't working either :(. My character is now moving down (so it's leaving my screen)... I'm feeling so stupid haha

Share this post


Link to post
Share on other sites
Let me try to explain it a bit better :) .

Your character is on your screen at an x and y position. The x axis is the position on the horizontal axis and the y axis is the position of the vertical axis. In order to make a character jump you need to manipulate the y axis. On a computer the y axis decreases as you move up towards the top of the screen (at the top left of the screen is at 0,0 and the bottom right coordinate is width,height)

Right so gravity is a force that provides a constant acceleration of an object downward . In our coordinate system this can be represented as a constant positive acceleration on the Y axis (positive meaning the value on the Y axis will increase and the object will move down).

The jump will then need to be an instantaneous negative acceleration on the Y axis (to make the object move up).

In physics we learn that the first derivative of a position function is the velocity of an object. This makes sense because a derivative deals with a rate of change over time. That is to say that your velocity is your rate of change of position over time... If we integrate the velocity (basically the inverse of a derivative) then we can obtain the position... The second derivative is acceleration (or the rate of change of the velocity over time). So if we integrate the acceleration we can find the velocity. So if we integrate the acceleration twice then we will arrive at our position!

Numerical methods will then tell us that we can approximate an integral (finding the area under a curve basically) using "euler's method" which means that if we take very small rectangles of our area and sum them up, we will approximate our integral... This translates nicely to our update loop...

SOO

PlayerY = your starting value.
PlayerYVel = 0.0
Gravity=9.8 (or some value)
deltatime = 0.1

in your update loop:

PlayerYVel = PlayerYVel + Gravity*deltatime //or +=, whichever you understand better
PlayerY = PlayerY + PlayerYVel * deltatime

If PlayerY collides with obstacle then set PlayerYVel to 0.

and in your jump code:

PlayerYVel = -JumpStrength

In the update loop the first line integrates the acceleration and the second line integrates the velocity to obtain the player's y position. For the jump we want to treat the jump as an instantaneous change in velocity (you could treat it like a massive acceleration but it then has to counteract gravity and if it is not strong enough then the jump will be fairly unimpressive).

You could do:

PlayerYVel -= JumpStrength

if you do not want to outright change the y velocity... however if we are jumping from a platform and the velocity has been zeroed, they both should have the same effect. However if we are in air and the velocity is positive, then this will result in a weaker secondary "double jump". It is all based on what you want to do!

Share this post


Link to post
Share on other sites
No need to feel stupid, we've all been there. You're fighting to overcome it so you're headed in the right direction. :)


Take a moment to mentally walk through your code. If you do that, it may help you see that you're going into the while (!goDown) loop and then into the for loop inside it and then the code run through all of those loops and returns true (goDown = True). And then in the keybinding code, jumpDown is called and the character falls down. And after all of that, the program is able to move on and run your Draw code.


I would like to point out that I started this approach before shadow began his explanation. His method of using physics (gravity/acceleration) is a better method to build a jumping system. I put this one together simple to help you easily see all of action/parts and how the separation of your updates and draws needs to work.

Give this approach a try..

Create a variable bool isJumping = False; where you have created the other variables you're using such as jumpHeight and sjefkePosition.

When the jump key is pressed set the character to be jumping:

if (keyboardState.IsKeyDown(Keys.RightShift))

{

//If not already jumping, set character to jumping.

if (!isJumping)


{



isJumping = True;

}



}





Inside your update code handle the character jumping:

if(isJumping)

{

jump(ref sjefkePosition.Y, jumpHeight);

}



This is where the real action is happening.

static void jump(ref float charPosY, float jumpHeight)

{

static int jumpStep = 0; //controls moving character through each step of jump process

int totalSteps = 6; //this is a "magic number" that I've chosen for the example. nothing special about it




//This example has the character moving up for the first half of the sequence (3 steps with this math) and then

//moving down the other half.

if (jumpStep < (totalSteps / 2))

{

//An example of the math, if you passed jumpHeight as 30, the math would be


//charPosY = charPosY - (30 / (6 / 2)); which becomes

//charPosY = charPosY - 10; so the character moves by 10. It will do this for (6/2) frames

//so 3 frames and will end up with the total being the full 30 that you passed as jumpHeight


charPosY = charPosY - (jumpHeight / (totalSteps / 2));

jumpStep++;



}

//This means we've gone over half the steps, so we want the character to fall back down.

else

{

//This is the same principle as the up code, it just moves down instead.

charPosY = charPosY + (jumpHeight / (totalSteps / 2));


jumpStep++;

//This resets our jump counter for the next jump once we've completed all of the steps.

if (jumpStep == totalSteps)

{


jumpStep = 0;

isJumping = False;

}

}

}

Share this post


Link to post
Share on other sites
It looks like my C#-fu was not on point. I tried plugging the code I gave you in a quick program and C# didn't stand for the line

static int jumpStep = 0; //controls moving character through each step of jump process

having static in it. Without the static keyword there, it would cause the character to be in the first step of jumping each time the method is called (so he'd only move up).




Moving that line of code outside the method so it's only called once (instead of once per method call) is a solution that works.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!