461 lines
No EOL
15 KiB
Text
461 lines
No EOL
15 KiB
Text
local 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",
|
|
}
|
|
|
|
-- Transition table: [current_state][input] = next_state
|
|
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 -- gravity force
|
|
self.jump_velocity = 800-- how strong the jump is
|
|
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.paused = false
|
|
|
|
self.current_movement = Movement.STILL_RIGHT
|
|
self.current_level = "level1"
|
|
|
|
go.set_position(vmath.vector3(100,100,0.2))
|
|
end
|
|
|
|
function final(self)
|
|
-- Add finalization code here
|
|
-- Learn more: https://defold.com/manuals/script/
|
|
-- Remove this function if not needed
|
|
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
|
|
-- print ("You have " .. self.amulet_timer .. " seconds left of amulet")
|
|
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
|
|
-- print ("You have " .. self.regen_timer .. " seconds left of regeneration")
|
|
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
|
|
if pos.y < -20 then
|
|
pos.y = 100
|
|
pos.x = 100
|
|
msg.post("main:/controller#main", "LifeLost")
|
|
msg.post("main:/controller#main", "play dying sound")
|
|
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
|
|
|
|
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)
|
|
|
|
--msg.post("@render:", "draw_line", { start_point = centre, end_point = platform, color = vmath.vector4(1,0,0,1) })
|
|
--msg.post("@render:", "draw_line", { start_point = ladder_up_left, end_point = ladder_up_right, color = vmath.vector4(1,0,0,1) })
|
|
--msg.post("@render:", "draw_line", { start_point = ladder_up_right, end_point = ladder_up_left, color = vmath.vector4(1,0,0,1) })
|
|
--msg.post("@render:", "draw_line", { start_point = ladder_down_left, end_point = ladder_down_right, color = vmath.vector4(1,0,0,1) })
|
|
--msg.post("@render:", "draw_line", { start_point = ladder_down_right, end_point = ladder_down_left, color = vmath.vector4(1,0,0,1) })
|
|
|
|
local platform_result = physics.raycast(centre, platform, { hash("platform") })
|
|
if platform_result then
|
|
local point = platform_result.position - pos
|
|
-- msg.post("@render:", "draw_debug_text", { text = "Platform", position = vmath.vector3(20, 400, 0), color = vmath.vector4(1, 0, 0, 1) } )
|
|
-- msg.post("@render:", "draw_debug_text", { text = "X : " .. tostring(point.x), position = vmath.vector3(20, 380, 0), color = vmath.vector4(1, 0, 0, 1) } )
|
|
-- msg.post("@render:", "draw_debug_text", { text = "Y : " .. tostring(point.y), position = vmath.vector3(20, 360, 0), color = vmath.vector4(1, 0, 0, 1) } )
|
|
if not self.climbing then
|
|
self.jumped = false
|
|
self.speed = 250
|
|
self.grounded = true
|
|
self.velocity.y = 0
|
|
if point.y > -36 then
|
|
pos.y = pos.y + (point.y + 36)
|
|
end
|
|
--if self.climbing then
|
|
-- self.climbing = false
|
|
-- sprite.play_flipbook("#sprite", hash("still_left"))
|
|
--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)
|
|
|
|
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 fixed_update(self, dt)
|
|
|
|
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")
|
|
msg.post("main:/controller#main", "play amulet sound")
|
|
end
|
|
if message.group == hash("mummy") then
|
|
msg.post("main:/controller#main", "LevelCompleted")
|
|
--print("collision with mummy")
|
|
end
|
|
end
|
|
if message_id == hash("curse_dying_reply") then
|
|
if message.dying == false then
|
|
msg.post("/holding_amulet#holdingamulet", "disable_sprite")
|
|
msg.post("main:/controller#main", "LifeLost")
|
|
msg.post("main:/controller#main", "play dying sound")
|
|
--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("pause") then
|
|
self.paused = true
|
|
end
|
|
if message_id == hash("unpause") then
|
|
self.paused = false
|
|
end
|
|
if message_id == hash("level1") then
|
|
self.current_level = "level1"
|
|
elseif message_id == hash("level2") then
|
|
self.current_level = "level2"
|
|
elseif message_id == hash("level3") then
|
|
self.current_level = "level3"
|
|
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
|
|
msg.post("main:/controller#main", "play jump sound")
|
|
if self.current_level == "level2" or self.current_level == "level3" then
|
|
self.speed = 500
|
|
end
|
|
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
|
|
|
|
function on_reload(self)
|
|
-- Add reload-handling code here
|
|
-- Learn more: https://defold.com/manuals/hot-reload/
|
|
-- Remove this function if not needed
|
|
end |