Page 1 of 1

Nonphysical translated movement

Posted: Mon Jul 20, 2009 1:33 am
by CharWirtanen
I notice there aren't any functions included for basic effects like translating a sprite to a position over a certain amount of time, does anyone have a tutorial or example on how to do this?

I understand the concept, but the math is messing me up a bit and I can't figure out how to implement such a thing well. What I'm basically trying to do is get a sprite to move up and then down smoothly, to create a 'hit' effect.\

Thanks in advance -- Love is awesome!

Edit: And while I'm here, is there any way to multiply a color onto an image?

Re: Nonphysical translated movement

Posted: Mon Jul 20, 2009 8:24 am
by Tenoch
To draw an image multiplied by a color, you can use love.graphics.setColorMode(love.color_modulate), it will then use the current color to, well, modulate each sprite drawing.

I'm not sure what you mean with your other question.
There is no function to "move" a sprite. LÖVE does not remember where sprites are, you have to draw them yourself where you want at each frame. Now to find the right functions to move a sprite smoothly from one point to another, many possibilities exist. A very good introduction is here: http://sol.gfxile.net/interpolation/index.html

Of course these functions are in 1D only, but you can siply apply them to both coordinates independently, and you'll hopefully get what you want.

Re: Nonphysical translated movement

Posted: Mon Jul 20, 2009 7:57 pm
by CharWirtanen
Tenoch wrote: There is no function to "move" a sprite. LÖVE does not remember where sprites are, you have to draw them yourself where you want at each frame. Now to find the right functions to move a sprite smoothly from one point to another, many possibilities exist. A very good introduction is here: http://sol.gfxile.net/interpolation/index.html

Of course these functions are in 1D only, but you can siply apply them to both coordinates independently, and you'll hopefully get what you want.
These are really good guides and while I knew how to do the basic method, that smoothstep trick is awesome, thanks a bunch. My question is more along the lines that I'm unsure how to integrate such a thing with LOVE's update() method to keep the timing right

Are there any existing examples of people using interpolation in LOVE with their images? I'm sure I can't be the first one to want to do this since its a basic need for npcs and enemies who move around

Re: Nonphysical translated movement

Posted: Tue Jul 21, 2009 8:04 am
by Tenoch
One possibility is to have, for the wanted object, one variable holding the current position, and one for the target position. Then at each update(), you make the current position closer to the target position:

Code: Select all

x = x + (targetx - x) * coeff * dt
(and same on y coord of course)

This is equivalent to the weighed average from the webpage, and this gives cool smooth movement (fast at the beginning, slower as you get there). I use it all the time to center cameras.

For other types of interpolation, you need to remember more information. Typically, the starting point, the distance to go, the time you want the movement to last and time since movement started. You first init:

Code: Select all

elapsedtime = 0
Then at each update you'll have something like:

Code: Select all

elapsedtime = elapsedtime + dt
param = elapsedtime / totaltime    -- this is the param in the range 0..1
x = startingx + distance * interpolationfunction(param)
(I assume the interpolation function takes params from 0 to 1, and returns also something that starts at 0 and ends at 1)

Although I never tried it should work. Maybe others will have easier/better ways :)

Re: Nonphysical translated movement

Posted: Tue Jul 21, 2009 8:45 am
by bartbes
I tend to do:

Code: Select all

--x is the x of the object
--targetx is the target x
--speed is the amount of pixels/second
function update(dt)
   local step = speed * dt
   local diff = targetx - x
   if math.abs(diff) <= step then
      x = targetx
   elseif diff < 0
      x = x - step
   else
      x = x + step
   end
end
Oh, I might've swapped targetx and x around, anyway, that's easy enough to detect and fix. This should work, but I want a better way to detect if it's positive or negative.. I used to do

Code: Select all

x = x + diff/math.abs(diff) * step
But that seemed too much work, I'm probably overlooking something anyway.

Re: Nonphysical translated movement

Posted: Tue Jul 28, 2009 3:37 am
by Jasoco
I use Tables for all my "actors" and "objects" in my game. I have NPC's, Enemies, Projectiles and Explosions (Animations that run until they expire) that are all rendered every frame.

A basic gist would be:

In the LOAD function:

Code: Select all

actor = {}
When you want to create an ACTOR you would:

Code: Select all

function createActor(x, y)
  table.insert(actor, {x = x, y = y})
end
In the UPDATE function I would have: (Where a would be the actor and i would be the index if you want to use it for anything, like destroying the table entry to remove it.)

Code: Select all

for i, a in ipairs(actor) do
  a.x = a.x + 1
  a.y = a.y + 1

  if a.x > screen_width or a.y > screen_height then 
    destroyActor(i)
  end
end
This example will move the existing ACTORs 1 pixel every frame and destroy them if they go off screen. Just as an example of course.

And in the DRAW function: (Assuming of course you have defined images beforehand and know how to use the drawing commands)

Code: Select all

for i, a in ipairs(actor) do
  love.graphics.draw(actor_image, a.x, a.y)
end
If you want to remove an ACTOR you would:

Code: Select all

function destroyActor(indexofactor)
  table.remove(actor, indexofactor)
end
ACTOR's could be created and destroyed at any time. So basically when an enemy or the player fires a projectile, a new projectile is INSERTed into the projectiles table. The UPDATE function will run through all living projectiles and move them appropriately based on the parameters I gave them at table insertion. When they run their course (In my case, when they collide with an enemy, the player or a wall) they are destroyed.

If no ACTORs are present, the for loop doesn't run anything. If one or more ACTORs exist, they are calculated. Keeps the FPS as high as possible by only drawing things that are alive.

This of course is a simple example to give you an idea.