Skip to content

Instantly share code, notes, and snippets.

@mhungerford
Created September 6, 2022 02:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mhungerford/565a66e3a4deb99ad9592b9b81517bb0 to your computer and use it in GitHub Desktop.
Save mhungerford/565a66e3a4deb99ad9592b9b81517bb0 to your computer and use it in GitHub Desktop.
-- the concept of space
-- by matt hungerford
-- vars
cartdata("tcos") -- savedata for high-scores
l={} -- list of ball objects
tp=2 -- edge padding
tb=92 -- danger-line offset
sa=15 -- shooter angle
u=1 -- shooter moving direction
g=-1 -- game mode (-1=title, 0=playing, 1=credits)
s=0 -- score
h=dget(0) -- high-score
p={} -- list of particles
_set_fps(60)
-- main loop using label "_" and goto
::_::
cls()
-- game bounds using contiguous mode for line
line(2,tb,2,2,7)
line(126,2)
line(126,tb)
fillp(░)line(2,tb)fillp() -- dashed danger line
-- print score/high-score using pinball text "\^p"
-- scores over 99 go offscreen, so adjust these cases
ss="\^pscore "..s.." high "..h
xo=min(2, 128 - ?ss,0,-128)
?ss,xo,116
mv=0
if (#l > 0) do
b=l[#l] -- current ball
x=b.x -- temp store frequently-used properties in variables to save on chars
y=b.y --
b.v*=.97 -- apply drag/friction to balls' velocities to slow them to a stop
b.b*=.97 --
x+=b.v -- apply the velocity to current ball position
y+=b.b --
mv=abs(b.v)+abs(b.b)
-- stop the ball if barely moving
if (mv < 0.02)do
mv=0
b.v = 0
b.b = 0
end
-- expand to fill available space for the last ball
e=min(96, x - tp - 2)
e=min(e, 126 - x - 1)
e=min(e, y - tp - 2)
e=min(e, tb - y - 1)
for k,t in pairs(l)do -- compare current ball to all other balls
circ(t.x,t.y,t.r,({11,9,8})[t.c]) -- draw each ball
if (k!=#l) then
a=x-t.x z=y-t.y -- calculate distance from ball
d=sqrt(a*a+z*z) --
e=min(e, d - t.r - 1)
-- if balls radius touch (ie. hit) trigger action on active ball
if(d<=b.r+t.r) then
t.c-=1
o=(d - b.r - t.r)
x-=o*(a/d)
y-=o*(z/d)
n=(t.x-b.x)/d -- calc normal vector
r=(t.y-b.y)/d --
v=b.v*-r+b.b*n -- calc dot product tangent
k=t.v*n+t.b*r --
b.v=(-r*v+n*k) * 1.15 -- calc final velocities
b.b=(n*v+r*k) * 1.15 --
-- add a particle effect
for i=0,20 do
add(p, {x=t.x-n*(d-b.r),y=t.y-r*(d-b.r),a=rnd(100)/100.0,s=rnd(3)/3,c=max(t.c,1),n=80})
end
?"\as0c",0,0
end
end
end
-- expand to fill e if stopped moving
if (mv==0 and e > b.r)b.r+=1
-- if hit 3 times, delete and add to score
foreach(l, function(t)
if(t.c==0)del(l,t)s+=1
end)
if(x+b.r>126 or x-b.r<2+1)b.v*=-1.1 -- if ball hits table boundary,
if(y-b.r<tp)b.b*=-1.1 -- calc rebound angle (+ a bit of bounce acceleration)
-- game over if ball goes over dashed line
if(b.b > 0 and y+b.r>tb)dset(0,h)g=1
b.x=x b.y=y -- store our temp vars back into the ball object
end --end of ball handling
-- draw particles and decimate
foreach(p, function(o)
o.x+=rnd(1)*sin(o.a)*o.s
o.y+=rnd(1)*cos(o.a)*o.s
pset(o.x,o.y,({11,9,8})[o.c])
o.n-=1
if(o.n<=0)del(p,o)
end)
-- high-score
h=max(h,s)
rt=flr(t()%3)*4 - 4
if (g==1)?"\^t\^wgame over",30+rt,24+rt,12
if (g!=0)?"\^t\#7the concept of space",25,44,0
if (g!=0)?"press x to start",34,64,12
-- x/y on unit circle shooter line
co=cos(sa/360)
si=sin(sa/360)
-- draw the angled shooter line
line(64,112,64-16*co,112+16*si,7)
if mv <= 0 and g==0 then
if (sa<=15) u=1
if (sa>=165) u=-1
sa+=u
end
-- single-button "x" starts game or shoots ball
if btnp(5) then
if g==0 and mv <= 0 then
-- add current ball to the list (table)
b=add(l,{x=64,y=112,r=4,c=3,a=0,v=-5.9*co,b=5.9*si})
elseif g!=0 then
l={}g=0 s=0
end
end
flip()
goto _
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment