how to run function every halfsecond instead of millisecond?

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.
Post Reply
xxcjn420xx
Prole
Posts: 8
Joined: Thu May 29, 2014 5:23 pm

how to run function every halfsecond instead of millisecond?

Post by xxcjn420xx »

So I'm trying to make the player be affected by gravity until the player collides with something while being able to change the direction of the gravity via the arrow keys. As one last condition, the player should not be able to change the gravity while in mid-air.
This is what I have so far:

Code: Select all

if love.keyboard.isDown("down") then
    repeat
        p.y = p.y + force
    until
        CheckCollision1(px,py,pw,ph, x1,y1,w1,h1) or
        CheckCollision2(px,py,pw,ph, x2,y2,w2,h2) or
        CheckCollision3(px,py,pw,ph, x3,y3,w3,h3) or
        CheckCollision4(px,py,pw,ph, x4,y4,w4,h4) or
        CheckCollision5(px,py,pw,ph, x5,y5,w5,h5) or
        CheckCollision6(px,py,pw,ph, x6,y6,w6,h6) or
        CheckCollision7(px,py,pw,ph, x7,y7,w7,h7)
end
if love.keyboard.isDown("up") then
    repeat
        p.y = p.y - force
    until
        CheckCollision1(px,py,pw,ph, x1,y1,w1,h1) or
        CheckCollision2(px,py,pw,ph, x2,y2,w2,h2) or
        CheckCollision3(px,py,pw,ph, x3,y3,w3,h3) or
        CheckCollision4(px,py,pw,ph, x4,y4,w4,h4) or
        CheckCollision5(px,py,pw,ph, x5,y5,w5,h5) or
        CheckCollision6(px,py,pw,ph, x6,y6,w6,h6) or
        CheckCollision7(px,py,pw,ph, x7,y7,w7,h7)
end
if love.keyboard.isDown("right") then
    repeat
        p.x = p.x + force
    until
        CheckCollision1(px,py,pw,ph, x1,y1,w1,h1) or
        CheckCollision2(px,py,pw,ph, x2,y2,w2,h2) or
        CheckCollision3(px,py,pw,ph, x3,y3,w3,h3) or
        CheckCollision4(px,py,pw,ph, x4,y4,w4,h4) or
        CheckCollision5(px,py,pw,ph, x5,y5,w5,h5) or
        CheckCollision6(px,py,pw,ph, x6,y6,w6,h6) or
        CheckCollision7(px,py,pw,ph, x7,y7,w7,h7)
end
if love.keyboard.isDown("left") then
    repeat
        p.x = p.x - force
    until
        CheckCollision1(px,py,pw,ph, x1,y1,w1,h1) or
        CheckCollision2(px,py,pw,ph, x2,y2,w2,h2) or
        CheckCollision3(px,py,pw,ph, x3,y3,w3,h3) or
        CheckCollision4(px,py,pw,ph, x4,y4,w4,h4) or
        CheckCollision5(px,py,pw,ph, x5,y5,w5,h5) or
        CheckCollision6(px,py,pw,ph, x6,y6,w6,h6) or
        CheckCollision7(px,py,pw,ph, x7,y7,w7,h7)
end


But the issue is that the code runs every millisecond or less, and I want the movement to be smooth instead of instant. Therefore, I'm wondering how best to approach this concept.

I realize that having a bunch of functions for checking collision like that is really bad design, but I have made no attempt at cleaning up or optimizing the code as of yet, and also it works and I did it by myself so I'm okay with it for now. I'll probably create another function that calls all of them or something like that. Thank you for your help and your time.


Here is my full main.lua if needed: http://pastebin.com/5X1dydqB
User avatar
undef
Party member
Posts: 438
Joined: Mon Jun 10, 2013 3:09 pm
Location: Berlin
Contact:

Re: how to run function every halfsecond instead of millisec

Post by undef »

You could work with acceleration.

Always update this:
p.y = p.y + speed.y
p.x = p.x + speed.x

And then apply acceleration to the speed:
-- you should set a terminal velocity so your object doesn't keep accelerating
if love.keyboard.isDown("down") and speed.y<terminalVelocity then
speed.y = speed.y + acceleration
end

Then you can check collision in update as well:
if collisionX() then speed.x = 0
if collisionY() then speed.y = 0

Something like that... I hope it helps
twitter | steam | indieDB

Check out quadrant on Steam!
xxcjn420xx
Prole
Posts: 8
Joined: Thu May 29, 2014 5:23 pm

Re: how to run function every halfsecond instead of millisec

Post by xxcjn420xx »

I'm afraid I couldn't make much sense of that, I'm sorry. :(
User avatar
undef
Party member
Posts: 438
Joined: Mon Jun 10, 2013 3:09 pm
Location: Berlin
Contact:

Re: how to run function every halfsecond instead of millisec

Post by undef »

