8 Commits

Author SHA1 Message Date
c752e8e1e3 fix hpcols_init
note that I need to re-call this whenever I have a new max hp

also note that vertmeter does not handle 1024 correctly. find out what max hp functions and hardcap it
2025-06-28 23:10:57 -07:00
507f06fb8c more efficient bullet spawning 2025-06-28 22:59:51 -07:00
14849101dd skip call to sparks if there are no sparks
Then don't check for nil spark colors in sparks itself.

Also uses a more verbose but more efficient exit check, and fixes a bug.
2025-06-28 22:49:10 -07:00
2cd7c64dd9 micro-optimize bullet details
Shots that miss are most likely to not be there yet, so check Y-top first.

If I assume shots will never be larger than 16 pixels per side, there is
no reason to check the ship's genuine width and height.
2025-06-28 22:35:36 -07:00
2d5d392df0 reverse strip logic
saves a single cycle per bullet, but...
2025-06-24 23:16:47 -07:00
904fbe6b2e bullets don't expire 2025-06-24 23:06:09 -07:00
36b268e057 initialization is very slightly faster this way, I think 2025-06-24 22:54:03 -07:00
3d6ef03b37 attempt to optimize collision
it's actually worse
2025-06-24 22:36:58 -07:00
2 changed files with 553 additions and 73 deletions

495
collision_profiling.p8 Normal file
View File

