Nonphysical translated movement

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
CharWirtanen
Prole
Posts: 7
Joined: Mon Jul 20, 2009 1:10 am

Nonphysical translated movement

Post 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?
User avatar
Tenoch
Citizen
Posts: 76
Joined: Mon Jul 21, 2008 7:49 am

Re: Nonphysical translated movement

Post 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.
"When in doubt, use brute force." Ken Thompson
CharWirtanen
Prole
Posts: 7
Joined: Mon Jul 20, 2009 1:10 am

Re: Nonphysical translated movement

Post 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
User avatar
Tenoch
Citizen
Posts: 76
Joined: Mon Jul 21, 2008 7:49 am

Re: Nonphysical translated movement

Post 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 :)
"When in doubt, use brute force." Ken Thompson
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Nonphysical translated movement

Post 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.
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Nonphysical translated movement

Post 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.
Post Reply

Who is online

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