diff options
| author | Elizabeth Hunt <elizabeth@simponic.xyz> | 2026-04-22 20:29:50 -0700 |
|---|---|---|
| committer | Elizabeth Hunt <elizabeth@simponic.xyz> | 2026-04-22 20:29:50 -0700 |
| commit | 24b0469237285a05d9ffc05d18e43cc5dcdef00f (patch) | |
| tree | 1c6924614b7d030c467919380d6c398d62efb602 | |
| parent | 078eca583eec21d317e931c84db8f084bef4305d (diff) | |
| download | dyl8-24b0469237285a05d9ffc05d18e43cc5dcdef00f.tar.gz dyl8-24b0469237285a05d9ffc05d18e43cc5dcdef00f.zip | |
Stuff
| -rw-r--r-- | collisions.lua | 6 | ||||
| -rw-r--r-- | dyl.lua | 85 | ||||
| -rw-r--r-- | dyl.p8 | 22 | ||||
| -rw-r--r-- | entity.lua | 91 | ||||
| -rw-r--r-- | math.lua | 4 | ||||
| -rw-r--r-- | util.lua | 11 |
6 files changed, 144 insertions, 75 deletions
diff --git a/collisions.lua b/collisions.lua index fb7aca7..feb138b 100644 --- a/collisions.lua +++ b/collisions.lua @@ -1,8 +1,8 @@ sw, sh = 8, 8 function is_colliding(a, b) - ax1, bx1 = a.pos.x, b.pos.x + ax1, bx1 = a.position.x, b.position.x ax2, bx2 = ax1 + sw, bx1 + sw - ay1, by1 = a.pos.y, b.pos.y + ay1, by1 = a.position.y, b.position.y ay2, by2 = ay1 + sh, by1 + sh return (ax1 < bx2 and ax2 > bx1 and ay1 < by2 and ay2 > by1) @@ -27,4 +27,4 @@ function run_collisions() ::continue:: end end -end
\ No newline at end of file +end @@ -1,18 +1,77 @@ +bow = entity() +function bow:transition_state() +end +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_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 +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_collidable() - :b_add_state("equipped", { + :b_add_state(States.Equipped, { animation={ pos_y = { sequence = { 82 }, dt = 1, reflect = vec2(false, true) }, - neg_y = { sequence = { 82 }, dt = 1 }, + 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_state(States.Equipped) + :build() player = entity() - :b_type(Entities.Player) +function player:transition_state() + if (self.velocity.x == 0 and self.velocity.y == 0) then + self:transition_to(States.Idle) + else + self:transition_to(States.Walk) + end +end +player:b_type(Entities.Player) + :b_line_of_sight(vec2(1, 0)) :b_render_order(0) :b_collidable() :b_position(vec2(30,30)) @@ -27,14 +86,15 @@ player = entity() }) :b_add_state(States.Walk, { animation = { - pos_x = { seq = { 2, 0 }, dt = 0.20 }, - neg_x = { seq = { 2, 0 }, dt = 0.20, reflect = vec2(true, false) }, - pos_y = { seq = { 4, 5 }, dt = 0.20 }, - neg_y = { seq = { 7, 8 }, dt = 0.20 } - } + 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_equipped({ sword }) + :build() _walk_speed = 35 -- powerup increase? function handle_input() @@ -59,11 +119,12 @@ function _update60() step_dt = step_t - old_step handle_input() - foreach(qsort(World, function(a, b) return a.equipped != nil end), function (e) e:update(step_dt) end) + qsort(World, function(a, b) return a.equipped != nil end) + foreach(World, function (e) e:update(step_dt) end) + run_collisions() end function _draw() - -- foreach(qsort(World, function (a, b) return a.render_order < b.render_order end), function (e) e:render() end) - foreach(World, function (e) e:render() end) -end
\ No newline at end of file + foreach(qsort(World, function(a, b) return a.render_order < b.render_order end), function (e) e:render() end) +end @@ -54,20 +54,20 @@ __gfx__ 00000000000000000008800000555500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -00040000000400000000007000000040000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -00504000005040000000075000030400000008e00005500005090000000900000000000000000000000000000000000000000000000000000000000000000000 -0050900005777900000075000000400000008e000055560000555550055555600000000000000000000000000000000000000000000000000000000000000000 -005040000500400000975000000404000058e0000006550000550000005500000000000000000000000000000000000000000000000000000000000000000000 -00504000005040000049000000400030006500000055500000500000005000000000000000000000000000000000000000000000000000000000000000000000 +00040000000400000000007000000070000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00504000005040000000075000000750000008e00005500005090000000900000000000000000000000000000000000000000000000000000000000000000000 +0050900005777900000075000000750000008e000055560000555550055555600000000000000000000000000000000000000000000000000000000000000000 +005040000500400000975000009750000058e0000006550000550000005500000000000000000000000000000000000000000000000000000000000000000000 +00504000005040000049000000490000006500000055500000500000005000000000000000000000000000000000000000000000000000000000000000000000 00040000000400000400000004000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000007000000040000000800000000000050000000600000000000000000000000000000000000000000000000000000000000000000000 -00000000000900000000075000030400000008e00006500000050000000500000000000000000000000000000000000000000000000000000000000000000000 -0049440000474400000075000000400000008e000055550000050000000500000000000000000000000000000000000000000000000000000000000000000000 -040000400407004000975000000404000058e0000055650000955000009550000000000000000000000000000000000000000000000000000000000000000000 -00555500005705000049000000400030006500000005050000055500000555000000000000000000000000000000000000000000000000000000000000000000 -00000000000550000400000004000000060000000000000000500000000500000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000004000000000000800000000000050000000600000000000000000000000000000000000000000000000000000000000000000000 +00000000000900000000000000490000000008e00006500000050000000500000000000000000000000000000000000000000000000000000000000000000000 +0049440000474400009000000097000000008e000055550000050000000500000000000000000000000000000000000000000000000000000000000000000000 +040000400407004004477770000570000058e0000055650000955000009550000000000000000000000000000000000000000000000000000000000000000000 +00555500005705000090000000005700006500000005050000055500000555000000000000000000000000000000000000000000000000000000000000000000 +00000000000550000000000000000570060000000000000000500000000500000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00056000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -1,21 +1,18 @@ Entities = { Player = 0, Sword = 1, - Enemy = 2 + Enemy = 2, + Bow = 3 } States = { Walk = "walk", - Idle = "idle" + Idle = "idle", + Equipped = "equipped", + Slashing = "slashing", + Drawing = "drawing", + Drawn = "drawn" } - -_id = 0 -function _next_id() - i = _id - _id += 1 - return i -end - Entity = {} Entity.__index = Entity function Entity:b_add_state(name, state) @@ -27,6 +24,7 @@ end function Entity:b_state(name) assert(self.states[name] != nil) self.state = name + self.state_stopwatch = 0 return self end function Entity:b_render_order(ord) @@ -53,49 +51,47 @@ function Entity:b_collidable() self.collision = true return self end +function Entity:b_line_of_sight(vec) + self.line_of_sight = vec2(vec) + return self +end +function Entity:build() + assert(self.transition_state) + + assert(self.position) + assert(self.state) + assert(self.state_stopwatch) +end function Entity:transition_to(state_name) - if self:transition(self.state, state_name) then + assert(self.states[state_name]) + if self.state ~= state_name then self.state = state_name self.state_stopwatch = 0 end + print(self.state) return self end -function Entity:transition(from, to) - if from == States.Walk and to == States.Idle or to == States.Idle and from == States.Walk then - return true - end - return false -end - function Entity:update(dt) - if self.state_stopwatch == nil then - self.state_stopwatch = 0 - end - self.state_stopwatch += dt self:integrate(dt) - self:update_sprite_position() self:update_line_of_sight() - if (self.velocity.x == 0 and self.velocity.x == self.velocity.y) then - self:transition_to(States.Idle) - else - self:transition_to(States.Walk) - end - + self:update_sprite_position() if (self.equipped != nil) then parent = self foreach(self.equipped, function (e) e:equipped_from(parent) end) end + + assert(self.transition_state) + self:transition_state() end function Entity:update_line_of_sight() nv = self.velocity:apply(normalize_scalar) if nv.y != 0 then self.line_of_sight = vec2(0, nv.y) - elseif nv.x != 0 then self.line_of_sight = vec2(nv.x, 0) - else self.line_of_sight = vec2(0, 0) end + elseif nv.x != 0 then self.line_of_sight = vec2(nv.x, 0) end end -- prevent cobblestoning during non-manhattan movement by "lagging" the sprite @@ -144,29 +140,24 @@ function Entity:update_sprite_position() end function Entity:integrate(dt) + self.state_stopwatch += dt if (self.velocity != nil) then self.position = self.position + (self.velocity * dt) end end -_equip_distance = 6 +_equipped_item_distance = 6 function Entity:equipped_from(parent) self.line_of_sight = vec2(parent.line_of_sight) - offset = (parent.line_of_sight * _equip_distance) + offset = (parent.line_of_sight * _equipped_item_distance) self.position = parent.position + offset self.sprite_position = parent.sprite_position + offset end -function _get_frame(anim, t) - len = #anim.seq - frames_passed = (t / anim.dt) - idx = flr(1 + (frames_passed % len)) - return anim.seq[idx] -end - -_animation_keys = {"neg", "", "pos"} +-- -1 0 1 +_animation_keys = {"neg", "pos", "pos"} function _get_animation_key(line_of_sight) n_line_of_sight = line_of_sight:apply(normalize_scalar) if n_line_of_sight.y ~= 0 then @@ -182,24 +173,32 @@ function Entity:render() if (animation == nil) then return end key = _get_animation_key(self.line_of_sight) animation = animation[key] or animation - assert(animation[key]) + assert(animation) + + frames_passed = flr(self.state_stopwatch / animation.dt) + frame = animation.sequence[1 + (frames_passed % (#animation.sequence))] + assert(frame) - frame = _get_frame(animation.sequence, self.state_t) - reflection = animation.reflection or vec2(false, false) + reflection = animation.reflect or vec2(false, false) spr( frame, - entity.sprite_position.x, entity.sprite_position.y, + self.sprite_position.x, self.sprite_position.y, 1, 1, reflection.x, reflection.y ) end +_id = 1 +function _next_id() + i = _id + _id += 1 + return i +end function entity() id = _next_id() World.add(setmetatable( { id = id, - position = vec2(0,0), velocity = vec2(0,0), collision = false }, Entity @@ -8,7 +8,7 @@ Vec2.__mul = function(a, b) return a.x * b.x + a.y * b.y end Vec2.__div = function(a, b) return vec2(a.x / b.x, a.y / b.y) end -Vec2.__tostring = function(a) return "(" .. a.x .. "," .. a.y .. ")" end +Vec2.__tostring = function(a) return "(" .. fmt(a.x) .. "," .. fmt(a.y) .. ")" end function Vec2:magnitude() return sqrt(self.x * self.x + self.y * self.y) @@ -33,4 +33,4 @@ function normalize_scalar(x) if x == 0 then return 0 end if x < 0 then return -1 end return 1 -end
\ No newline at end of file +end @@ -49,4 +49,13 @@ function filter(a, pred) end end return filtered -end
\ No newline at end of file +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" +end |
