Hi, I’m using the exact same code as the platformer tutorial as I’m not pretty good with physics. I took a video of how this looks.
Btw I’m using @britzl’s orthographic camera, pretty cool and easy to use.
If it helps this is the code I’m using for the player (kinematic).
-- player.script
----
local move_acceleration = 3500
local air_acceleration_factor = 0.8
local max_speed = 450
local gravity = -1000
local jump_takeoff_speed = 550
local fall_multiplier = 2.5
local low_jump_multiplier = 2
local msg_contact_point_response = hash("contact_point_response")
local group_obstacle = hash("obstacle")
local input_right = hash("right")
local input_left = hash("left")
local input_jump = hash("jump")
function init(self)
msg.post(".", "acquire_input_focus")
self.velocity = vmath.vector3(0, 0, 0)
self.correction = vmath.vector3()
self.ground_contact = false
self.move_input = 0
self.anim = nil
end
function final(self)
msg.post(".", "release_input_focus")
end
function update(self, dt)
local target_speed = self.move_input * max_speed
local speed_diff = target_speed - self.velocity.x
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
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
local v0 = self.velocity
self.velocity = self.velocity + dv
local dp = (v0 + self.velocity) * dt * 0.5
-- Make jump look more natural
if self.velocity.y < 0 then
self.velocity.y = self.velocity.y + gravity * (fall_multiplier - 1) * dt
elseif self.velocity.y > 0 then
self.velocity.y = self.velocity.y + gravity * (low_jump_multiplier - 1) * dt
end
-- Apply all this before
go.set_position(go.get_position() + dp)
-- Reset volatile state
self.correction = vmath.vector3()
self.move_input = 0
self.ground_contact = false
end
function handle_obstacle_contact(self, normal, distance)
local proj = vmath.dot(self.correction, normal)
local comp = (distance - proj) * normal
self.correction = self.correction + comp
go.set_position(go.get_position() + comp)
if normal.y > 0.7 then
self.ground_contact = true
end
proj = vmath.dot(self.velocity, normal)
if proj < 0 then
self.velocity = self.velocity - proj * normal
end
end
function on_message(self, message_id, message, sender)
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
function jump(self)
if self.ground_contact then
self.velocity.y = jump_takeoff_speed
end
end
function abort_jump(self)
if self.velocity.y > 0 then
self.velocity.y = self.velocity.y * 0.4
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
end
end