±g ™glocal Movement = { STILL_LEFT = "STILL_LEFT", STILL_RIGHT = "STILL_RIGHT", MOVING_LEFT = "MOVING_LEFT", MOVING_RIGHT = "MOVING_RIGHT", CLIMBING_UP = "CLIMBING_UP", CLIMBING_DOWN = "CLIMBING_DOWN", FALLING = "FALLING", JUMPING_LEFT = "JUMPING_LEFT", JUMPING_RIGHT = "JUMPING_RIGHT", JUMPING_STRAIGHT_UP = "JUMPING_STRAIGHT_UP", CLIMBING_STILL = "CLIMBING_STILL", } local Actions = { LEFT_ARROW_PRESS = "LEFT_ARROW_PRESS", LEFT_ARROW_RELEASE = "LEFT_ARROW_RELEASE", RIGHT_ARROW_PRESS = "RIGHT_ARROW_PRESS", RIGHT_ARROW_RELEASE = "RIGHT_ARROW_RELEASE", UP_ARROW_PRESS = "UP_ARROW_PRESS", UP_ARROW_RELEASE = "UP_ARROW_RELEASE", DOWN_ARROW_PRESS = "DOWN_ARROW_PRESS", DOWN_ARROW_RELEASE = "DOWN_ARROW_RELEASE", SPACE_BAR_PRESS = "SPACE_BAR_PRESS", SPACE_BAR_RELEASE = "SPACE_BAR_RELEASE", } local transitions = { [Movement.STILL_RIGHT] = { [Actions.RIGHT_ARROW_PRESS] = Movement.MOVING_RIGHT, [Actions.RIGHT_ARROW_RELEASE] = Movement.STILL_RIGHT, [Actions.LEFT_ARROW_PRESS] = Movement.MOVING_LEFT, [Actions.LEFT_ARROW_RELEASE] = Movement.STILL_LEFT, [Actions.UP_ARROW_PRESS] = Movement.CLIMBING_UP, [Actions.UP_ARROW_RELEASE] = Movement.CLIMBING_STILL, [Actions.DOWN_ARROW_PRESS] = Movement.CLIMBING_DOWN, [Actions.DOWN_ARROW_RELEASE] = Movement.CLIMBING_STILL, }, [Movement.STILL_LEFT] = { [Actions.RIGHT_ARROW_PRESS] = Movement.MOVING_RIGHT, [Actions.RIGHT_ARROW_RELEASE] = Movement.STILL_RIGHT, [Actions.LEFT_ARROW_PRESS] = Movement.MOVING_LEFT, [Actions.LEFT_ARROW_RELEASE] = Movement.STILL_LEFT, [Actions.UP_ARROW_PRESS] = Movement.CLIMBING_UP, [Actions.UP_ARROW_RELEASE] = Movement.CLIMBING_STILL, [Actions.DOWN_ARROW_PRESS] = Movement.CLIMBING_DOWN, [Actions.DOWN_ARROW_RELEASE] = Movement.CLIMBING_STILL, }, [Movement.MOVING_LEFT] = { [Actions.RIGHT_ARROW_PRESS] = Movement.MOVING_RIGHT, [Actions.LEFT_ARROW_PRESS] = Movement.MOVING_LEFT, [Actions.LEFT_ARROW_RELEASE] = Movement.STILL_LEFT, [Actions.UP_ARROW_PRESS] = Movement.CLIMBING_UP, [Actions.DOWN_ARROW_PRESS] = Movement.CLIMBING_DOWN, }, [Movement.MOVING_RIGHT] = { [Actions.RIGHT_ARROW_PRESS] = Movement.MOVING_RIGHT, [Actions.RIGHT_ARROW_RELEASE] = Movement.STILL_RIGHT, [Actions.LEFT_ARROW_PRESS] = Movement.MOVING_LEFT, [Actions.UP_ARROW_PRESS] = Movement.CLIMBING_UP, [Actions.DOWN_ARROW_PRESS] = Movement.CLIMBING_DOWN, }, [Movement.CLIMBING_STILL] = { [Actions.RIGHT_ARROW_PRESS] = Movement.MOVING_RIGHT, [Actions.RIGHT_ARROW_RELEASE] = Movement.STILL_RIGHT, [Actions.LEFT_ARROW_PRESS] = Movement.MOVING_LEFT, [Actions.LEFT_ARROW_RELEASE] = Movement.STILL_LEFT, [Actions.UP_ARROW_PRESS] = Movement.CLIMBING_UP, [Actions.UP_ARROW_RELEASE] = Movement.CLIMBING_STILL, [Actions.DOWN_ARROW_PRESS] = Movement.CLIMBING_DOWN, [Actions.DOWN_ARROW_RELEASE] = Movement.CLIMBING_STILL, }, [Movement.CLIMBING_UP] = { [Actions.RIGHT_ARROW_PRESS] = Movement.MOVING_RIGHT, [Actions.LEFT_ARROW_PRESS] = Movement.MOVING_LEFT, [Actions.LEFT_ARROW_PRESS] = Movement.MOVING_LEFT, [Actions.LEFT_ARROW_RELEASE] = Movement.STILL_LEFT, [Actions.UP_ARROW_PRESS] = Movement.CLIMBING_UP, [Actions.UP_ARROW_RELEASE] = Movement.CLIMBING_STILL, [Actions.DOWN_ARROW_PRESS] = Movement.CLIMBING_DOWN, [Actions.DOWN_ARROW_RELEASE] = Movement.CLIMBING_STILL, }, [Movement.CLIMBING_DOWN] = { [Actions.RIGHT_ARROW_PRESS] = Movement.MOVING_RIGHT, [Actions.LEFT_ARROW_PRESS] = Movement.MOVING_LEFT, [Actions.UP_ARROW_PRESS] = Movement.CLIMBING_UP, [Actions.UP_ARROW_RELEASE] = Movement.CLIMBING_STILL, [Actions.DOWN_ARROW_PRESS] = Movement.CLIMBING_DOWN, [Actions.DOWN_ARROW_RELEASE] = Movement.CLIMBING_STILL, }, } function init(self) msg.post(".", "acquire_input_focus") self.direction = vmath.vector3(0,0,0) self.speed = 250 self.gravity = -5000 self.jump_velocity = 800 self.velocity = vmath.vector3(0, 0, 0) self.grounded = false self.jumped = false self.near_up_ladder = false self.correction = vmath.vector3() self.climbing = false self.is_moving = 0 self.left_pressed = false self.right_pressed = false self.up_pressed = false self.down_pressed = false self.jump_pressed = false self.have_amulet = false self.amulet_timer = 0 self.regenerating = false self.regen_timer = 0 self.blink_on_timer = 0 self.blink_off_timer = 0 self.current_lives = 3 self.current_score = 000 self.paused = false self.current_movement = Movement.STILL_RIGHT go.set_position(vmath.vector3(100,100,0.2)) msg.post("/banner#banner", "lives", {lives = self.current_lives}) end local function handleInput(self, input) local Transitions = transitions[self.current_movement] local next_movement = Transitions and Transitions[input] if next_movement then print("Transitioning from", self.current_movement, "to", next_movement, "on input", input) self.current_movement = next_movement if next_movement == Movement.MOVING_LEFT then sprite.play_flipbook("#sprite", hash("run_left")) msg.post("holding_amulet", "left") self.direction.x = -1 self.velocity.y = 0 end if next_movement == Movement.MOVING_RIGHT then sprite.play_flipbook("#sprite", hash("run_right")) msg.post("holding_amulet", "right") self.direction.x = 1 self.velocity.y = 0 end if next_movement == Movement.STILL_RIGHT then if not self.climbing then sprite.play_flipbook("#sprite", hash("still_right")) else next_movement = Movement.CLIMBING_STILL sprite.play_flipbook("#sprite", hash("still_climbing")) end self.direction.x = 0 end if next_movement == Movement.STILL_LEFT then if not self.climbing then sprite.play_flipbook("#sprite", hash("still_left")) else next_movement = Movement.CLIMBING_STILL sprite.play_flipbook("#sprite", hash("still_climbing")) end self.direction.x = 0 end if next_movement == Movement.CLIMBING_STILL then sprite.play_flipbook("#sprite", hash("still_climbing")) self.velocity.y = 0 self.climbing = true if self.right_pressed then handleInput(self, Actions.RIGHT_ARROW_PRESS) print("Actions.LEFT_RIGHT_PRESS from climbing_still") elseif self.left_pressed then handleInput(self, Actions.LEFT_ARROW_PRESS) print("Actions.LEFT_ARROW_PRESS from climbing_still") end end if next_movement == Movement.CLIMBING_UP then sprite.play_flipbook("#sprite", hash("climbing")) self.direction.x = 0 self.velocity.y = 150 self.climbing = true end if next_movement == Movement.CLIMBING_DOWN then sprite.play_flipbook("#sprite", hash("climbing")) self.direction.x = 0 self.velocity.y = -150 self.climbing = true end else print("No transition defined for", input, "in state", self.current_movement) end end function update(self, dt) if not self.paused then if self.amulet_timer > 0 then self.amulet_timer = self.amulet_timer - dt if self.amulet_timer < 0 then self.amulet_timer = 0 self.have_amulet = false msg.post("holding_amulet", "disable_sprite") end end if self.regen_timer > 0 then self.regen_timer = self.regen_timer - dt if self.regen_timer < 0 then self.regen_timer = 0 self.regenerating = false msg.post("#sprite", "enable") end if self.regenerating then if self.blink_on_timer > 0 then self.blink_on_timer = self.blink_on_timer - dt msg.post("#sprite", "enable") elseif self.blink_off_timer > 0 then self.blink_off_timer = self.blink_off_timer - dt msg.post("#sprite", "disable") else self.blink_on_timer = 0.25 self.blink_off_timer = 0.25 end end end self.correction = vmath.vector3() self.velocity.x = self.direction.x * self.speed local pos = go.get_position() pos = pos + self.velocity * dt if pos.x < 24 then pos.x = 24 elseif pos.x > 1030 then pos.x = 1030 end if pos.y < 0 then pos.y = 100 end local centre = vmath.vector3(pos.x, pos.y - 10, 0) local platform = pos + vmath.vector3(0, -36, 0) local ladder_up_left = pos + vmath.vector3(-24, -32, 0) local ladder_up_right = pos + vmath.vector3(24, -32, 0) local ladder_down_left = pos + vmath.vector3(-24, -42, 0) local ladder_down_right = pos + vmath.vector3(24, -42, 0) local platform_result = physics.raycast(centre, platform, { hash("platform") }) if platform_result then local point = platform_result.position - pos if not self.climbing then self.jumped = false self.grounded = true self.velocity.y = 0 if point.y > -36 then pos.y = pos.y + (point.y + 36) end end else self.grounded = false end local ladder_up_result1 = physics.raycast(ladder_up_right, ladder_up_left, { hash("ladder") }) local ladder_up_result2 = physics.raycast(ladder_up_left, ladder_up_right, { hash("ladder") }) if ladder_up_result1 then self.near_up_ladder = true elseif ladder_up_result2 then self.near_up_ladder = true else self.near_up_ladder = false end local ladder_down_result1 = physics.raycast(ladder_down_right, ladder_down_left, { hash("ladder") }) local ladder_down_result2 = physics.raycast(ladder_down_left, ladder_down_right, { hash("ladder") }) if ladder_down_result1 then self.near_down_ladder = true elseif ladder_down_result2 then self.near_down_ladder = true else self.near_down_ladder = false end if not (self.near_up_ladder or self.near_down_ladder)then if self.climbing then self.climbing = false if self.left_pressed then handleInput(self, Actions.LEFT_ARROW_PRESS) end if self.right_pressed then handleInput(self, Actions.RIGHT_ARROW_PRESS) end end end local debug_vars = { x = pos.x, y = pos.y, x_vel = self.velocity.x, y_vel = self.velocity.y, grounded = self.grounded, near_up_ladder = self.near_up_ladder, near_down_ladder = self.near_down_ladder, jumped = self.jumped, climbing = self.climbing, left_pressed = self.left_pressed, right_pressed = self.right_pressed, up_pressed = self.up_pressed, down_pressed = self.down_pressed, } msg.post("#debug", "set_vars", debug_vars) local score_vars = { score = self.current_score, } msg.post("/banner#score", "set_scores", score_vars) if not self.grounded and not ((self.near_up_ladder or self.near_down_ladder) and self.climbing) then self.velocity.y = self.velocity.y + self.gravity * dt end go.set_position(pos) end end function on_message(self, message_id, message, sender) if message_id == hash("contact_point_response") then if message.group == hash("curse") then if not self.regenerating then print("collision with curse") msg.post(message.other_id, "dying") end end if message.group == hash("amulet") then self.have_amulet = true self.amulet_timer = 5 msg.post("holding_amulet", "enable_sprite") print("collision with amulet") end end if message_id == hash("curse_dying_reply") then if message.dying == false then msg.post("/holding_amulet#holdingamulet", "disable_sprite") self.current_lives = self.current_lives - 1 msg.post("/banner#banner", "lives", {lives = self.current_lives}) if self.current_lives == 0 then local data = { score = self.current_score } msg.post("main:/controller#main", "NoMoreLives", data) else self.current_movement = Movement.MOVING_RIGHT handleInput(self, Actions.RIGHT_ARROW_RELEASE) go.set_position(vmath.vector3(100,100,0.2)) self.regenerating = true self.regen_timer = 3 end end end if message_id == hash("add 100 points") then self.current_score = self.current_score + 100 print(self.current_score) end if message_id == hash("pause") then self.paused = true end if message_id == hash("unpause") then self.paused = false end end function on_input(self, action_id, action) if not self.paused then if action_id == hash("left") then if action.pressed then self.left_pressed = true handleInput(self, Actions.LEFT_ARROW_PRESS) elseif action.released then self.left_pressed = false handleInput(self, Actions.LEFT_ARROW_RELEASE) end end if action_id == hash("right") then if action.pressed then self.right_pressed = true handleInput(self, Actions.RIGHT_ARROW_PRESS) elseif action.released then self.right_pressed = false handleInput(self, Actions.RIGHT_ARROW_RELEASE) end end if action_id == hash("jump") and action.pressed and not self.jumped and not self.climbing then self.velocity.y = self.jump_velocity print("Is this working?") self.jumped = true end if action_id == hash("climb_up") then if action.pressed then self.up_pressed = true handleInput(self, Actions.UP_ARROW_PRESS) elseif action.released then self.up_pressed = false handleInput(self, Actions.UP_ARROW_RELEASE) end end if action_id == hash("climb_down") then if action.pressed then self.down_pressed = true handleInput(self, Actions.DOWN_ARROW_PRESS) elseif action.released then self.down_pressed = false handleInput(self, Actions.DOWN_ARROW_RELEASE) end end end end @main/player.script"