9 Commits

Author SHA1 Message Date
1ef5b56c58 wait this version of zot actually looks good 2025-06-01 23:46:59 -07:00
44fb8482a5 a version of zot that does not look awful
performance impact is probably not acceptable though
2025-06-01 23:29:03 -07:00
62f8f27829 a zot prototype that looks awful
I need to draw all the hot parts last
2025-06-01 23:06:44 -07:00
542acc5308 nano-optimizations 2025-06-01 21:03:04 -07:00
4e66c875ad improve legibility 2025-06-01 20:58:21 -07:00
812d32e70c micro-optimizations 2025-06-01 20:58:12 -07:00
d2ec1b39df Show approximation of contact zone 2025-06-01 20:38:56 -07:00
a3ac8074ae line-box collision implemented by Pyrex&Nyeo 2025-06-01 20:29:02 -07:00
85d28ae28b get rid of pships
lots of things rely on exactly one primary ship now, so this was just
overhead and wasted tokens / cspace.
2025-06-01 17:55:46 -07:00
2 changed files with 194 additions and 34 deletions

172
collisiontest.p8 Normal file
View File

@ -0,0 +1,172 @@
pico-8 cartridge // http://www.pico-8.com
version 42
__lua__
bx0=0
by0=0
bx1=127
by1=127
lx0=0
ly0=0
lx1=127
ly1=127
-->8
function collides()
local tmin,tmax=0,1
local ldx,ldy=lx1-lx0,ly1-ly0
-- x
if ldx==0 then
if (lx0<bx0 or lx0>bx1) return
else
local tx0=(bx0-lx0)/ldx
local tx1=(bx1-lx0)/ldx
if (tx0 > tx1) tx0,tx1=tx1,tx0
if (tmin < tx0) tmin=tx0
if (tmax > tx1) tmax=tx1
end
if ldy==0 then
if (ly0<by0 or ly0>by1) return
else
local ty0=(by0-ly0)/ldy
local ty1=(by1-ly0)/ldy
if (ty0 > ty1) ty0,ty1=ty1,ty0
if (tmin < ty0) tmin=ty0
if (tmax > ty1) tmax=ty1
end
if (tmax < tmin) return
return tmin,tmax
end
-->8
function _init()
poke(0x5f2d,1) -- enable mouse
end
function _bounce_screen(x)
return _bounce(x*128,128)
end
function _bounce(x,mx)
x=x%(mx * 2)
if (x>=mx)return mx-(x-mx)
return x
end
function _to_halfopen(x0,x1)
-- turn two numbers into a
-- half-open integer range
x0=flr(x0)
x1=flr(x1)
local lo=min(x0,x1)
local hi=max(x0,x1)
if (hi==lo) return lo,hi
return lo,hi-1
end
function _update60()
local t=time()/16
local bx0_=_bounce_screen(t*1)
local by0_=_bounce_screen(t*2)
local bx1_=_bounce_screen(t*3)
local by1_=_bounce_screen(t*4)
bx0,bx1=_to_halfopen(bx0_,bx1_)
by0,by1=_to_halfopen(by0_,by1_)
update_line()
--[[
local lx0_=_bounce_screen(t*1.5)
local ly0_=_bounce_screen(t*2.5)
local lx1_=_bounce_screen(t*3.5)
local ly1_=_bounce_screen(t*4.5)
lx0,lx1=lx0_,lx1_
ly0,ly1=ly0_,ly1_
]]--
end
was_down=false
last_mx,last_my=nil,nil
function update_line()
local mx,my=stat(32),stat(33)
local is_down=stat(34)!=0
if is_down then
if was_down then
lx1,ly1=mx,my
else
lx0,ly0=mx,my
end
end
was_down=is_down
last_mx,last_my=mx,my
end
-->8
function _draw()
cls(0)
rect(bx0,by0,bx1,by1,6)
zot(lx1,ly1,0,lx1-lx0,ly1-ly0,10,9,8)
--line(lx0,ly0,lx1,ly1,2)
local cmin, cmax = collides()
if cmin then
local dx,dy=lx1-lx0,ly1-ly0
line(lx0 + dx*cmin,
ly0 + dy*cmin,
lx0 + dx*cmax,
ly0 + dy*cmax,
11)
pset(lx0 + dx*cmin,
ly0 + dy*cmin,
12)
end
pset(last_mx,last_my,7)
end
-->8
function zot_one(x, y, r, ir, dx, dy, hot, warm)
local x0, y0 = x-dx, y-dy
local rx,ry,irx,iry=r*sgn(dx),r*sgn(dy),ir*sgn(dx),ir*sgn(dy)
if warm then
line(x0+irx,y0-ry,x+rx,y-iry,warm)
line(x0-rx,y0+iry,x-irx,y+ry,warm)
--line(x0-rx,y0-ry,x+rx,y+ry,warm)
end
line(x0,y0,x+rx,y-iry,hot)
line(x0,y0,x-irx,y+ry,hot)
--line(x0,y0,x+rx,y+ry,hot)
end
function zot(x,y,r,dx,dy,hot,warm,cold)
local x0,y0,sdx,sdy=x-dx,y-dy,sgn(dx),sgn(dy)
local rx,ry=r*sdx,r*sdy
if cold then
rectfill(x0-rx,y0-ry,x0+rx,y0+ry,cold)
local sdxh,sdyh=sdx/2,sdy/2
line(x0-rx-sdxh,y0+ry+sdyh,x-rx,y+ry,cold)
line(x0+rx+sdxh,y0-ry-sdyh,x+rx,y-ry,cold)
end
for i=-r,r do
line(x0+i*sdx,y0-ry,x+rx,y-i*sdy,warm)
line(x0-rx,y0+i*sdy,x-i*sdx,y+ry,warm)
end
for i=-r,r do
line(x0,y0,x+rx,y-i*sdy,hot)
line(x0,y0,x-i*sdx,y+ry,hot)
end
end
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

