'FALL STOP - swing, tap, drop, land. 'TODO: provide different palette for 1 and 2 and swap at each try 'pal#0 bottle 'pal#1 rope, landing pad 'pal#2 ground 'pal#3 city, bottle reflect 'pal#4 hud 'bg#0 text 'bg#1 rope only, one column scrolled per scanline 'bg#2 landing pad only 'bg#3 rope holder, groud, city 'spr#100 bottle reflect 'spr#101 bottle 'spr#101 rope tip 'pram$e000 2bytes high score 'pram$e002 16bytes seed 'file#3 rope holder 'file#4 landing pads 'file#5 hud 'file#6 city 'file#7 alternative palette 'the whole playfield area is bounded to 23x36 'all physics computation are 0x0 based coords, then the whole drawing operation are shifted using 'SCROLL' to center it 'the rope is drawn with the raster interrupt by shifting it's pixel using 'SCROLL' '''DATA difficulty_data: 'r max score 'w pad width in cells 'x,y pad bg copy params 'i,a pad min and max height offset from play field in pixel 'm rope amplitude 's rope swing force 'l rope length from pivot in pixel 'o pad max x offset from center in pixel 'u score multiplier ' r w x y i a m s l o u data 00100 ,8 ,0,00 ,100,100 ,0.06,0.00044,50 ,00 ,1 data 00400 ,6 ,0,04 ,150,180 ,0.08,0.00044,50 ,20 ,1.11 data 00800 ,5 ,0,08 ,170,200 ,0.10,0.00066,99 ,70 ,1.22 data 01000 ,4 ,0,12 ,170,240 ,0.12,0.00066,25 ,40 ,1.33 data 02000 ,3 ,0,16 ,150,240 ,0.14,0.00088,50 ,80 ,1.55 data 03000 ,2 ,0,20 ,150,270 ,0.16,0.00088,50 ,60 ,1.88 data 99999 ,3 ,0,16 ,100,100 ,0.18,0.00088,50 ,90 ,1.88 bottle_frames: 'list of characters for bottle spinning animation data 16,19,22,25,28 data 64,67,70,73,76 'additionnal frame for when the bottle land on the pad data 112,115,118,121,124 'cache it for quick access dim bfs(14) restore bottle_frames for bf=0 to 14 :read bfs(bf) :next bf reflect_frames: 'follow the bottle orientation data 192,194,196,198,200 data 202,204,206,224,224 data 192,192,192,192,192 'same but flipped data 192,204,202,198,226 data 196,194,228,230,230 data 192,192,192,192,192 dim rfs(29) restore reflect_frames for bf=0 to 29 :read rfs(bf) :next bf '''ROPE 'rnx= layer 1 scroll value at scanline 0 'rsl= pixels the rope gains on every scanline global rnx,rsl,winy rnx=0 :rsl=0 sub r scroll 1,rnx-(raster-winy+1)*rsl, end sub '''NEEDED 'to detect layout changes shownw=0 :shownh=0 'to center the 23x36cells window in the center according shown.w and shown.h winx=0 :winy=0 'center rope pivot point inside the window pivx=23*8/2 'bottle frame bf=0 'reflect flip frame offset rf=0 'landing pad width in cell padw=0 'bg copy coord padxc=0 :padyc=0 'landing pad position: left, right and top boundaries in pixels padl=0 :padr=0 :padt=0 'distance from top of playing field and landing pad in pixel distmin=0 :distmax=0 'ground position in pixel groundy=34*8 'fall acceleration in pixels per frame grav=0.34 'part of the slide speed kept every frame fric=0.72 'the slide stops below this speed slowv=0.08 'random seed if peekl($e002)=0 then randomize 123,$e002 'state '0= swinging '1= falling '2= sliding '3= landed '4= missed st=0 'hold during a number of frame hold=45 hld=0 'score reducer per swing reduce=20 rdc=0 'initial score score=0 best=peekw($E000) 'initial difficulty gosub difficulty sw=amp :av=0 'initial palette gosub colorize '''MAIN 'kickstart sound generator, avoid framedrop volume 0,,0 play 0,1 stop 0 volume 0,,3 font 160 on raster call r 'setup sprite size and palette sprite 100 pal 3 size 1 sprite 101 pal 0 size 2 sprite 102 pal 1 do 'detect layout changes if shownw<>shown.w or shownh<>shown.h then shownw=shown.w :shownh=shown.h gosub layout gosub hud gosub redraw 'seed the tip at the angle the rope is really at, otherwise the first 'frame sees it jump from straight down and hands out a huge momentum tipx=pivx+rlen*cos(0.75+sw) :tipy=rlen*sin(0.75+sw) otipx=tipx :otipy=tipy end if 'swing the rope otipx=tipx :otipy=tipy oav=av add sw,av add av,swkc*sin(sw) 'compute rope tip position tipx=pivx+rlen*cos(0.75+sw) tipy=rlen*sin(0.75+sw) 'reduce score at each swing if oav<>0 and sgn(av)<>sgn(oav) and score>0 then score=max(100,score-rdc) gosub hud end if 'compute rope line linear parameters rsl=(tipx-pivx)/(tipy) rnx=1-pivx-winx 'compute and draw rope cy1=int(tipy)\8 bg 1 :pal 1 bg fill 0,0 to 0,63 char 0 if cy1>0 then bg fill 0,0 to 0,cy1-1 char 15 cell 0,cy1,8+(int(tipy) mod 8) 'update according to the state on st gosub s_swing, s_fall, s_slide, s_over, s_over 'draw bottle and rope tip sprite 100,bx-4+winx,by+4+winy,rfs(bf+rf) sprite 101,bx-8+winx,by+winy,bfs(bf) sprite 102,tipx-4+winx,tipy-4+winy,4 wait vbl loop '''STATES s_swing: 'the bottle is attached to the rope tip 'compute rop tip position bx=tipx-4 :by=tipy-4 vx=tipx-otipx :vy=tipy-otipy sprite 101 flip abs(vx>0),0 rf=abs(vx>0)*15 if tap then st=1 play 0,64,4 end if return s_fall: 'the bottle falling free after being detached from the rope oby=by 'compute gravity add vy,grav add bx,vx add by,vy if bf<9 then add bf,1/2 'check if bottle land on the pad if vy>0 and oby+20<=padt and by+20>=padt then if bx+7>=padl and bx+1=groundy then by=groundy-20 st=4 bf=0 hld=hold score=0 play 1,20,20 rdc=0 end if return 'sliding on the platform s_slide: 'compute slide and friction add bx,vx if bf<14 then add bf,1/2 vx=vx*fric 'left the pad and fall again if bx+7=padr then st=1 vy=0 'bottle stop sliding else if abs(vx)=threshold and threshold<99999 skip 10 :read threshold wend read padw, padxc, padyc, distmin, distmax, amp, swkc, rlen, padoff, multiplier padt=rnd(distmax-distmin,$e002)+distmin padl=(23-padw)*8\2+padoff*(rnd $e002)*((rnd(1,$e002)*2)-1) padr=padl+padw*8 return redraw: 'redraw pad 'draw the pad bg 2 :cls 2 bg source rom(4) bg copy padxc,padyc,8,4 to 0,0 scroll 2,-padl-winx,-padt-winy 'draw below the pad until it reach the floor t=padt+4*8 :y=4 while t