diff --git a/defold_game/main/player.script b/defold_game/main/player.script index fb9fb6a..39e64a7 100644 --- a/defold_game/main/player.script +++ b/defold_game/main/player.script @@ -1,7 +1,7 @@ -go.property("acceleration", 100) -go.property("deceleration", 200) -go.property("max_speed", 400) -go.property("wheel_base", 40) -- pixels between left and right wheels +local ACCELERATION = 100 +local DECELERATION = 200 +local MAX_SPEED = 400 +local WHEEL_BASE = 80 local UP = vmath.vector3(0, 1, 0) @@ -10,27 +10,41 @@ function init(self) self.left_speed = 0 self.right_speed = 0 - self.left_input = false - self.right_input = false + self.left_fwd = false + self.left_rev = false + self.right_fwd = false + self.right_rev = false +end + +local function update_speed(speed, drive, dt) + if drive ~= 0 then + local target = drive * MAX_SPEED + local step = ACCELERATION * dt + if speed < target then + return math.min(speed + step, target) + else + return math.max(speed - step, target) + end + else + local step = DECELERATION * dt + if speed > 0 then + return math.max(speed - step, 0) + else + return math.min(speed + step, 0) + end + end end function update(self, dt) - -- each wheel accelerates when its key is held, decelerates otherwise - if self.left_input then - self.left_speed = math.min(self.left_speed + self.acceleration * dt, self.max_speed) - else - self.left_speed = math.max(self.left_speed - self.deceleration * dt, 0) - end + local left_drive = (self.left_fwd and 1 or 0) - (self.left_rev and 1 or 0) + local right_drive = (self.right_fwd and 1 or 0) - (self.right_rev and 1 or 0) - if self.right_input then - self.right_speed = math.min(self.right_speed + self.acceleration * dt, self.max_speed) - else - self.right_speed = math.max(self.right_speed - self.deceleration * dt, 0) - end + self.left_speed = update_speed(self.left_speed, left_drive, dt) + self.right_speed = update_speed(self.right_speed, right_drive, dt) -- differential drive: speed difference creates rotation, average creates forward motion local linear_speed = (self.left_speed + self.right_speed) / 2 - local angular_vel = (self.right_speed - self.left_speed) / self.wheel_base + local angular_vel = (self.right_speed - self.left_speed) / WHEEL_BASE local rot = go.get_rotation() rot = rot * vmath.quat_rotation_z(angular_vel * dt) @@ -40,15 +54,13 @@ function update(self, dt) p = p + vmath.rotate(rot, UP * linear_speed * dt) go.set_position(p) - -- reset each frame (on_input re-sets if key is still held) - self.left_input = false - self.right_input = false end function on_input(self, action_id, action) - if action_id == hash("a_key") then - self.left_input = true - elseif action_id == hash("d_key") then - self.right_input = true + local held = action.pressed or not action.released + if action_id == hash("a_key") then self.left_fwd = held + elseif action_id == hash("q_key") then self.left_rev = held + elseif action_id == hash("d_key") then self.right_fwd = held + elseif action_id == hash("e_key") then self.right_rev = held end end