local PLAYER_SPEED = 100 local PLAYER_DASH_SPEED = 500 local PLAYER_ACCEL = 30 local PLAYER_JUMP_FORCE = 350 local PLAYER_DASH_TIMER = 0.15 local PLAYER_DASH_COOLDOWN = 0.5 local PLAYER_MAX_JUMPS = 2 local COYOTE = 0.1 register_comp("Player", function(player) player.jump_input_timer = 0 player.grounded_timer = 0 player.jumps = 0 end) local function player_normal_state_init(state) state.dash_cooldown = 0 end local function player_normal_state_update(player, state, dt) local inputx = bton(is_input_pressed("Right")) - bton(is_input_pressed("Left")) player.vx = dlerp(player.vx, inputx * PLAYER_SPEED, PLAYER_ACCEL * dt) player.vy = math.min(player.vy + GRAVITY * dt, TERMINAL_VELOCITY) if inputx ~= 0 then player.sprite:set_tag("run") elseif not player.box:touching_down() then if player.vy < -100 then player.sprite:set_tag("jump_up") elseif player.vy > 100 then player.sprite:set_tag("jump_down") else player.sprite:set_tag("jump_trans") end else player.sprite:set_tag("idle") end if player.jumps > 0 then if player.jump_input_timer > 0 then player.grounded_timer = 0 player.jump_input_timer = 0 player.vy = -PLAYER_JUMP_FORCE player.jumps = player.jumps - 1 new_speck_entity(player.x, player.y, "res/speck/test.speck.lua") player.camera:shake(12, 0.1, 90) end end if not is_input_pressed("Jump") and player.vy < -100 then player.vy = -100 end if player.grounded_timer > 0 then player.jumps = PLAYER_MAX_JUMPS else -- going off the ledge removes a jump if player.jumps == PLAYER_MAX_JUMPS then player.jumps = player.jumps - 1 end end if state.dash_cooldown <= 0 and is_input_just_pressed("Dash") then set_state(player, "Dash") state.dash_cooldown = PLAYER_DASH_COOLDOWN end state.dash_cooldown = state.dash_cooldown - dt end local function player_dash_state_enter(player, state) local inputx = bton(is_input_pressed("Right")) - bton(is_input_pressed("Left")) if inputx == 0 then inputx = 1 --TODO: Change this to be the direction that the player is facing end player.vx = PLAYER_DASH_SPEED * inputx player.vy = 0 state.dash_timer = PLAYER_DASH_TIMER end local function player_dash_state_update(player, state, dt) state.dash_timer = state.dash_timer - dt if state.dash_timer <= 0 then set_state(player, "Normal") end end local function player_dash_state_exit(player, state, entering) player.vx = player.vx / 2 end function player_update_sys(player, dt) if player.vx ~= 0 then player.scalex = sign(player.vx) end player.jump_input_timer = player.jump_input_timer - dt if is_input_just_pressed("Jump") then player.jump_input_timer = COYOTE end player.grounded_timer = player.grounded_timer - dt if player.box:touching_down() then player.grounded_timer = COYOTE end if love.keyboard.isDown("k") then export_speck_sys(player.speck_sys, "test.speck.lua") end end function new_player(x, y) local ent = new_entity() add_comp(ent, "Player") add_comp(ent, "Body", x, y, 8, 14, { offsetx = -4, offsety = -6, layers = {}, mask = { "Hard" }, }) add_comp(ent, "Camera") set_active_camera(ent.camera) add_comp(ent, "Sprite", "res/img/player.ase", { offsetx = 0.5, offsety = 0.5, }) add_comp(ent, "State_Machine", "Normal", { Normal = { init = player_normal_state_init, update = player_normal_state_update, }, Dash = { enter = player_dash_state_enter, update = player_dash_state_update, exit = player_dash_state_exit, }, }) return ent end