From 2a61e8b5d6aba26cc6ab44c602bab867ac2bb9ad Mon Sep 17 00:00:00 2001 From: Kistaro Windrider Date: Sun, 15 Oct 2023 21:09:12 -0700 Subject: [PATCH] partial conversion to CSV-based levels, does not run yet --- updatedshmup.p8 | 259 ++++++++++++++++++++++++++---------------------- 1 file changed, 140 insertions(+), 119 deletions(-) diff --git a/updatedshmup.p8 b/updatedshmup.p8 index 27ad9d0..9a6c07f 100644 --- a/updatedshmup.p8 +++ b/updatedshmup.p8 @@ -26,22 +26,19 @@ end -- ret is definitely not nil -- before calling setmetatable. -- use to initialize mutables. +-- +-- if there was a previous new, +-- it is invoked on the new +-- object *after* more, because +-- this works better with the +-- `more` impls i use. function mknew(tt, more) - local mt = {__index=tt} - -- check "more" only once ever - if more then - tt.new = function(ret) - if (not ret) ret = {} - more(ret) - setmetatable(ret, mt) - return ret - end - else - tt.new=function(ret) - if (not ret) ret = {} - setmetatable(ret, mt) - return ret - end + local mt,oldnew = {__index=tt},tt.new + tt.new=function(ret) + if(not ret) ret = {} + if(more) more(ret) + if(oldnew) oldnew(ret) + setmetatable(ret, mt) end end @@ -672,34 +669,29 @@ blocky = frownie.new{ } mknew(blocky) -function spawn_spewy_at(x, y) - local spewy = frownie.new{ - x = x, - y = y, - sprite = 26, - power = -20, - hurt = { - x_off = 0, - y_off = 1, - width = 8, - height = 5 - }, - - hp = 1, - maxpower = 70, - generator = 0.5, - main_gun = protron_gun.new{enemy=true}, - fire_off_x = 4, - fire_off_y = 7, - grab_butts = function() - local butts = frownie.grab_butts() - butts[5] = 1 - return butts - end, - } - eships:push_back(spewy) - return spewy -end +spewy = frownie.new{ + sprite=26, + power=-20, + hurt = { + x_off=0, + y_off=1, + width=8, + height=5 + }, + hp=1, + maxpower=70, + generator=0.5, + fire_off_x=4, + fire_off_y = 7, + grab_butts=function() + local butts=frownie.grab_butts() + butts[5]=1 + return butts + end +} +mknew(spewy, function(ship) + ship.main_gun=ship.main_gun or protron_gun.new{enemy=true} +end} chasey = ship_m.new{ sprite = 5, @@ -724,59 +716,47 @@ chasey = ship_m.new{ thrust = 0.2, drag = 0.075, slip = true, +} +mknew(chasey, function(ship) + ship.main_gun=ship.main_gun or zap_gun.new{enemy=true} +end) +function chasey:grab_butts() + local butts = {[0]=0,0,0,0,0,0} + if (self.x < primary_ship.x) butts[1] = 1 + if (self.x > primary_ship.x) butts[0] = 1 + if (self.x - 16 < primary_ship.x and self.x + 16 > primary_ship.x) butts[5] = 1 + return butts +end + +xl_chasey=chasey.new{ + size=2, + maxspd=1.25, + hurt = { + x_off = 2, + y_off = 4, + width = 12, + height = 10 + }, + hp = 20, + shield = 5, + boss = true, + slip = false, + main_gun = zap_gun.new{enemy=true}, grab_butts = function(self) - local butts = {0,0,0,0,0} - butts[0] = 0 - if (self.x < primary_ship.x) butts[1] = 1 - if (self.x > primary_ship.x) butts[0] = 1 - if (self.x - 16 < primary_ship.x and self.x + 16 > primary_ship.x) butts[5] = 1 + local butts = chasey.grab_butts(self) + if (self.y < 4) butts[3] = 1 return butts end, + draw = function(self) + if(self.fx_pal) pal(self.fx_pal) + sspr(40, 0, 8, 8, self.x, self.y, 16, 16) + pal() + end, } -mknew(chasey) - -function spawn_chasey_at(x, y) - local c = chasey.new{ - x = x, - y = y, - main_gun = zap_gun.new{enemy=true}, - } - eships:push_back(c) - return c -end - -function spawn_xl_chasey_at(x, y) - local c = chasey.new{ - x = x, - y = y, - size = 2, - maxspd = 1.25, - hurt = { - x_off = 2, - y_off = 4, - width = 12, - height = 10 - }, - hp = 20, - shield = 5, - boss = true, - slip = false, - main_gun = zap_gun.new{enemy=true}, - grab_butts = function(self) - local butts = chasey.grab_butts(self) - if (self.y < 4) butts[3] = 1 - return butts - end, - draw = function(self) - if(self.fx_pal) pal(self.fx_pal) - sspr(40, 0, 8, 8, self.x, self.y, 16, 16) - pal() - end, - } - eships:push_back(c) - return c -end +mknew(xl_chasey, function(ship) + ship.main_gun=ship.main_gun or zap_gun.new{enemy=true} +end) -->8 -- collisions @@ -914,35 +894,7 @@ end -->8 -- example level -function std_spawn(tnm, n, blocking, goodie) - -- TODO: implement - -- look up enemy type from tnm - -- spawn n of them at random positions, - -- see spawn_rnd_x. - -- if blocking, patch the blocking logic in. - -- if they drop a goodie, find the goodie, - -- then patch the bonus logic in. -end --- to implement: repeat(times, interval, f, ...) --- once on this frame, then times-1 times after that spaced interval --- frames apart, f(...). schedule this like the one-off written in --- example_level. - --- then convert sample_level to csv. --- spawn_spec_gun_at and spawn_main_gun_at will need parsed forms. --- the boss also needs to be reachable, but one-off is fine. --- each row of level csv is offset,event,event-args... --- where offset,eol is a special case. - -function spawn_rnd_x(typ) - s = typ.new{ - x = rnd(104), - y = -(typ.size * 8 - 1) - } - eships:push_back(s) - return s -end function spawn_blocking_rnd_x(typ) freeze += 1 @@ -1048,6 +1000,75 @@ function spawn_blocking_boss_chasey() return c end +spawns = { + chasey = chasey, + frownie = frownie, + blocky = blocky, + spewy = spewy, + spewy_xl=spewy_xl, + -- TODO: populate this +} +function std_spawn(tnm, n, blocking, goodie,altspr) + local typ = spawns[tnm] + assert(typ, tostr(tnm).." not a spawnable") + for i=1,(n or 1) do + spawn_rnd(typ, blocking, goodie,altspr) + end +end + +-- blocking: 1 or 0 +function spawn_rnd(typ, blocking, goodie,altspr) + freeze += blocking + s = typ.new{ + x = rnd(104), + y = -(typ.size * 8 - 1) + ice=blocking + die=function(self) + freeze -= self.ice + self.ice=0 + typ.die(self) + spawn_goodie(goodie, self.x, self.y, self.size) + end + } + if (altspr) s.spr = altspr + eships:push_back(s) + return s +end + +-- TODO: spawn_goodie compatible versions of gun drops +-- TODO: goodie table +function spawn_goodie(goodie_name, x, y, sz) + if (not goodie_name or #goodie_name == 0) return + local sh = sz and sz/2 or 0 + goodies[goodie_name].new{}:spawn_at(x+sh,y+sh) +end + +-- TODO: populate level_events + +-- to implement: multi(times, interval, f, ...) +-- once on this frame, then times-1 times after that spaced interval +-- frames apart, f(...). schedule this like the one-off written in +-- example_level. +function multi(times, interval, fnm, ...) + local f,irm = level_events[fnm],interval + fnm(...) + events:push_back{move=function() + irm-=1 + if irm <= 0 then + irm=interval + times-=1 + fnm(...) + return times <= 1 + end + end} +end + +-- then convert sample_level to csv. +-- spawn_spec_gun_at and spawn_main_gun_at will need parsed forms. +-- the boss also needs to be reachable, but one-off is fine. +-- each row of level csv is offset,event,event-args... +-- where offset,eol is a special case. + example_level = { [1]=spawn_frownie, [60]=spawn_bonus_vulcan_chasey,