I’ve been making a platformer and everything is going smoothly however my animations seem to be a bit odd.
As you can see in the first few seconds the animations seem to be working fine but as my speed increases the animations starts to alter weirdly, this is obviously due different animations merging in between seen by my print statements, I am not sure how to fix this as animations is not really my thing.
local move_acceleration = 100
local air_acceleration_factor = 0.25
local max_speed = 150
local gravity = -400
local jump_takeoff_speed = 220
local touch_jump_timeout = 0.2
-- pre-hashing ids improves performance
local msg_contact_point_response = hash("contact_point_response")
local msg_animation_done = hash("animation_done")
local group_obstacle = hash("ground")
local input_left = hash("left")
local input_right = hash("right")
local input_jump = hash("up")
local input_touch = hash("touch")
local anim_run = hash("run")
local anim_idle = hash("idle")
local anim_jump = hash("jump")
local anim_fall = hash("fall")
function init(self)
msg.post(".", "acquire_input_focus")
msg.post("/camera#camera", "acquire_camera_focus")
msg.post("@render:", "use_fixed_projection", { zoom = 1.5, near = -1, far = 1 })
self.velocity = vmath.vector3(0, 0, 0)
-- support variable to keep track of collisions
self.correction = vmath.vector3()
self.ground_contact = false
self.move_input = 0
self.anim = nil
self.touch_jump_timer = 0
end
local function play_animation(self, anim)
-- only play animations which are not already playing
if self.anim ~= anim then
sprite.play_flipbook("#sprite", anim)
self.anim = anim
end
end
local function update_animations(self)
-- make sure the player character faces the right way
sprite.set_hflip("#sprite", self.move_input < 0)
if self.ground_contact then
if self.velocity.x == 0 then
play_animation(self, anim_idle)
print("Idle")
else
play_animation(self, anim_run)
print("Run")
end
elseif self.velocity.y >0 then
play_animation(self, anim_jump)
print("Jump")
else
play_animation(self, anim_fall)
print("Fall")
end
end
local function handle_obstacle_contact(self, normal, distance)
local proj = vmath.dot(self.correction, normal)
local comp = (distance - proj) * normal
-- add it to the correction vector
self.correction = self.correction + comp -- compensate
go.set_position(go.get_position() + comp)
if normal.y > 0.7 then -- i did a trial and error to get this value
self.ground_contact = true
end
-- project the velocity onto the normal
proj = vmath.dot(self.velocity, normal)
if proj < 0 then
-- remove that component in that case
self.velocity = self.velocity - proj * normal
end
end
function on_message(self, message_id, message, sender)
-- check if we received a contact point message
if message_id == msg_contact_point_response then
if message.group == group_obstacle then
handle_obstacle_contact(self, message.normal, message.distance)
end
end
end
local function jump(self)
-- only allow jump from ground
if self.ground_contact then
self.velocity.y = jump_takeoff_speed
play_animation(self, anim_jump)
end
end
local function abort_jump(self)
-- cut the jump short if we are still going up
if self.velocity.y > 0 then
self.velocity.y = self.velocity.y * 0.5
end
end
function on_input(self, action_id, action)
if action_id == input_left then
self.move_input = -action.value
elseif action_id == input_right then
self.move_input = action.value
elseif action_id == input_jump then
if action.pressed then
jump(self)
elseif action.released then
abort_jump(self)
end
elseif action_id == input_touch then
local diff = action.x - go.get_position().x
if math.abs(diff) > 10 then
-- slow down when less than 100 pixels away
self.move_input = diff / 100
self.move_input = math.min(1, math.max(-1, self.move_input))
end
if action.released then
-- start timing the last release to see if we are about to jump
self.touch_jump_timer = touch_jump_timeout
elseif action.pressed then
if self.touch_jump_timer > 0 then
jump(self)
end
end
end
end
function update(self, dt)
local target_speed = self.move_input * max_speed
local speed_diff = target_speed - self.velocity.x -- differences of velocity
-- the complete acceleration to integrate over this frame
local acceleration = vmath.vector3(0, gravity, 0)
if speed_diff ~= 0 then
if speed_diff < 0 then
acceleration.x = -move_acceleration
else
acceleration.x = move_acceleration
end
if not self.ground_contact then -- decreases acceleration for money
acceleration.x = air_acceleration_factor * acceleration.x
end
end
local dv = acceleration * dt
if math.abs(dv.x) > math.abs(speed_diff) then
dv.x = speed_diff
end
-- save the current velocity for later use
local v0 = self.velocity
self.velocity = self.velocity + dv
local dp = (v0 + self.velocity) * dt * 0.5
-- apply it to the player character
go.set_position(go.get_position() + dp)
if self.touch_jump_timer > 0 then
self.touch_jump_timer = self.touch_jump_timer - dt
end
update_animations(self)
self.correction = vmath.vector3() --correcting collisions
self.move_input = 0
self.ground_contact = false
end
Decided to give the whole code as I have no idea