Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Player logic
- -- these are the tweaks for the mechanics, feel free to change them for a different feeling
- -- acceleration factor to use when air-borne
- local air_acceleration_factor = 0.8
- -- max speed right/left
- local max_speed = 600
- -- gravity pulling the player down in pixel units
- local gravity = -1900
- -- take-off speed when jumping in pixel units
- local jump_takeoff_speed = 1200
- -- 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("jump")
- local anim_walk = hash("walk")
- local anim_idle = hash("idle")
- local anim_jump = hash("jump")
- local anim_fall = hash("fall")
- --physics.set_constant(/player#collisionobject, "continuous_collision", true)
- function init(self)
- -- this lets us handle input in this script
- msg.post(".", "acquire_input_focus")
- -- activate camera attached to the player collection
- -- this will send camera updates to the render script
- msg.post("#camera", "acquire_camera_focus")
- msg.post("@render:", "use_camera_projection")
- -- initial player velocity
- self.velocity = vmath.vector3(0, 0, 0)
- -- the direction the player is facing
- self.facing_direction = 0
- -- support variable to keep track of collisions and separation
- self.correction = vmath.vector3()
- -- if the player stands on ground or not
- self.ground_contact = false
- -- the currently playing animation
- self.anim = nil
- end
- local function play_animation(self, anim)
- -- only play animations which are not already playing
- if self.anim ~= anim then
- -- tell the sprite to play the animation
- sprite.play_flipbook("#sprite", anim)
- -- remember which animation is playing
- self.anim = anim
- end
- end
- local function update_animations(self)
- -- make sure the player character faces the right way
- sprite.set_hflip("#sprite", self.facing_direction < 0)
- -- make sure the right animation is playing
- if self.ground_contact then
- if self.velocity.x == 0 then
- play_animation(self, anim_idle)
- else
- play_animation(self, anim_walk)
- end
- else
- if self.velocity.y > 0 then
- play_animation(self, anim_jump)
- else
- play_animation(self, anim_fall)
- end
- end
- end
- function fixed_update(self, dt)
- -- apply gravity
- self.velocity.y = self.velocity.y + gravity * dt
- -- move player
- local pos = go.get_position()
- pos = pos + self.velocity * dt
- go.set_position(pos)
- -- update animations based on state (ground, air, move and idle)
- update_animations(self)
- -- reset volatile state
- self.correction = vmath.vector3()
- self.ground_contact = false
- -- self.wall_contact = false
- end
- -- https://defold.com/manuals/physics/#resolving-kinematic-collisions
- local function handle_obstacle_contact(self, normal, distance)
- if distance > 0 then
- -- First, project the accumulated correction onto
- -- the penetration vector
- local proj = vmath.project(self.correction, normal * distance)
- if proj < 1 then -- default is 1 ME
- -- Only care for projections that does not overshoot.
- local comp = (distance - distance * proj) * normal
- -- Apply compensation
- go.set_position(go.get_position() + comp) -- + comp
- -- Accumulate correction done
- self.correction = self.correction + comp
- end
- end
- -- collided with a wall
- -- stop horizontal movement
- if math.abs(normal.x) > 0.7 then
- self.wall_contact = true
- self.velocity.x = 0
- end
- -- collided with the ground
- -- stop vertical movement
- if math.abs(normal.y) > 0.7 then
- self.ground_contact = true
- self.velocity.y = 0
- end
- -- collided with the ceiling
- -- stop vertical movement
- if normal.y < -0.7 then
- self.velocity.y = 0
- 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
- -- check that the object is something we consider an obstacle
- if message.group == group_obstacle then
- handle_obstacle_contact(self, message.normal, message.distance)
- end
- end
- end
- local function jump(self)
- -- set take-off speed
- self.velocity.y = jump_takeoff_speed
- -- play animation
- play_animation(self, anim_jump)
- self.ground_contact = false
- end
- local function walk(self, direction)
- -- only change facing direction if direction is other than 0
- if direction ~= 0 then
- self.facing_direction = direction
- end
- -- update velocity and use different velocity on ground and in air
- if self.ground_contact then
- self.velocity.x = max_speed * direction
- else
- -- move slower in the air
- self.velocity.x = max_speed * air_acceleration_factor * direction
- end
- end
- function on_input(self, action_id, action)
- if action_id == input_left then
- walk(self, -action.value)
- elseif action_id == input_right then
- walk(self, action.value)
- elseif action_id == input_jump then
- if action.pressed then
- jump(self)
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement