Page 1 of 1

*dt not working, love.keypressed(k) questions (SOLVED)

Posted: Fri Apr 26, 2013 3:22 pm
by Rafer45
Hey! Thanks for coming to help out.
So:
I'm using *dt to make sure my player moves at the same speed in every computer, but it doesn't seem to be working. I opened the same file in my computer and my school's computer, but my character moved far too quickly in the latter
Also, I don't know how to use love.keypressed without defining everything within it in one big chunk of unrelated code (e.g defining bounce toggle in love.keypressed, but having to define closing the game with esc in the same place)

Thank you in advance. An explanation of what the code is actually doing would be much appreciated :D

Re: *dt not working, love.keypressed(k) questions

Posted: Sat Apr 27, 2013 12:30 pm
by easy82
Hi! I've made an example that explains everything through comments (.love is included). This is more-or-less how I make framerate-independent movement in games.

Code: Select all

function love.load()
  -- Set character properties
  man = {}
  man.posX = 100
  man.posY = 200
  man.size = 20
  man.speed = 1
  man.friction = 0.1
  man.keyLeft = "left"
  man.keyRight = "right"
  man.keyUp = "up"
  man.keyDown = "down"

  man.moveLeft = false
  man.moveRight = false
  man.moveUp = false
  man.moveDown = false
  man.forceX = 0
  man.forceY = 0

  -- Timestep for fixed timer
  timer = {}
  timer.step = 0.01
  timer.remain = 0
  timer.cycles = 0

  -- Slow mode is off by default
  slowMode = false
end

function love.keypressed(k)
  -- Quit if escape was pressed
  if k == "escape" then love.event.push("quit") end

  -- Toggle slow mode
  if k == " " then slowMode = not slowMode end

  -- Player control
  if k == man.keyLeft  then man.moveLeft  = true end
  if k == man.keyRight then man.moveRight = true end
  if k == man.keyUp    then man.moveUp    = true end
  if k == man.keyDown  then man.moveDown  = true end
end

function love.keyreleased(k)
  -- Player control
  if k == man.keyLeft  then man.moveLeft  = false end
  if k == man.keyRight then man.moveRight = false end
  if k == man.keyUp    then man.moveUp    = false end
  if k == man.keyDown  then man.moveDown  = false end
end

function love.update(dt)
  -- Move out character with framerate-independent speed
  timer.remain = timer.remain + dt
  timer.cycles = 0

  while timer.remain > timer.step do
    timer.remain = timer.remain - timer.step
    timer.cycles = timer.cycles + 1

    -- Add controlling force
    if man.moveLeft  then man.forceX = man.forceX - man.speed end
    if man.moveRight then man.forceX = man.forceX + man.speed end
    if man.moveUp    then man.forceY = man.forceY - man.speed end
    if man.moveDown  then man.forceY = man.forceY + man.speed end

    -- Smooth movement
    man.forceX = man.forceX * (1 - man.friction)
    man.forceY = man.forceY * (1 - man.friction)

    -- Change the position itself
    man.posX = man.posX + man.forceX
    man.posY = man.posY + man.forceY
  end
end

function love.draw()
  -- Draw our character
  love.graphics.setColor(255, 0, 0)
  love.graphics.circle("fill", man.posX, man.posY, man.size)

  -- Print some useful info
  love.graphics.setColor(255, 255, 255)
  love.graphics.print("Use arrow keys to move, space to toggle slow mode.", 10, 10)
  love.graphics.print("Delta: " .. love.timer.getDelta(), 10, 30)
  love.graphics.print("Remain: " .. string.format("%.3f", timer.remain), 10, 50)
  love.graphics.print("Cycles: " .. timer.cycles, 10, 70)

  -- Emulate a slower computer
  if slowMode then love.timer.sleep(0.05) end
end
Download:
fixedtimeexample.love
(931 Bytes) Downloaded 160 times

Re: *dt not working, love.keypressed(k) questions

Posted: Mon Apr 29, 2013 3:32 pm
by Rafer45
I'm sorry, but what did you do? I didn't really understand what the *dt was doing and what all of the time functiuons did :|
Sorry for being so nooby, but I really didn't understand much.
Also, how can I define love.keypressed(k) without having to define it all at once? (like in the code :death: )

Re: *dt not working, love.keypressed(k) questions

Posted: Mon Apr 29, 2013 9:55 pm
by easy82
Rafer45 wrote:I'm sorry, but what did you do? I didn't really understand what the *dt was doing and what all of the time functiuons did :|
Sorry for being so nooby, but I really didn't understand much.
Also, how can I define love.keypressed(k) without having to define it all at once? (like in the code :death: )
The code shows how to make framerate independent, smooth movement. So whatever your FPS is, your characters will move the same way, on every computer. It uses a fixed timer to achieve this effect. This way you can forget about dt, and use constant speed to move your characters (or anything else) around!

About the keypressed related issue: you just need to write your function somewhere that handles keypressed or keyreleased events, and finally call this function in love.keypressed or love.keyreleased.

I've updated the example, where I've made it more easier to use and to understand the above methods. I've also restructured the code, so that you can see how you can structure your code. Be warned though, the code is rather basic!

Download:
fixedtimeexample2.love
(1.93 KiB) Downloaded 145 times

Re: *dt not working, love.keypressed(k) questions

Posted: Tue Apr 30, 2013 11:25 am
by Lafolie
There's a blog entry that explains this pretty well. http://blogs.love2d.org/content/quick-snips-delta-time