aboutsummaryrefslogtreecommitdiff
path: root/src/objs/player.lua
blob: 78124868ae384f2efe469131adcb3b75360e1de2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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 COYOTE = 0.1

register_comp("Player", function(player)
  player.jump_input_timer = 0
  player.grounded_timer = 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.grounded_timer > 0 then
    if player.jump_input_timer > 0 then
      player.vy = -PLAYER_JUMP_FORCE
    end
  end
  if not is_input_pressed("Jump") and player.vy < -100 then
    player.vy = -100
  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
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, "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