summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dyl.lua248
-rw-r--r--dyl.p826
-rw-r--r--entity.lua24
-rw-r--r--util.lua116
-rw-r--r--world.lua27
5 files changed, 297 insertions, 144 deletions
diff --git a/dyl.lua b/dyl.lua
index 6c2a012..6a337cd 100644
--- a/dyl.lua
+++ b/dyl.lua
@@ -1,64 +1,139 @@
+_slashing_timer_sec = 0.12
+function spawn_slashing_particle(e)
+ slash_animation = entity()
+ _slash_animation_distance = 3
+ function slash_animation:transition_state()
+ -- TODO: Find a better place to put this lol. This has nothing to do with state
+ -- transitions
+ slash_animation:equipped_from(e, _slash_animation_distance)
+ end
+ return slash_animation:b_type(Entities.Enemy)
+ :b_line_of_sight(e.line_of_sight)
+ :b_position(vec2(e.position))
+ :b_sprite_position(vec2(position))
+ :b_render_order(-1)
+ :b_live_for(_slashing_timer_sec)
+ :b_add_state(
+ States.Active, {
+ animation = {
+ pos_y = { sequence = { 115, 116, 117 }, dt = _slashing_timer_sec / 3, reflect = vec2(true, true) },
+ neg_y = { sequence = { 115, 116, 117 }, dt = _slashing_timer_sec / 3 },
+ pos_x = { sequence = { 112, 113, 114 }, dt = _slashing_timer_sec / 3 },
+ neg_x = { sequence = { 112, 113, 114 }, dt = _slashing_timer_sec / 3, reflect = vec2(true, false) }
+ }
+ }
+ )
+ :b_state(States.Active)
+ :build()
+end
+
+enemy = entity()
+function enemy:transition_state()
+end
+enemy:b_type(Entities.Enemy)
+ :b_position(vec2(30, 40))
+ :b_sprite_position(vec2(30, 30))
+ :b_line_of_sight(vec2(1, 0))
+ :b_render_order(1)
+ :b_collidable()
+ :b_add_state(
+ States.Idle, {
+ animation = {
+ pos_y = { sequence = { 32, 33 }, dt = 1 },
+ neg_y = { sequence = { 32, 33 }, dt = 1 },
+ pos_x = { sequence = { 32, 33 }, dt = 1 },
+ neg_x = { sequence = { 32, 33 }, dt = 1, reflect = vec2(true, false) }
+ }
+ }
+ )
+ :b_add_state(
+ States.Walk, {
+ animation = {
+ pos_x = { sequence = { 32, 34 }, dt = 0.20 },
+ neg_x = { sequence = { 32, 34 }, dt = 0.20, reflect = vec2(true, false) },
+ pos_y = { sequence = { 32, 34 }, dt = 0.20 },
+ neg_y = { sequence = { 32, 34 }, dt = 0.20 }
+ }
+ }
+ )
+ :b_state(States.Walk)
+ :b_equipped({ sword })
+ :build()
+
+
bow = entity()
function bow:transition_state()
end
-bow
- :b_type(Entities.Bow)
+bow:b_type(Entities.Bow)
:b_position(vec2(0, 0))
:b_sprite_position(vec2(0, 0))
:b_line_of_sight(vec2(1, 0))
:b_render_order(1)
:b_collidable()
- :b_add_state(States.Equipped, {
- animation={
- pos_y = { sequence = { 96 }, dt = 1, reflect = vec2(false, true) },
- neg_y = { sequence = { 96 }, dt = 1 },
- pos_x = { sequence = { 80 }, dt = 1 },
- neg_x = { sequence = { 80 }, dt = 1, reflect = vec2(true, false) }
- }
- })
- :b_add_state(States.Drawn, {
- animation={
- pos_y = { sequence = { 81 }, dt = 1, reflect = vec2(false, true) },
- neg_y = { sequence = { 81 }, dt = 1 },
- pos_x = { sequence = { 81 }, dt = 1 },
- neg_x = { sequence = { 81 }, dt = 1, reflect = vec2(true, false) }
- }
- })
- :b_add_state(States.Drawing, {
- animation = bow.states[States.Equipped]
- })
+ :b_add_state(
+ States.Equipped, {
+ animation = {
+ pos_y = { sequence = { 96 }, dt = 1, reflect = vec2(false, true) },
+ neg_y = { sequence = { 96 }, dt = 1 },
+ pos_x = { sequence = { 80 }, dt = 1 },
+ neg_x = { sequence = { 80 }, dt = 1, reflect = vec2(true, false) }
+ }
+ }
+ )
+ :b_add_state(
+ States.Drawn, {
+ animation = {
+ pos_y = { sequence = { 81 }, dt = 1, reflect = vec2(false, true) },
+ neg_y = { sequence = { 81 }, dt = 1 },
+ pos_x = { sequence = { 81 }, dt = 1 },
+ neg_x = { sequence = { 81 }, dt = 1, reflect = vec2(true, false) }
+ }
+ }
+ )
+ :b_add_state(
+ States.Drawing, {
+ animation = bow.states[States.Equipped]
+ }
+ )
:b_state(States.Equipped)
:build()
sword = entity()
-_slashing_timer_ms = 500
function sword:transition_state()
- if(btn(5)) then self:transition_to(States.Slashing)
- elseif self.state == States.Slashing and self.state_stopwatch > _slashing_timer_ms then self:transition_to(States.Equipped) end
+ if button_just_pressed(5) and self.state == States.Equipped then
+ self:transition_to(States.Slashing)
+ spawn_slashing_particle(self)
+ elseif self.state == States.Slashing and self.state_stopwatch > _slashing_timer_sec then
+ self:transition_to(States.Equipped)
+ end
end
sword
:b_type(Entities.Sword)
:b_line_of_sight(vec2(1, 0))
:b_position(vec2(0, 0))
:b_sprite_position(vec2(0, 0))
- :b_render_order(1)
+ :b_render_order(0)
:b_collidable()
- :b_add_state(States.Equipped, {
- animation={
- pos_y = { sequence = { 82 }, dt = 1, reflect = vec2(false, true) },
- neg_y = { sequence = { 82 }, dt = 1, reflect = vec2(true, false)},
- pos_x = { sequence = { 82 }, dt = 1 },
- neg_x = { sequence = { 82 }, dt = 1, reflect = vec2(true, false) }
- }
- })
- :b_add_state(States.Slashing, {
- animation={
- pos_y = { sequence = { 82, 82+16 }, dt = 1, reflect = vec2(false, true) },
- neg_y = { sequence = { 82, 82+16 }, dt = 1, reflect = vec2(true, false)},
- pos_x = { sequence = { 82, 82+16 }, dt = 1 },
- neg_x = { sequence = { 82, 82+16 }, dt = 1, reflect = vec2(true, false) }
- }
- })
+ :b_add_state(
+ States.Equipped, {
+ animation = {
+ pos_y = { sequence = { 99 }, dt = 1, reflect = vec2(false, true) },
+ neg_y = { sequence = { 99 }, dt = 1, reflect = vec2(true, false) },
+ pos_x = { sequence = { 98 }, dt = 1 },
+ neg_x = { sequence = { 98 }, dt = 1, reflect = vec2(true, false) }
+ }
+ }
+ )
+ :b_add_state(
+ States.Slashing, {
+ animation = {
+ pos_y = { sequence = { 82, 98 }, dt = _slashing_timer_sec / 2, reflect = vec2(false, true) },
+ neg_y = { sequence = { 82, 98 }, dt = _slashing_timer_sec / 2, reflect = vec2(true, false) },
+ pos_x = { sequence = { 82, 99 }, dt = _slashing_timer_sec / 2, reflect = vec2(false, false)},
+ neg_x = { sequence = { 82, 99 }, dt = _slashing_timer_sec / 2, reflect = vec2(true, false) }
+ }
+ }
+ )
:b_state(States.Equipped)
:build()
@@ -70,61 +145,74 @@ function player:transition_state()
self:transition_to(States.Walk)
end
end
-player:b_type(Entities.Player)
+player
+ :b_type(Entities.Player)
:b_line_of_sight(vec2(1, 0))
- :b_render_order(0)
+ :b_render_order(2)
:b_collidable()
- :b_position(vec2(30,30))
- :b_sprite_position(vec2(30,30))
- :b_add_state(States.Idle, {
- animation = {
- pos_y = { sequence = { 3, 19 }, dt = 1 },
- neg_y = { sequence = { 6, 22 }, dt = 1 },
- pos_x = { sequence = { 0, 1 }, dt = 1 },
- neg_x = { sequence = { 0, 1 }, dt = 1, reflect = vec2(true, false) }
- }
- })
- :b_add_state(States.Walk, {
- animation = {
- pos_x = { sequence = { 2, 0 }, dt = 0.20 },
- neg_x = { sequence = { 2, 0 }, dt = 0.20, reflect = vec2(true, false) },
- pos_y = { sequence = { 4, 5 }, dt = 0.20 },
- neg_y = { sequence = { 7, 8 }, dt = 0.20 }
- }
- })
- :b_state("idle")
+ :b_position(vec2(30, 30))
+ :b_sprite_position(vec2(30, 30))
+ :b_add_state(
+ States.Idle, {
+ animation = {
+ pos_y = { sequence = { 3, 19 }, dt = 1 },
+ neg_y = { sequence = { 6, 22 }, dt = 1 },
+ pos_x = { sequence = { 0, 1 }, dt = 1 },
+ neg_x = { sequence = { 0, 1 }, dt = 1, reflect = vec2(true, false) }
+ }
+ }
+ )
+ :b_add_state(
+ States.Walk, {
+ animation = {
+ pos_x = { sequence = { 2, 0 }, dt = 0.20 },
+ neg_x = { sequence = { 2, 0 }, dt = 0.20, reflect = vec2(true, false) },
+ pos_y = { sequence = { 4, 5 }, dt = 0.20 },
+ neg_y = { sequence = { 7, 8 }, dt = 0.20 }
+ }
+ }
+ )
+ :b_state(States.Idle)
:b_equipped({ sword })
:build()
_walk_speed = 35 -- powerup increase?
function handle_input()
- dpos = vec2(0, 0)
- if btn(0) then dpos.x -= 1 end
- if btn(1) then dpos.x += 1 end
- if btn(3) then dpos.y += 1 end
- if btn(2) then dpos.y -= 1 end
+ dpos = vec2(0, 0)
+ if btn(0) then dpos.x -= 1 end
+ if btn(1) then dpos.x += 1 end
+ if btn(3) then dpos.y += 1 end
+ if btn(2) then dpos.y -= 1 end
- player.velocity = dpos:normal() * _walk_speed
+ player.velocity = dpos:normal() * _walk_speed
end
function _init()
end
-step_t = time()
-function _update60()
- cls(0) -- clear here in case we want to print to screen outside of _draw
+_step_t = time()
+function _update()
+ -- clear here in case we want to print to screen outside of _draw
+ cls(0)
+
+ old_step = _step_t
+ _step_t = time()
+ step_dt = _step_t - old_step
- old_step = step_t
- step_t = time()
- step_dt = step_t - old_step
+ foreach(update_hooks, function(f) f(step_dt) end)
- handle_input()
- qsort(World, function(a, b) return a.equipped != nil end)
- foreach(World, function (e) e:update(step_dt) end)
+ handle_input()
+ World.foreach(function(e) if (not e.equipped) then e:update(step_dt) end end)
+ World.foreach(function(e) if (e.equipped) then e:update(step_dt) end end)
- run_collisions()
+ run_collisions()
+
+ World.cull_the_dead()
end
function _draw()
- foreach(qsort(World, function(a, b) return a.render_order < b.render_order end), function (e) e:render() end)
-end
+ qsort(World, function(a, b) return b.render_order < a.render_order end)
+ World.foreach(function(e)
+ e:render()
+ end)
+end \ No newline at end of file
diff --git a/dyl.p8 b/dyl.p8
index 0367033..423b331 100644
--- a/dyl.p8
+++ b/dyl.p8
@@ -61,21 +61,21 @@ __gfx__
00504000005040000049000000490000006500000055500000500000005000000000000000000000000000000000000000000000000000000000000000000000
00040000000400000400000004000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000000000004000000000000800000000000050000000600000000000000000000000000000000000000000000000000000000000000000000
-00000000000900000000000000490000000008e00006500000050000000500000000000000000000000000000000000000000000000000000000000000000000
-0049440000474400009000000097000000008e000055550000050000000500000000000000000000000000000000000000000000000000000000000000000000
-040000400407004004477770000570000058e0000055650000955000009550000000000000000000000000000000000000000000000000000000000000000000
-00555500005705000090000000005700006500000005050000055500000555000000000000000000000000000000000000000000000000000000000000000000
-00000000000550000000000000000570060000000000000000500000000500000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000070000000000000000000800000000000050000000600000000000000000000000000000000000000000000000000000000000000000000
+00000000000900000070000000000000000008e00006500000050000000500000000000000000000000000000000000000000000000000000000000000000000
+0049440000474400007000000000000000008e000055550000050000000500000000000000000000000000000000000000000000000000000000000000000000
+040000400407004009490000000900000058e0000055650000955000009550000000000000000000000000000000000000000000000000000000000000000000
+00555500005705000040000000447777006500000005050000055500000555000000000000000000000000000000000000000000000000000000000000000000
+00000000000550000000000000090000060000000000000000500000000500000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-00056000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000005650600000000000000000000005006500000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000560000000000000000005606056600650000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000060000000000000000650005665000660000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000650000005605000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-00000000000000000056600000000000000006000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00056000000600000000000000000000006000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000005650600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000560000000000005600000005665000000066000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000060000000000050000000066506060000056000000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000650000005605000000000005000000000005600000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000056600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000600000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/entity.lua b/entity.lua
index 945b787..56dcd74 100644
--- a/entity.lua
+++ b/entity.lua
@@ -2,11 +2,13 @@ Entities = {
Player = 0,
Sword = 1,
Enemy = 2,
- Bow = 3
+ Bow = 3,
+ Particle = 4
}
States = {
Walk = "walk",
Idle = "idle",
+ Active = "active",
Equipped = "equipped",
Slashing = "slashing",
Drawing = "drawing",
@@ -51,6 +53,10 @@ function Entity:b_collidable()
self.collision = true
return self
end
+function Entity:b_live_for(t)
+ self.life_time = t
+ return self
+end
function Entity:b_line_of_sight(vec)
self.line_of_sight = vec2(vec)
return self
@@ -69,10 +75,13 @@ function Entity:transition_to(state_name)
self.state = state_name
self.state_stopwatch = 0
end
- print(self.state)
return self
end
+function Entity:kill()
+ self.life_time = -1
+end
+
function Entity:update(dt)
self:integrate(dt)
@@ -86,6 +95,10 @@ function Entity:update(dt)
assert(self.transition_state)
self:transition_state()
+
+ if self.life_time ~= nil then
+ self.life_time -= dt
+ end
end
function Entity:update_line_of_sight()
@@ -147,10 +160,11 @@ function Entity:integrate(dt)
end
_equipped_item_distance = 6
-function Entity:equipped_from(parent)
+function Entity:equipped_from(parent, dist)
+ dist = dist or _equipped_item_distance
self.line_of_sight = vec2(parent.line_of_sight)
- offset = (parent.line_of_sight * _equipped_item_distance)
+ offset = (parent.line_of_sight * dist)
self.position = parent.position + offset
self.sprite_position = parent.sprite_position + offset
@@ -203,5 +217,5 @@ function entity()
collision = false
}, Entity
))
- return World[id]
+ return World.get(id)
end
diff --git a/util.lua b/util.lua
index 157d7ad..b73838a 100644
--- a/util.lua
+++ b/util.lua
@@ -1,49 +1,51 @@
+update_hooks = {}
+
-- https://pico-8.fandom.com/wiki/Qsort
-function qsort(a,c,l,r)
- c,l,r=c or function(a,b) return a<b end,l or 1,r or #a
- if l<r then
- if c(a[r],a[l]) then
- a[l],a[r]=a[r],a[l]
- end
- local lp,k,rp,p,q=l+1,l+1,r-1,a[l],a[r]
- while k<=rp do
- local swaplp=c(a[k],p)
- -- "if a or b then else"
- -- saves a token versus
- -- "if not (a or b) then"
- if swaplp or c(a[k],q) then
- else
- while c(q,a[rp]) and k<rp do
- rp-=1
- end
- a[k],a[rp],swaplp=a[rp],a[k],c(a[rp],p)
- rp-=1
- end
- if swaplp then
- a[k],a[lp]=a[lp],a[k]
- lp+=1
- end
- k+=1
- end
- lp-=1
- rp+=1
- -- sometimes lp==rp, so
- -- these two lines *must*
- -- occur in sequence;
- -- don't combine them to
- -- save a token!
- a[l],a[lp]=a[lp],a[l]
- a[r],a[rp]=a[rp],a[r]
- qsort(a,c,l,lp-1 )
- qsort(a,c, lp+1,rp-1 )
- qsort(a,c, rp+1,r)
- end
+function qsort(a, c, l, r)
+ c, l, r = c or function(a, b) return a < b end, l or 1, r or #a
+ if l < r then
+ if c(a[r], a[l]) then
+ a[l], a[r] = a[r], a[l]
+ end
+ local lp, k, rp, p, q = l + 1, l + 1, r - 1, a[l], a[r]
+ while k <= rp do
+ local swaplp = c(a[k], p)
+ -- "if a or b then else"
+ -- saves a token versus
+ -- "if not (a or b) then"
+ if swaplp or c(a[k], q) then
+ else
+ while c(q, a[rp]) and k < rp do
+ rp -= 1
+ end
+ a[k], a[rp], swaplp = a[rp], a[k], c(a[rp], p)
+ rp -= 1
+ end
+ if swaplp then
+ a[k], a[lp] = a[lp], a[k]
+ lp += 1
+ end
+ k += 1
+ end
+ lp -= 1
+ rp += 1
+ -- sometimes lp==rp, so
+ -- these two lines *must*
+ -- occur in sequence;
+ -- don't combine them to
+ -- save a token!
+ a[l], a[lp] = a[lp], a[l]
+ a[r], a[rp] = a[rp], a[r]
+ qsort(a, c, l, lp - 1)
+ qsort(a, c, lp + 1, rp - 1)
+ qsort(a, c, rp + 1, r)
+ end
return a
end
function filter(a, pred)
filtered = {}
- for k,v in ipairs(a) do
+ for k, v in ipairs(a) do
if pred(v) then
filtered[k] = v
end
@@ -53,9 +55,33 @@ end
function fmt(x)
t = type(x)
- if t == "number" then return "" .. x
- elseif t == "string" then return x
- elseif t == "boolean" and x then return "true"
- elseif t == "boolean" and not x then return "false" end
- return "NA"
+ if t == "number" then
+ return "" .. x
+ elseif t == "string" then
+ return x
+ elseif t == "boolean" and x then
+ return "true"
+ elseif t == "boolean" and not x then
+ return "false"
+ end
+ return "_unknown_"
+end
+
+_button_states = {}
+function _update_button_states(_dt)
+ for button = 0, 20 do
+ if btn(button) then
+ if _button_states[button] == "up" then
+ _button_states[button] = "just_pressed"
+ else
+ _button_states[button] = "held"
+ end
+ else
+ _button_states[button] = "up"
+ end
+ end
end
+update_hooks[1] = _update_button_states
+function button_just_pressed(id)
+ return _button_states[id] == "just_pressed"
+end \ No newline at end of file
diff --git a/world.lua b/world.lua
index fd793a4..cb322df 100644
--- a/world.lua
+++ b/world.lua
@@ -1,5 +1,30 @@
+_World = {}
World = {}
+
function World.add(entity)
- World[entity.id] = entity
+ _World[entity.id] = entity
return World
+end
+
+function World.foreach(f)
+ for id, entity in pairs(_World) do
+ f(entity)
+ end
+end
+
+function World.cull_the_dead()
+ to_reap = {}
+ for id, e in pairs(_World) do
+ if (e.life_time ~= nil and e.life_time <= 0) then
+ to_reap[id] = e
+ end
+ end
+ for id, e in pairs(to_reap) do
+ _World[id] = nil
+ end
+ return _World
+end
+
+function World.get(id)
+ return _World[id]
end \ No newline at end of file