0 Favourites

Move sprite to a new position?

  • Hi all, I'm trying to figure out how to move a sprite to a new position. So, for example, when a condition is met I want a sprite to move to self.x-50, and I want that movement to happen over the span of .5 seconds.

    In my searching I've come across LERP, but I'm extremely confused about how to use it. Every tutorial and forum explanation comes with someone sharing a .capx to explain it, but obviously all the links are dead.

    I followed one suggestion I saw, and even though I don't really understand why it works, it does kind of work. The problem is that the sprite's movement starts fast and then slows, so it's not one consistent movement.

    Could anyone help me to better understand LERP, or explain another way to do this? (though I do really want to learn LERP, as it seems like it's going to be something I have to understand to advance in Construct).

    Thanks!

  • wirelesstkd

    Ashley wrote a great blog post about lerp here: https://www.scirra.com/blog/ashley/17/using-lerp-with-delta-time

    The reason why the example you followed slowed down is probably because the first value in the lerp expression was being updated every tick. So, the distance the sprite moves gets smaller and smaller as it approaches the target location. This provides a nice ease in effect (if that is what you want - which you don't).

    eg: Set Sprite.x to Lerp( Sprite.x, TargetX, dt )

    Sprite.x changes every time the expression is evaluated (and is used inside the lerp expression), so the amount the sprite moves each step of the way is reduced as it gets closer to the target - which slows it down. since you want a constant speed, you need to change the third value in the expression (the percent moved from value1 to value2) without changing value1.

    eg: Set Sprite.x to Lerp( StartX, TargetX, percentMoved)

    when percentMoved = 0 the sprite will be at StartX

    when percentMoved = 0.5 the sprite will be half way between startX and targetX

    when percentMoved = 1 the sprite will be at targetX

    so, as percentMoved changes from 0 to 1 (or 0% to 100%) the sprite will move at a steady speed (as long as percentMoved changes at a constant speed).

    You just have to be careful not to change startX or targetX while the sprite is moving.

    If you add dt to percentMoved every tick, then it would take 1 second to move from startX to targetX.

    but since you want the move to take 0.5 seconds, you want to add dt*2.

    I made a quick sample here: http://www.rieperts.com/games/forum/lerp.capx

  • Thanks very much! I don't really understand this, but I'm going to sit down and try to make it make sense. Your explanation is very clear, but I'm terrible with math (which I know makes game-development a terrible hobby for me, but I'll persist, lol).

    Thank you for the capx - I'm definitely going to spend with it trying to figure it out.

  • lerp(a,b,x)

    a - Starting number

    b - Ending number

    x - The percentage amount between the start and end number you want to get (between 0 and 1, or 0% and 100%)

    So lerp(10,20,0.5) gives you 15, or halfway between 10 and 20.

    Allan gave a pretty good explanation of why it slows down above - basically when you use the current position as a start point, the lerp amount gets updated every tick to be smaller and smaller.

    Just going to give you a heads up though - lerp is generally used for more advanced gradual motion/inertia. If you're looking for simple straightforward movement, you would best be served by getting familiar with the Bullet behavior. The Bullet behavior is generally the go to solution for almost all linear movement needs.

    Alternatively, http://c2rexplugins.weebly.com/rex_moveto.html is a fantastic plugin that you might find useful.

  • if you want to smoothly shift sprite

    use lerp

    but if you are not familier with lerp then you can use litetween behaviour for same

  • Hi everyone, I'm really stuck on this again. I've decided that I do actually want the lerp type of movement, but I can't get it to work. Basically, when the player collides with an object I want the object to push the player back. So I'm trying to say that the player should move Player.X-200.

    I would think that I should just do...

    Player > set x > lerp(player.x, player.x-200, 0.5)

    ...with the understand that I can play around with the 0.5 to make it faster or slow, depending on how it looks (I understand that I'll eventually want to use delta time to make it frame rate independent, but I just want to understand the basics before I dive in to that).

    However, when I do this the character teleports to player.x-200 instead of moving slowly.

    Can anyone explain what I'm doing wrong here?

    Thanks in advance for your patience

    Matt

  • lerp(player.x, player.x-200, 0.5) is the equivilant of moving the player left 100 pixels every time it is run.

    Since player.x gets updated every time it is moved, lerp isn't doing much here.

    Example if you have running every tick

    Frame 1. Player.x is 2000. lerp(player.x, player.x-200, 0.5) = lerp(2000, 1800, 0.5) = 1900

    Frame 2. Player.x is 1900. lerp(player.x, player.x-200, 0.5) = lerp(1900, 1700, 0.5) = 1800

    Frame 3. Player.x is 1800. lerp(player.x, player.x-200, 0.5) = lerp(1800, 1600, 0.5) = 1700

    and so on.

    If you want a gradual movement that slows down, use a fixed target (usually accomplished by setting the target position in a variable once). So set TargetPosition to player.x-200, one time. Following the previous example on frame 1, this would be 1800.

    Frame 1. Player.x is 2000. lerp(player.x, TargetPosition, 0.5) = lerp(2000, 1800, 0.5) = 1900

    Frame 2. Player.x is 1900. lerp(player.x, TargetPosition, 0.5) = lerp(1900, 1800, 0.5) = 1850

    Frame 3. Player.x is 1850. lerp(player.x, TargetPosition, 0.5) = lerp(1850, 1800, 0.5) = 1825

    and so on. You can see the amount the player moves each tick gets less and less, but it will never actually reach 1800.

    If your lerp event runs only once, it also doesn't serve much purpose in this case.

  • Construct 3

    Buy Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Buy Now Construct 3 users don't see these ads
  • Okay, here's a capx I made testing this out:

    https://drive.google.com/open?id=0B4Hga ... zJIVklTZlk

    Would mind taking a look and letting me know what I did wrong?

  • Save the project as a simple file ex 1.capx

    I used lerp, now i use lunarray.litetween behavior.

  • Event 2 is a subevent of event 1. Therefore it runs only one time, on collision.

    You'll need another condition to determine when to start/stop running your lerp event.

    Honestly I would say lerp isn't the right method to use for this application, you should probably set platform behavior vector x.

  • I was originally using the vector x behavior, but the problem I ran in to was that it would only move a small way back. I thought this was because the vector x is capped at the movement speed. When I tried to increase the movement speed, obviously the character moved too quickly.

    I think I read elsewhere on the forum that it would be advisable to use lerp to get around this. Do you think there's a better way?

  • Okay, so I got it - thank you oosyrag. I set a global boolean called collision, then said:

    On collision with enemy, set Target to Player.X-200 AND set Collision to True

    Then...

    If Collision is True, set Player X to lerp(Player.X, Target, 0.5) AND Wait .25 seconds, then set Collision to False

    So I see what you mean about that not being optimal. If you think there's a better way, please let me know

    But I THINK I finally understand lerp, which is a huge win for me.

  • Oh right, I remember I was the one who mentioned the max speed thing haha. Here's how I would do it:

    + Player: On collision with Enemy

    -> Player: Set Platform vector X to -1000

    -> Player: Set Platform maximum speed to 1000

    -> Player: Start ignoring Platform user input

    + System: Player.?Platform.?MaxSpeed > 330

    -> Player: Set Platform maximum speed to max(?300?,?abs(?Player.?Platform.?VectorX)?)

    + System: Else

    + System: Trigger once

    -> Player: Stop ignoring Platform user input

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)