aboutsummaryrefslogtreecommitdiff
path: root/src/objs/player.lua
blob: 66ea3796d771b7f5d6cf0be83246efafc8998bac (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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, "Speck_System")
  ent.speck_sys.interval = 0.05

  ent.speck_sys.spawn_amount_max = 10

  ent.speck_sys.lifetime_max = 0.6
  ent.speck_sys.lifetime_min = 0.3

  ent.speck_sys.initial_velx = 100
  ent.speck_sys.initial_vely = 0
  ent.speck_sys.spread = 360

  ent.speck_sys.forcey = 1000
  ent.speck_sys.bounce = true

  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