Nexrem
Nexrem

Reputation: 111

Love2D, LUA Tween resetting

I have a problem with my tweening. I am using tween.lua to move my character left or right when that button is held. On release the player returns back to the middle. Tweening works perfectly for when the character goes either left or right but, for some reason when it has to go back to the middle the character just warps there and does not tween. I suspect that either the base X is overriding it or I am not resseting at the right moment. Here is my code:

--Local variables
local lg = love.graphics
local lk = love.keyboard

function player:load(arg) --Player load function. Called when loaded.

    self.img = lg.newImage(currentPimg)
    playerWidth = player.img:getWidth() --Gets player image width and sets as a variable
    self.mid = width/2 - playerWidth/2
    self.left = 100 - playerWidth/2
    self.right = width - 100 - playerWidth/2

    self.x = player.mid
    self.y = height-150
    self.speed = 0.04

    GoMid = tween.new(player.speed , player, {x=player.mid}, 'linear')
    GoLeft = tween.new(player.speed , player, {x=player.left}, 'linear')
    GoRight = tween.new(player.speed , player, {x=player.right}, 'linear')
end

function player:update(dt) --Player update function. Called each frame, passes DT (delta time)

playerWidth = player.img:getWidth() --Gets player image width and sets as a variable

if LeftStarted and not isLeft then
    GoLeft:reset()
    LeftStarted = false
end
if RightStarted and not isRight then
    GoRight:reset()
    RightStarted = false
end
if MidStarted and not isMid then
    GoMid:reset()
    MidStarted = false
end


if isMid then --If is true then do action
    GoMid:update(dt)
    MidStarted = true
end
if isRight then --If is true then do action
    GoRight:update(dt)
    RightStarted = true
end
if isLeft then --If is true then do action
    GoLeft:update(dt)
    LeftStarted = true
end

if lk.isDown("left", "a") and not isRight then --this check needs to be done since the code is executed the first time. If I do not check weird stuff happens
    isLeft = true 
    isRight, isMid = false
elseif lk.isDown("right", "d") then --checks if the button is down and returns true if it is
    isRight = true
    isLeft, isMid = false
else -- if nothing is down resets player to mid and all variables to false
    isLeft, isRight = false
    isMid = true
end
end

function player:draw(dt) --Draw function. Called each frame, passes DT (delta time)

lg.draw(player.img, player.x, player.y) --Draws player image at X and Y
end

Upvotes: 2

Views: 419

Answers (1)

Isti115
Isti115

Reputation: 2748

Working version of your code

So, after messing a lot with the code, I can present the following to you:

player = { } --Required table thing

--Local variables
local lg = love.graphics
local lk = love.keyboard

function player:load(arg) --Player load function. Called when loaded.

        self.img = lg.newImage(currentPimg)
        playerWidth = player.img:getWidth() --Gets player image width and sets as a variable
        self.mid = width/2 - playerWidth/2
        self.left = 100 - playerWidth/2
        self.right = width - 100 - playerWidth/2

        self.x = player.mid
        self.y = height-150
        self.speed = 0.5

        GoMid = tween.new(player.speed , player, {x=player.mid}, 'linear')
        GoLeft = tween.new(player.speed , player, {x=player.left}, 'linear')
        GoRight = tween.new(player.speed , player, {x=player.right}, 'linear')
end

function player:update(dt) --Player update function. Called each frame, passes DT (delta time)

    playerWidth = player.img:getWidth() --Gets player image width and sets as a variable

    if LeftStarted and not isLeft then
    GoMid = tween.new(player.speed , player, {x=player.mid}, 'linear')
    LeftNeedsReset = true
        LeftStarted = false
    end
    if RightStarted and not isRight then
    GoMid = tween.new(player.speed , player, {x=player.mid}, 'linear')
    RightNeedsReset = true
        RightStarted = false
    end

    if isMid then --If is true then do action
        GoMid:update(dt)
    end
    if isRight then --If is true then do action
    if RightNeedsReset then
      GoRight:reset()
      RightNeedsReset = false
    end
        GoRight:update(dt)
        RightStarted = true
    end
    if isLeft then --If is true then do action
    if LeftNeedsReset then
      GoLeft:reset()
      LeftNeedsReset = false
    end
        GoLeft:update(dt)
        LeftStarted = true
    end

    if lk.isDown("left", "a") and not isRight then --this check needs to be done since the code is executed the first time. If I do not check weird stuff happens
        isLeft = true
        isRight, isMid = false, false
    elseif lk.isDown("right", "d") then --checks if the button is down and returns true if it is
        isRight = true
        isLeft, isMid = false, false
    else -- if nothing is down resets player to mid and all variables to false
        isLeft, isRight = false, false
        isMid = true
    end
end

function player:draw(dt) --Draw function. Called each frame, passes DT (delta time)

    lg.draw(player.img, player.x, player.y) --Draws player image at X and Y
end

This sort of achieves what I think you wanted (the player smoothly moving back to the center), but I still don't think this is a good solution.
What I did was that I made a new motion with the appropriate starting point whenever the player needs to start moving back towards the center, and I delayed the resetting of the directional motions until it was necessary, because it makes the player jump back to the starting point.

Observations

I have noticed a few things while I was working with your code.

The first one was that you tried to give a value to multiple variables. As far as I know, it doesn't work this way in Lua. In order to do that you would have to write this:
isLeft, isRight = false, false
instead of this:
isLeft, isRight = false

Also a thing that took a while for me to notice while debugging was that you have wrote the resetting parts of the directions in a different order than the updating parts. I wouldn't consider this a good habit unless you have got very strong reasons to do it this way.

Suggestions

In my opinion this library isn't really suited for this task (although I don't know it very well, this was my first time using it while debugging your code). This could be done easily with built in functionality of the language and the framework itself. You could have a variable that keeps track of the current position, and then change it continuously towards the direction of the pressed button until a limit, and then dragging it back to the center when all the keys are released.

I haven't tested this code, just written it blindly, but it might look something like this:

if love.keyboard.isDown("left") then
  if currentPosition > middlePosition - movementLimit then
    currentPosition = currentPosition - 20 * dt
  end
elseif love.keyboard.isDown("right") then
  if currentPosition < middlePosition + movementLimit then
    currentPosition = currentPosition + 20 * dt
  end
else
  if currentPosition < middlePosition then
    currentPosition = currentPosition + 20 * dt
  elseif currentPosition > middlePosition then
    currentPosition = currentPosition - 20 * dt
  end
end

ps.:Another thing I wouldn't mind would be if you could keep the wording of your comments in the source code between the bounds of good taste. [khm.. debugging.lua : line 7. khm..]

I hope you succeed with your project! Good luck!

Upvotes: 4

Related Questions