@ -0,0 +1,495 @@
pico-8 cartridge // http://www.pico-8.com
version 42
__lua__
-- prof: cpu cycle counter v1.4
-- BY PANCELOR
--[[------------------------
use this cart to precisely
measure code execution time
--------------------------------
★ overview ★
--------------------------------
| tab 0 | usage guide |
| tab 1 | (internals) |
| tab 2 | your code here |
--------------------------------
-----------------------
-- ★ usage guide ★ --
-----------------------
웃: i have two code snippets;
which one is faster?
🐱: edit the last tab with your
snippets, then run the cart.
it will tell you precisely
how much cpu it takes to
run each snippet.
the results are also copied
to your clipboard.
웃: what do the numbers mean?
🐱: the cpu cost is reported
as lua and system cycle
counts. look up stat(1)
and stat(2) for more info.
if you're not sure, just
look at the first number.
lower is faster (better)
웃: why "{locals={9}}"
in the example?
🐱: accessing local variables
is faster than global vars.
so if your test involves
local variables, simulate
this by passing them in:
prof(function(a)
sqrt(a)
end,{ locals={9} })
/!\ /!\ /!\ /!\
local values from outside
the current scope are also
slower to access! example:
global = 4
local outer = 4
prof(function(x)
local _ = x --fast
end,function(x)
local _ = outer --slow
end,function(x)
local _ = global --slow
end,{ locals={4} })
/!\ /!\ /!\ /!\
웃: can i do "prof(myfunc)"?
🐱: no, this sometimes gives
wrong results! always use
inline functions:
prof(function()
--code for myfunc here
end)
as an example, "prof(sin)"
reports "-2" -- wrong! but
"prof(function()sin()end)"
correctly reports "4"
(see the technical notes at
the start of the next tab
for a brief explanation.
technically, "prof(myfunc)"
will work if myfunc was made
by the user, but you will
risk confusing yourself)
---------------
★ method 2 ★
---------------
this cart is based on
code by samhocevar:
https://www.lexaloffle.com/bbs/?pid=60198#p
if you do this method, be very
careful with local/global vars.
it's very easy to accidentally
measure the wrong thing.
here's an example of how to
measure cycles (ignoring this
cart and using the old method)
function _init()
local a=11.2 -- locals
local n=1024
flip()
local tot1,sys1=stat(1),stat(2)
for i=1,n do end --calibrate
local tot2,sys2=stat(1),stat(2)
for i=1,n do local _=sqrt(a) end --measure
local tot3,sys3=stat(1),stat(2)
function cyc(t0,t1,t2) return ((t2-t1)-(t1-t0))*128/n*256/stat(8)*256 end
local lua = cyc(tot1-sys1,tot2-sys2,tot3-sys3)
local sys = cyc(sys1,sys2,sys3)
print(lua.."+"..sys.."="..(lua+sys).." (lua+sys)")
end
run this once, see the results,
then change the "measure" line
to some other code you want
to measure.
note: wrapping the code inside
"_init()" is required, otherwise
builtin functions like "sin"
will be measured wrong.
(the reason is explained at
the start of the next tab)
---------------
★ method 3 ★
---------------
another way to measure cpu cost
is to run something like this:
function _draw()
cls(1)
local x=9
for i=1,1000 do
local a=sqrt(x) --snippet1
-- local b=x^0.5 --snippet2
end
end
while running, press ctrl-p to
see the performance monitor.
the middle number shows how much
of cpu is being used, as a
fraction. (0.60 = 60% used)
now, change the comments on the
two code snippets inside _draw()
and re-run. compare the new
result with the old to determine
which snippet is faster.
note: every loop iteration costs
an additional 2 cycles, so the
ratio of the two fractions will
not match the ratio of the
execution time of the snippets.
but this method can quickly tell
you which snippet is faster.
]]
-->8
--[[ profiler.lua
more info: https://www.lexaloffle.com/bbs/?tid=46117
usage:
prof(function()
memcpy(0,0x200,64)
end,function()
poke4(0,peek4(0x200,16))
end)
passing locals:
prof(
function(a,b)
local c=(a+1)*(b+1)-1
end,
function(a,b)
local c=a*b+a+b
end,
{locals={3,5}}
)
getting global/local variables exactly right
is very tricky; you should always use inline
functions like above; if you try e.g. prof(sin)
the results will be wrong.
# minutiae / notes to self:
---------------------------
doing this at top-level is awkward:
for _=1,n do end -- calibrate
for _=1,n do sin() end -- measure
b/c sin is secretly local at top-level,
so it gives a misleading result (3 cycles).
do it inside _init instead for a
more representative result (4 cycles).
## separate issue:
------------------
if you call prof(sin), it gives the wrong result (-2 cycles) because
it's comparing sin() against noop() (not truly nothing).
but we want the noop() there for normal inline prof() calls,
to avoid measuring the cost of the indirection
(calling func() from inside prof() is irrelevant to
how cpu-expensive func()'s body is)
]]
-- prof(fn1,fn2,...,fnN,[opts])
--
-- opts.locals: values to pass
-- opts.name: text label
-- opts.n: number of iterations
function prof(...)
local funcs={...}
local opts=type(funcs[#funcs])=="table" and deli(funcs) or {}
-- build output string
local msg=""
local function log(s)
msg..=s.."\n"
end
if opts.name then
log("prof: "..opts.name)
end
for fn in all(funcs) do
local dat=prof_one(fn,opts)
log(sub(" "..dat.total,-3)
.." ("
..dat.lua
.." lua, "
..dat.sys
.." sys)")
end
-- copy to clipboard
printh(msg,"@clip")
-- print + pause
cls()
stop(msg)
end
function prof_one(func, opts)
opts = opts or {}
local n = opts.n or 0x200 --how many times to call func
local locals = opts.locals or {} --locals to pass func
-- we want to type
-- local m = 0x80_0000/n
-- but 8MHz is too large to fit in a pico-8 number,
-- so we do (0x80_0000>>16)/(n>>16) instead
-- (n is always an integer, so n>>16 won't lose any bits)
local m = 0x80/(n>>16)
assert(0x80/m << 16 == n, "n is too small") -- make sure m didn't overflow
local fps = stat(8)
-- given three timestamps (pre-calibration, middle, post-measurement),
-- calculate how many more CPU cycles func() took compared to noop()
-- derivation:
-- T := ((t2-t1)-(t1-t0))/n (frames)
-- this is the extra time for each func call, compared to noop
-- this is measured in #-of-frames -- it will be a small fraction for most ops
-- F := 1/30 (seconds/frame) (or 1/60 if this test is running at 60fps)
-- this is just the framerate that the tests run at, not the framerate of your game
-- M := 256*256*128 = 0x80_0000 = 8MHz (cycles/second)
-- (PICO-8 runs at 8MHz; see https://www.lexaloffle.com/dl/docs/pico-8_manual.html#CPU)
-- cycles := T frames * F seconds/frame * M cycles/second
-- optimization / working around pico-8's fixed point numbers:
-- T2 := T*n = (t2-t1)-(t1-t0)
-- M2 := M/n = (M>>16)/(n>>16) := m (e.g. when n is 0x1000, m is 0x800)
-- cycles := T2*M2*F
local function cycles(t0,t1,t2)
local diff = (t2-t1)-(t1-t0)
local e1 = "must use inline functions -- see usage guide"
assert(0<=diff,e1)
local thresh = 0x7fff.ffff/(m/fps)
local e2 = "code is too large or slow -- try profiling manually with stat(1)"
assert(diff<=thresh,e2)
return diff*(m/fps)
end
local noop = function() end -- this must be local, because func is local
flip() --avoid flipping mid-measurement
local atot,asys=stat(1),stat(2)
for _=1,n do noop(unpack(locals)) end -- calibrate
local btot,bsys=stat(1),stat(2)
for _=1,n do func(unpack(locals)) end -- measure
local ctot,csys=stat(1),stat(2)
-- gather results
local tot=cycles(atot,btot,ctot)
local sys=cycles(asys,bsys,csys)
return {
lua=tot-sys,
sys=sys,
total=tot,
}
end
-->8
-- your code here
--edit me:
prof(function(b1,b2)
return
b1[1]<=b2[3]
and b1[2]<=b2[4]
and b1[3]>=b2[1]
and b1[4]>=b2[2]
end,function(b1, b2)
return
b1.x1<=b2.x2
and b1.y1<=b2.y2
and b1.x2>=b2.x1
and b1.y2>=b2.y1
end,{ locals={{1,1,1,1,x1=1,x2=1,y1=1,y2=1},{1,1,1,1,x1=1,x2=1,y1=1,y2=1}} })
-- "locals" (optional) are
-- passed in as args. see the
-- usage guide for details.
__label__
00006660000000006660000000006660000006006000606066600000066060600660060000000000000000000000000000000000000000000000000000000000
00006000060000006060666000006000000060006000606060600600600060606000006000000000000000000000000000000000000000000000000000000000
00006660666000006060000000006660000060006000606066606660666066606660006000000000000000000000000000000000000000000000000000000000
00000060060000006060666000000060000060006000606060600600006000600060006000000000000000000000000000000000000000000000000000000000
00006660000000006660000000006660000006006660066060600000660066606600060000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00006060000000006660000000006060000006006000606066600000066060600660060000000000000000000000000000000000000000000000000000000000
00006060060000006060666000006060000060006000606060600600600060606000006000000000000000000000000000000000000000000000000000000000
00006660666000006060000000006660000060006000606066606660666066606660006000000000000000000000000000000000000000000000000000000000
00000060060000006060666000000060000060006000606060600600006000600060006000000000000000000000000000000000000000000000000000000000
00000060000000006660000000000060000006006660066060600000660066606600060000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
70000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
07000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
07000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
70000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__sfx__
030100003052500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505

View File

@ -61,11 +61,11 @@ end
-- call f on everything on list
-- and return a new list of
-- items for which f was false.
function stripped(list, f)
-- items for which f was true.
function filtered(list, f)
local ret, n = {}, 0
for v in all(list) do
if not f(v) then
if f(v) then
n += 1
ret[n] = v
end
@ -75,25 +75,25 @@ end
-- call :move on everything on
-- src and dump everything
-- for which it returned false
-- for which it returned true
-- onto dest.
function appendmove(dest, src)
local n = #dest
for v in all(src) do
if not v:move() then
if v:move() then
n += 1
dest[n] = v
end
end
end
-- like stripped, but calls
-- like filtered, but calls
-- :move on stuff in the list
-- instead of taking a func arg.
function stripmoved(list)
function filtermoved(list)
local ret, n = {}, 0
for v in all(list) do
if not v:move() then
if v:move() then
n += 1
ret[n] = v
end
@ -130,7 +130,7 @@ hpcols_lut = csv[[36
-- call after any change to maxhp
-- configures health gradient
function init_hpcols()
hpcols = hpcols_lut[min(primary_ship.maxhp,6)]
hpcols = hpcols_lut[min(primary_ship.maxhp,5)]
end
function wipe_game()
@ -196,11 +196,11 @@ function updategame()
current_wave = flotilla.new()
current_wave:load(rnd() > 0.5 and 7 or 0, 0, min(ones(waves_complete)\2, 4))
end
events = stripmoved(events)
events = filtermoved(events)
appendmove(events, new_events)
new_events = {}
intangibles_bg = stripmoved(intangibles_bg)
eships = stripmoved(eships)
intangibles_bg = filtermoved(intangibles_bg)
eships = filtermoved(eships)
-- eship collider will be used
-- both for pship and pbullets.
@ -213,25 +213,26 @@ function updategame()
ps:hitship(es)
es:hitship(ps)
end
ebullets = stripped(ebullets, function(eb)
if (eb:move()) return true
if (not collides(pbox, hurtbox(eb))) return
ebullets = filtered(ebullets, function(eb)
if (not eb:move()) return
if (not collides(pbox, hurtbox(eb))) return true
ps:hitbullet(eb)
return eb:hitship(ps)
return not eb:hitship(ps)
end)
else
ebullets=stripmoved(ebullets)
ebullets=filtermoved(ebullets)
end
pbullets = stripped(pbullets, function(pb)
if (pb:move()) return true
pbullets = filtered(pbullets, function(pb)
if (not pb:move()) return
for es in eship_collider:iterate_collisions(hurtbox(pb)) do
es:hitbullet(pb)
if (pb:hitship(es)) return true
if (pb:hitship(es)) return
end
return true
end)
intangibles_fg = stripmoved(intangibles_fg)
intangibles_fg = filtermoved(intangibles_fg)
if waves_complete == 32767 and #eships == 0 and #ebullets == 0 and #events == 0 then
game_state = win
@ -535,10 +536,10 @@ function ship_m:constrain(p, dp, pmin, pmax, want)
end
function ship_m:move()
if (self.dead) return true;
if (self.dead) return;
self:refresh_shield()
local dx, dy, shoot_spec1, shoot_spec2 = self:act()
local sg, xm, ym = self.special_guns, self.xmomentum, self.ymomentum
local sg, xm, ym, sp = self.special_guns, self.xmomentum, self.ymomentum, self.sparks
dx = self:constrain(self.x, xm, self.xmin, self.xmax, dx)
dy = self:constrain(self.y, ym, self.ymin, self.ymax, dy)
self:maybe_shoot(self.main_gun)
@ -546,7 +547,7 @@ function ship_m:move()
if (shoot_spec1) self:maybe_shoot(sg[1])
if (shoot_spec2) self:maybe_shoot(sg[2])
end
spark(self.sparks, self.x + 4*self.size, self.y + 4*self.size, dx*2.5, dy*2.5, self.sparkodds)
if(sp) spark(sp, self.x + 4*self.size, self.y + 4*self.size, dx*2.5, dy*2.5, self.sparkodds)
xm = self:calc_velocity(xm, dx)
ym = self:calc_velocity(ym, dy)
@ -555,7 +556,7 @@ function ship_m:move()
self.xmomentum = xm
self.ymomentum = ym
return false
return true
end
function ship_m:draw()
@ -567,12 +568,8 @@ end
function hurtbox(ship)
local h = ship.hurt
return {
x=ship.x + h.x_off,
y=ship.y + h.y_off,
width=h.width,
height=h.height
}
local x1,y1 = ship.x + h.x_off, ship.y+h.y_off
return {x1=x1, y1=y1, x2=x1+h.width, y2=y1+h.height}
end
function ship_m:maybe_shoot(gun)
@ -621,14 +618,6 @@ end
-->8
-- bullet and gun behaviors
function player_blt_cat()
return pbullets
end
function enemy_blt_cat()
return ebullets
end
-- x, y: position
-- dx, dy: movement (linear)
-- f: frames remaining; nil for no limit
@ -641,9 +630,9 @@ end
-- details, check impl
-- damage -- damage to do to
-- a ship that gets hit
-- category -- function that
-- returns which bullet list
-- to spawn onto
-- category -- string naming
-- which bullet list to spawn
-- onto, from _ENV
-- hitship -- event handler,
-- takes ship as argument.
-- default: die, return true.
@ -776,13 +765,9 @@ function bullet_base:hitship(_)
end
function bullet_base:move()
local x,y,f = self.x + self.dx, self.y+self.dy,self.f
local x,y = self.x + self.dx, self.y+self.dy
self.x,self.y=x,y
if f then
self.f = f-1
if (f <= 0) return true
end
return (y> 130) or (y < -(self.height<<3)) or (x > 128) or (x < -(self.width<<3))
return (y<=128) and (y >= -16) and (x <= 128) and (x >= -16)
end
function bullet_base:draw()
@ -792,7 +777,7 @@ end
function bullet_base:spawn_at(x, y)
self.x = x - self.x_off
self.y = y - self.y_off
add(self.category(), self)
add(_ENV[self.category], self)
end
function gun_base:shoot(x, y)
@ -862,7 +847,7 @@ zap_p = mknew(bullet_base.new{
hitship = const_fxn(true),
category = player_blt_cat,
category = "pbullets",
})
zap_gun_p = mknew(gun_base.new{
@ -921,7 +906,7 @@ blast = mknew(bullet_base.new{
end)
end
end,
category=player_blt_cat
category="pbullets"
})
blast_gun = mknew(gun_base.new{
@ -960,14 +945,14 @@ protron_e = mknew(bullet_base.new{
y_off = 4,
damage = 1,
category = enemy_blt_cat,
category = "ebullets",
})
protron_p = mknew(protron_e.new{
sprite=23,
dym = -1,
y_off = 0,
category=player_blt_cat,
category="pbullets",
})
protron_gun_e = mknew(gun_base.new{
@ -1014,13 +999,13 @@ vulcan_e = mknew(bullet_base.new{
y_off = 0,
damage = 0.5,
category=enemy_blt_cat
category="ebullets"
})
vulcan_p = mknew(vulcan_e.new{
sprite=22,
y_off = 4,
category=player_blt_cat
category="pbullets"
})
vulcan_gun_e = mknew(gun_base.new{
@ -1356,14 +1341,13 @@ end
-->8
-- collisions
-- box: x, y, width, height
function collides(box1, box2)
return not (
box1.x>box2.x+box2.width
or box1.y>box2.y+box2.height
or box1.x+box1.width<box2.x
or box1.y+box1.height<box2.y)
-- box: x1, y1, x2, y2
function collides(b1, b2)
return
b1.y1<=b2.y2
and b1.y2>=b2.y1
and b1.x1<=b2.x2
and b1.x2>=b2.x1
end
collider = mknew{
@ -1384,10 +1368,10 @@ collider = mknew{
}
function collider_indexes(box)
local ret = {}
for x = box.x\8, (box.x+box.width)\8 do
for y = box.y\8, (box.y+box.height)\8 do
add(ret, x+256*y)
local ret, ylo, yhi = {}, box.y1\8, box.y2\8
for x = box.x1\8, box.x2\8 do
for y = ylo, yhi do
add(ret, x+(y<<8))
end
end
return ret
@ -1582,13 +1566,13 @@ blip_fx = mknew{
}
function blip_fx:move()
if (self.cancel) return true
if (self.cancel) return
self.frames -= 1
if self.frames < 0 then
self.obj.fx_pal = nil
return true
return
end
return false
return true
end
function blip_fx:abort()
@ -1633,18 +1617,19 @@ spark_particle=mknew{}
function spark_particle:move()
if (rnd(4) < 1) self.sidx += 1
if (self.sidx > #self.sprs) return true
if (self.sidx > #self.sprs) return
self.x += self.dx
self.y += self.dy
self.dx -= mid(0.05,-0.05, self.dx)
self.dy -= mid(0.05,-0.05, self.dy)
return true
end
function spark_particle:draw()
pset(self.x,self.y,self.sprs[self.sidx])
end
function spark(sprs, x, y, dx, dy, odds, fg)
if (sprs==nil or flr(rnd(odds) or (abs(dx) < 0.5 and abs(dy))) ~= 0) return
if ((dx > -0.5 and dx < 0.5 and dy > -0.5 and dy < 0.5) or rnd(odds) >= 1) return
local target = fg and intangibles_fg or intangibles_bg
target[#target+1] = spark_particle.new{
x = x + rnd(4) - 2,
@ -1663,7 +1648,7 @@ xp_gem = mknew(bullet_base.new{
dy = 0.75,
width=1, -- not used for spr but
height=1,-- bullet_base uses it
category = enemy_blt_cat,
category = "ebullets",
damage = 0,
hurt = {
x_off = -2,