View File

@ -169,8 +169,6 @@ function wipe_game()
xpwhoosh = nil
primary_ship = player.new()
init_hpcols()
pships = linked_list.new()
pships:push_back(primary_ship)
eships = linked_list.new()
pbullets = linked_list.new()
ebullets = linked_list.new()
@ -208,7 +206,8 @@ function ones(n)
end
function updategame()
if (primary_ship.xp >= primary_ship.xptarget) and (gframe - primary_ship.last_xp_frame > 0x0.000f) and (not primary_ship.dead) then
local ps = primary_ship
if (ps.xp >= ps.xptarget) and (gframe - ps.last_xp_frame > 0x0.000f) and (not ps.dead) then
mode = rearm_mode.new()
return _update60()
end
@ -238,36 +237,24 @@ function updategame()
end
events:vore(new_events)
events:strip(call_move)
for _, lst in ipairs{intangibles_bg, pships, eships, pbullets, ebullets} do
for _, lst in ipairs{intangibles_bg, eships, pbullets, ebullets} do
lst:strip(call_move)
end
pships:strip(
function(ps)
local pbox, pded = hurtbox(ps), false
eships:strip(
function(es)
if (not collides(pbox, hurtbox(es))) return
pded = pded or ps:hitship(es)
return es:hitship(ps)
end
)
return pded
end
)
pships:strip(
function(ps)
local pbox, pded = hurtbox(ps), false
ebullets:strip(
function(eb)
if (not collides(pbox, hurtbox(eb))) return
pded = pded or ps:hitbullet(eb)
return eb:hitship(ps)
end
)
return pded
end
)
if not ps.dead then
ps:move()
local pbox = hurtbox(ps)
eships:strip(function(es)
if(not collides(pbox, hurtbox(es))) return
ps:hitship(es)
return es:hitship(ps)
end)
ebullets:strip(function(eb)
if (not collides(pbox, hurtbox(eb))) return
ps:hitbullet(eb)
return eb:hitship(ps)
end)
end
-- many bullets and many enemy ships;
-- use bucket collider for efficiency
@ -302,9 +289,9 @@ function updategame()
if waves_complete == 32767 and not eships.next and not ebullets.next and not events.next then
game_state = win
end
if (not pships.next) game_state = lose
if (ps.dead) game_state = lose
if primary_ship.xp >= primary_ship.xptarget then
if ps.xp >= ps.xptarget then
if not xpwhoosh then
xpwhoosh = 0
else
@ -393,8 +380,8 @@ end
function drawgame()
clip(0,0,112,128)
rectfill(0,0,112,128,0)
for slist in all{intangibles_bg, pbullets, pships, eships, ebullets, intangibles_fg} do
slist:draw()
for drawable in all{intangibles_bg, pbullets, primary_ship, eships, ebullets, intangibles_fg} do
drawable:draw()
end
clip(0,0,128,128)
drawhud()
@ -624,6 +611,7 @@ function ship_m:move()
end
function ship_m:draw()
if (self.dead) return
if(self.fx_pal) pal(self.fx_pal)
spr(self.sprite, self.x, self.y, self.size, self.size)
pal()