Jumping Problem

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
Xfcn
Citizen
Posts: 65
Joined: Sat Jul 12, 2008 6:53 am

Jumping Problem

Post by Xfcn »

Okay, so I'm trying to (very simply) make a little dude jump up and land. So far it's actually going okay. I got him to jump. But he jumps at OMG ridiculous speed versus the left and right which are far more reasonable. I know dt has to figure into this SOMEWHERE but it's escaping me where (I don't understand a lot of the math behind what I'm doing).

So here's what I have so far:

Code: Select all

-- Make a dude jump up and land. Also allow the movement left and right.

function load()
   dude = love.graphics.newImage("dude.png")
   x = 300
   y = 400
   speed = 100
   jump = 0
end

function update(dt)
	if love.keyboard.isDown(love.key_right) then
		x = x + (speed * dt)
	elseif love.keyboard.isDown(love.key_left) then
		x = x - (speed * dt)
	end
	
	if love.keyboard.isDown(love.key_up) then
		if jump == 0 then
			jump = 1
			accel = 10
			velocity = 100
		end
	end
	
	if jump == 1 then
		velocity = (velocity - accel)
		y = y - velocity
		if y >= 400 then
			jump = 0
			velocity = 0
			accel = 0
		end
	end
	
end

function draw()
	love.graphics.draw(dude,x,y)
end
Any ideas?
"Any sufficiently advanced technology is indistinguishable from magic." - Arthur C. Clarke
User avatar
cag
Citizen
Posts: 65
Joined: Sun Jun 29, 2008 5:09 am

Re: Jumping Problem

Post by cag »

(OK, so LOVE currently uses the awesome Box2D, so if you're going into more depth with the physics, I highly suggest learning to use that API. Then again, that's for some more hardcore stuff, so this is fine for simple stuff.)

Anyways, you're using the euler method of integrating over dt, which is to say that every 'time step,' you simply add acceleration to velocity, and you use the equation d=vt to find the displacement from the last timestep.

Of course, the simple answer is to change:

Code: Select all

y = y - velocity
to

Code: Select all

y = y - velocity * dt
which should give the desired result.

Anyways, a small suggestion:

Code: Select all

      if y >= 400 then
         jump = 0
         velocity = 0
         accel = 0
         y = 400 -- because if this is excluded, potential errors in the euler method might cause the thing to land at somewhere below 400
      end
User avatar
Xfcn
Citizen
Posts: 65
Joined: Sat Jul 12, 2008 6:53 am

Re: Jumping Problem

Post by Xfcn »

Awesome, thanks. What I wound up with:

Code: Select all

-- Make a dude jump up and land. Also allow the movement left and right.

function load()
   dude = love.graphics.newImage("dude.png")
   x = 300
   y = 400
   speed = 100
   jump = 0
end

function update(dt)
	if love.keyboard.isDown(love.key_right) then
		x = x + (speed * dt)
	elseif love.keyboard.isDown(love.key_left) then
		x = x - (speed * dt)
	end
	
	if love.keyboard.isDown(love.key_up) then
		if jump == 0 then
			jump = 1
			accel = 1 -- Changed to slow his jump speed.
			velocity = 400 -- Changed to the maximum height of the screen from his jump. He never gets this high.
		end
		if jump == 1 then -- DOUBLE JUMP! WOO!
			if velocity <= 10 then
				jump = 2
				velocity = 400
			end
		end	
	end
	
	if jump ~= 0 then
		velocity = (velocity - accel)
		y = y - velocity * dt
		if y > 400 then -- Changed to ONLY greater than 400.
			jump = 0
			velocity = 0
			accel = 0
			y = 400
		end
	end
	
end

function draw()
	love.graphics.draw(dude,x,y)
end
Yup! That wound up with a double-jump! Woo! :D (Included dude.png if anyone wants to dork with this themselves.)
Attachments
dude.png
dude.png (998 Bytes) Viewed 13107 times
"Any sufficiently advanced technology is indistinguishable from magic." - Arthur C. Clarke
User avatar
Xfcn
Citizen
Posts: 65
Joined: Sat Jul 12, 2008 6:53 am

Re: Jumping Problem

Post by Xfcn »

Just an update, as I've gotten this to do both Double Jump (if you continue holding the jump key down, he double-jumps, something I'm not entirely certain I like) and a little bit of hang-time (which helps you to find the height of the jump for maximum double-jump).

Here ya go:

Code: Select all

-- Make a dude jump up and land. Also allow the movement left and right.

function load()
   local f = love.graphics.newFont(love.default_font, 14)
   dude = love.graphics.newImage("dude.png")
   x = 300
   y = 400
   speed = 100
   jump = 0
   velocity = 0
   accel = 0
   love.graphics.setPointSize(2)
   love.graphics.setColor(255,0,0)
   love.graphics.setFont(f)
end

function update(dt)
	if love.keyboard.isDown(love.key_right) then
		x = x + (speed * dt)
	elseif love.keyboard.isDown(love.key_left) then
		x = x - (speed * dt)
	end
	
	if love.keyboard.isDown(love.key_up) then
		if jump == 0 then
			jump = 1
			accel = 1 -- Changed to slow his jump speed.
			velocity = 400 -- Changed to the maximum height of the screen from his jump. He never gets this high.
		elseif jump == 1 then -- DOUBLE JUMP! WOO!
			if velocity <= 200 then
				jump = 2
				velocity = 400
			end
		end
	end
	
	if jump ~= 0 then
		velocity = (velocity - accel)
		if velocity > 50 then
			y = y - velocity * dt
		elseif velocity <= 0 then
		    y = y - velocity * dt
		end
		if y >= 400 then -- Changed to ONLY greater than 400.
			jump = 0
			velocity = 0
			accel = 0
			y = 400
		end
	end
