Commented source code



-- This function starts a new game.
-- It positions the ball in the launcher chute,
-- zeroes its velocity,
-- and resets the multiplier bonus status.
-- There's no launcher logic, just a bumper
-- at the bottom of the chute.
function st()
	x=119
	y=64
	xv=0
	yv=0
	mu=1
	ma=false
	mb=false
	mc=false
end

-- z is score and w is how many balls you have left
st()
z=0
w=5

-- We don't use the update function, everything is in draw
function _draw()
	-- lf and rf are the flipper status.
	-- ll and lr are the flipper status on the previous frame.
	-- We don't use btnp, since the keyboard fires it too often
	ll=lf
	lr=rf
	lf=btn(4)
	rf=btn(5)

	-- Next, draw the table. We have to do this first
	-- because we read the screen to know where the walls are

	-- walls
	cls(12)
	rectfill(40,8,90,128,0)
	rectfill(16,40,123,128) -- remember colour from drawstate
	rectfill(8,63,123,128)
	circfill(40,40,32)
	circfill(90,40,32)
	rectfill(113,45,115,128,12)
	circfill(62,84,3)

	-- multiplier
	circfill(40,64,2)
	circfill(52,62,2)
	circfill(64,60,2)
	circfill(76,58,2)
	-- lights (? is shorthand for print)
	?'1',45,61,ma and 13 or 1
	?'k',57,59,mb and 14 or 2
	?'p',69,57,mc and 11 or 3
	?'x'..mu,54,52,9

	-- bumpers
	rectfill(116,120,123,128,8) -- bottom of launch chute
	circfill(66,26,5)
	circfill(48,35,5)
	circfill(82,40,5)
	rectfill(4,63,7,72)

	-- This loop draws all the sloped ramps and flippers
	-- which need some thickness to them
	for i=0,3 do
		-- ramps to central chute
		line(18,100+i,43,114+i,12)
		line(105,100+i,78,114+i)
		-- side gutters
		line(18+i,102,18+i,75+i)
		line(105-i,102,105-i,75+i)
		-- top right ramp
		line(110,55+i,113,53+i)
		-- triangle bumpers by flippers
		line(30+i,95,30+i,80+i)
		line(93-i,95,93-i,80+i)
		line(30,95-i,43-i,101-i)
		line(93,95-i,80+i,101-i)
		line(34-i,84-i,43-i,101-i,8)
		line(89+i,84-i,80+i,101-i,8)
		--flippers
		line(14,60+i,26,(lf and 56 or 64)+i,7)
		line(43,114+i,55,(lf and 110 or 118)+i)
		line(78,114+i,66,(rf and 110 or 118)+i)
		line(109,55+i,97,(rf and 51 or 59)+i)
	end

	-- handle flippers
	-- the f function does a flip in the specified area
	if lf and not ll then f(13,15,60);f(42,15,114)end
	if rf and not lr then f(79,-15,114);f(110,-15,55)end

	-- calculate movement in quarter steps like mario 64
	for i=1,4 do
		-- ly is the y coordinate on the last frame.
		-- this is used to check when you roll over a light
		ly=y

		-- move the ball by its speed
		x+=xv/4
		y+=yv/4

		-- find the normal of the wall if we hit one
		nx=0
		ny=0
		b=false -- b is true if we hit a bumper
		for t=0,1,0.125 do
			s=sin(t)
			c=cos(t)
			p=pget(x+s*2,y+c*2)
			if p==8 or p==7 or p==12 then
				nx+=s
				ny+=c
				if p==8 then b=true end
			end
		end
		l=sqrt(nx*nx+ny*ny)
		if l>0 then -- this only fires if we hit something
			-- divide by l to get the normalised normal
			nx/=l
			ny/=l
			-- nudge the ball away from the wall
			x-=nx
			y-=ny
			-- work out the component of speed perpendicular to the wall
			p=abs(nx*xv+ny*yv)*-0.6
			-- give an extra kick and some score if the wall is a bumper
			if b then
				p*=rnd()+3
				z+=mu
				?'\a' -- \a is a control code that makes a beep
			end
			-- work out the tangent component (with some jitter
			-- so we never get stuck but still roll neatly down slopes)
			t=(nx*yv-ny*xv)*(0.8+rnd()*0.2)+rnd()*0.05
			-- apply the newly bounced velocities to the ball
			xv=p*nx-t*ny
			yv=p*ny+t*nx
		end

		-- gravity
		yv+=0.025

		-- max speed - partly to keep things manageable,
		-- but mostly to prevent us clipping through thin walls
		-- (eg, the flippers)
		l=sqrt(xv*xv+yv*yv)/8
		if l>1 then xv/=l;yv/=l end

		-- check if we rolled over the multiplier lights
		if x>42 and x<50 and (y-63)*(ly-63)<0 then ma=true end
		if x>54 and x<62 and (y-61)*(ly-61)<0 then mb=true end
		if x>66 and x<74 and (y-59)*(ly-59)<0 then mc=true end
		if ma and mb and mc then
			-- if we got all of them, bump the multiplier and reset them
			mu+=1
			ma=false
			mb=false
			mc=false
		end
	end

	-- draw the ball
	?'●',x-3,y-2,6
	-- draw the score and lives counters
	?z..'000',1,1,10
	?'●x'..w,110,1

	-- check if the ball is lost
	if y>130 and w>0 then
		w-=1
		st()
	end
end

-- if you flipped, work out where on the flipper the ball is
-- and (if it is on the flipper) add an appropriate kick
function f(a,b,c)
	d=(x-a)/b
	e=(y+2-c)*d/4
	if d>=0 and d<=1 and e>=-1.2 and e<=1.2 then
		y-=4*d-2
		yv=-5*d
		xv=b*d*0.3
	end
end

Files

pinball.zip Play in browser
3 days ago
pinball.p8.png 5 kB
3 days ago

Get 1k Pinball #Pico1k

Leave a comment

Log in with itch.io to leave a comment.