Ah, sorry... I guess I was too superficial^^

The way you do it right now the position is being changed abpruptly, which doesn't seem natural.
What you probably want is it to be more like a spaceship flying in space: Unless it hits something or unless you apply force on it, it just keeps flying.
Or do you want something else?


Your code gets run too often because of the repeat loop, which you don't need.
Just constantly applying speed to your objects position in the update function should suffice.
On collision you just set the speed to zero.
If you want to abpruptly change direction you could just set the speed to any value, otherwise you could do something like speed = speed +0.1
twitter | steam | indieDB

Check out quadrant on Steam!
xxcjn420xx
Prole
Posts: 8
Joined: Thu May 29, 2014 5:23 pm

Re: how to run function every halfsecond instead of millisec

Post by xxcjn420xx »

What I’m trying to do is make it to where the player will not move once the game starts until the player uses an arrow key. Once an arrow key is pressed, even if the key is released, I want the player to move in the direction of the key pressed until it collides with something, in which case the player stops at the border of the object they collided with. Hopefully that made sense.

From my gathering,

Code: Select all

if love.keyboard.isDown("down") then
            if not CheckCollision(px,py,pw,ph, x1,y1,w1,h1, x2,y2,w2,h2, x3,y3,w3,h3, x4,y4,w4,h4, x5,y5,w5,h5, x6,y6,w6,h6, x7,y7,w7,h7) then
                py = py + force
            else
                py = Y
            end         
elseif love.keyboard.isDown("up") then
            if not CheckCollision(px,py,pw,ph, x1,y1,w1,h1, x2,y2,w2,h2, x3,y3,w3,h3, x4,y4,w4,h4, x5,y5,w5,h5, x6,y6,w6,h6, x7,y7,w7,h7) then
                py = py - force
            else
                py = Y  
            end    
elseif love.keyboard.isDown("right") then
            if not CheckCollision(px,py,pw,ph, x1,y1,w1,h1, x2,y2,w2,h2, x3,y3,w3,h3, x4,y4,w4,h4, x5,y5,w5,h5, x6,y6,w6,h6, x7,y7,w7,h7) then
                px = px + force
            else
                px = X
            end
elseif love.keyboard.isDown("left") then
            if not CheckCollision(px,py,pw,ph, x1,y1,w1,h1, x2,y2,w2,h2, x3,y3,w3,h3, x4,y4,w4,h4, x5,y5,w5,h5, x6,y6,w6,h6, x7,y7,w7,h7) then
                px = px - force
            else
                px = X
            end
        end        
will this work?
User avatar
undef
Party member
Posts: 438
Joined: Mon Jun 10, 2013 3:09 pm
Location: Berlin
Contact:

Re: how to run function every halfsecond instead of millisec

Post by undef »

Ok, I like in 2048 kind of?
https://gabrielecirulli.github.io/2048/

The code you wrote will only move the player while the key is down, you might rather want to use love.keypressed( k )

The way I usually handle this is like this:

Code: Select all

keys = {
	escape = love.event.quit,
	r = love.load,
}

function love.keypressed( k )
	local action = keys[k]
	if action then  action( )  end
end
a simpler but less reusable version would be:

Code: Select all

function love.keypressed( k )
	if k=="down" then
	   force.x = 0
           force.y = <yourNumber>
       end
       -- of course the other  keys as well
end
and in love.update() you would do the following:

Code: Select all

py = py + force.y
px = px + force.x
if CheckCollision() then
    force.x, force.y = 0, 0
    -- you'll probably want to move the player away from the collision object here so it dosen't get through it ( just move the player a pixel away )
end
twitter | steam | indieDB

Check out quadrant on Steam!
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: how to run function every halfsecond instead of millisec

Post by Jasoco »

Look up a library called Cron.

Very useful.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: how to run function every halfsecond instead of millisec

Post by micha »

Whenever you want to do an action that lasts longer than one timestep, then you cannot implement this by having a while/repeat/for-loop inside of one timestep. Instead you have to organize the action in a way that it is done over several timesteps. The simplest way for your case is to introduce a variable "state" that tells you, what is happening at the moment (this is what undef already suggested).
Let's say, when the player has not pressed any button, then the state is "waiting".
When a button is pressed then the state changes. For example like this:

Code: Select all

function love.keypressed(key)
  if state == 'waiting' then
    if key == 'up' then
      state = 'up'
    elseif key == 'down' then
      state = 'down'
   -- and so on
    end
  end
end
And then in the update you make an if construction that checks which of the states you are in and perform the action accordingly:

Code: Select all

function love.update(dt)
  if state == 'up' then
    player.y = player.y - force
  elseif state == 'down' then
    player.y = player.y + force
  -- and so on
  end
end
Once this concept is clear to you, try to understand the suggestion of undef. With his construction you can save a couple of lines and avoid an if-construction in the update.
Post Reply

Who is online

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