end

function draw()
	love.graphics.draw(dude,x,y)
	love.graphics.point(x,y)
	
	love.graphics.draw("Dude is at (" .. x .. "," .. y .. ")",50,50)
end
Now my thing is: does this work the same on all computers or is the speed completely tied to my machine?
"Any sufficiently advanced technology is indistinguishable from magic." - Arthur C. Clarke
User avatar
Kaze
Party member
Posts: 189
Joined: Sat Jul 19, 2008 4:39 pm
Location: Dublin, Ireland

Re: Jumping Problem

Post by Kaze »

I tried it. He jumps way too high.
User avatar
Xfcn
Citizen
Posts: 65
Joined: Sat Jul 12, 2008 6:53 am

Re: Jumping Problem

Post by Xfcn »

Kaze wrote:I tried it. He jumps way too high.
Does he jump off the screen? Because right now he's meant to jump a goodly portion of the screen. But not off.
"Any sufficiently advanced technology is indistinguishable from magic." - Arthur C. Clarke
User avatar
Kaze
Party member
Posts: 189
Joined: Sat Jul 19, 2008 4:39 pm
Location: Dublin, Ireland

Re: Jumping Problem

Post by Kaze »

Way off.
User avatar
Xfcn
Citizen
Posts: 65
Joined: Sat Jul 12, 2008 6:53 am

Re: Jumping Problem

Post by Xfcn »

Kaze wrote:Way off.
Hmm. How's his left to right? Is he Road Runner or is he fairly sedate?
"Any sufficiently advanced technology is indistinguishable from magic." - Arthur C. Clarke
User avatar
cag
Citizen
Posts: 65
Joined: Sun Jun 29, 2008 5:09 am

Re: Jumping Problem

Post by cag »

I forgot to mention that to be more physically correct and consistent, you have to use

Code: Select all

      velocity = velocity - accel * dt
instead of

Code: Select all

      velocity = velocity - accel
so yeah, timing will be off unless you fix this line. Also, the following discussion will assume the above:

The timing should (now) be relatively the same across all machines because it's adjusted to the variable dt. The problem is either in changing the acceleration to 1, or in neglecting to change the initial velocity to compensate for the reduced acceleration. Currently, since the guy isn't accelerating down as fast, so his speed doesn't change as much every timestep. That means he'll stay going fast for awhile.

Code: Select all

         velocity = 400 -- Changed to the maximum height of the screen from his jump. He never gets this high.
So the above comment isn't true. You have to look at some kinematics equations to find maximum height of jump. So some bla bla math physics:

v^2 = v_0 ^2 + 2a(delta s) = 0 (find where speed is 0, which is where maximum height occurs)
==> delta s = -v_0^2 / (2a)

And substituting in current values of v_0 = 400 and a = -1 (negative because accelerating in opposite direction) gives:

delta s = 80000 pixels

...which is pretty far off. Anyways, to find a v_0 you would want to use, solve for v_0:

v_0 = sqrt( 2a(delta s) )

so let's assume we want a gravitational acceleration of 200 px / sec^2 (it actually isn't that large), and the stick guy to rise 100 px:

v_0 = sqrt( 2 * 200 * (100) ) = 200

so setting v_0 = 200, a = 200 should make the stick guy rise 100 px. Of course, _still_, since you're using the euler method of integration, there's going to be a small % error (like... miniscule, but deadly if it's for some crazy hardcore engineering application) euler method is an approximation of a physical system. The % error depends on how small your dt is, for the most part, so this should work fine.

Anyways, resulting code from my wall-of-text:

Code: Select all

-- Make a dude jump up and land. Also allow the movement left and right.

local G_ACCEL = 200
local V_NAUGHT = 200
local V_DOUBLE_JUMP_CHECK = 100

function load()
   local f = love.graphics.newFont(love.default_font, 14)
   dude = love.graphics.newImage("dude.png")
   x = 300
   y = 400
   speed = 100
   jump = 0
   velocity = 0
   accel = 0
   love.graphics.setPointSize(2)
   love.graphics.setColor(255,0,0)
   love.graphics.setFont(f)
end

function update(dt)
   if love.keyboard.isDown(love.key_right) then
      x = x + (speed * dt)
   elseif love.keyboard.isDown(love.key_left) then
      x = x - (speed * dt)
   end
   
   if love.keyboard.isDown(love.key_up) then
      if jump == 0 then
         jump = 1
         accel = G_ACCEL -- Changed to slow his jump speed.
         velocity = V_NAUGHT -- Changed to the maximum height of the screen from his jump. He never gets this high.
      elseif jump == 1 then -- DOUBLE JUMP! WOO!
         if velocity <= V_DOUBLE_JUMP_CHECK then
            jump = 2
            velocity = V_NAUGHT
         end
      end
   end
   
   if jump ~= 0 then
      velocity = velocity - accel * dt
      y = y - velocity * dt
      if y >= 400 then -- Changed to ONLY greater than 400.
         jump = 0
         velocity = 0
         accel = 0
         y = 400
      end
   end
end

function draw()
   love.graphics.draw(dude,x,y)
   love.graphics.point(x,y)
   
   love.graphics.draw("Dude is at (" .. x .. "," .. y .. ")",50,50)
end
User avatar
Xfcn
Citizen
Posts: 65
Joined: Sat Jul 12, 2008 6:53 am

Re: Jumping Problem

Post by Xfcn »

It certainly works. I understood none of what you said, but it works. :D
"Any sufficiently advanced technology is indistinguishable from magic." - Arthur C. Clarke
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 14 guests