Nibbles Game by SandraD28th Jun 2004 9:48
|
---|
Summary Improved Nibbles game. More commentary. Description First a reply to a forum message, this is my first complete game. Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com rem Nibbles Version 1.1 rem by SandraD 06/16/04 rem **main source** rem 06/28/04 additional comments added rem to explain what's going on, and added rem code to increase difficulty during play. set display mode 800, 600, 16 sync on randomize timer() hide mouse rem Load Sounds -- using windows defaults load sound "c:\windows\media\ding.wav", 1 load sound "c:\windows\media\recycle.wav",2 rem load music "canyon.mid", 1 rem globals (in DBC, as arrays) rem just in case I want to use functions for stuff. dim head(0) dim tail(0) rem this is x/y direction.... dim way(1) rem the skipper value dim lag(0) rem a score (of course) and count of worms.. dim score(0) dim worms(0) rem put up to 5 targets on screen rem #6 is a "fast zero" dim targets(6,3) dim ts(0) rem step size/world size/borders dim xsize(2) dim ysize(2) rem world time... twice... dim tim(1) rem game timing delay dim dela(0) rem I like color globals, saves wear on my brain... rem plus it's easier to change them this way. dim white(0) white(0) = rgb(255, 255, 255) dim green(0) green(0) = rgb(0, 128, 0) dim blue(0) blue(0) = rgb(0,0,192) dim gray(0) gray(0) = rgb(85, 85, 85) dim brtgrn(0) brtgrn(0) = rgb(0, 192, 0) dim red(0) red(0) = rgb(192, 0, 0) rem first scale the world, so it looks/acts the same rem for the most common video resolution settings. rem steps is desired grid horizontally... steps = 120 rem divide desired steps into display width xsize(1) = (screen width() - 20) / steps rem find size of border left-right xsize(0) = screen width() - (xsize(1) * steps) rem find actual size of the horizontital grid xsize(2) = (screen width() - xsize(0)) / xsize(1) rem convert to often used zero xsize(0) = xsize(1) + (xsize(0) / 2) rem now do the same for y, using previous x size rem ysize(2) temporarily replaces steps here... ysize(2) = (screen height() - 40) / xsize(1) ysize(1) = (screen height() - 40) / ysize(2) ysize(0) = screen height() - (ysize(1) * ysize(2)) ysize(2) = (screen height() - ysize(0)) / ysize(1) rem convert to often used zero ysize(0) = ysize(1) + ysize(0) ysize(2) = ysize(2) - 8 rem set up world and worm arrays... a = xsize(2) * ysize(2) dim worm(a, 1) dim wormsize(0) wormsize(0) = a a = xsize(2) + 1 b = ysize(2) + 1 dim world(a, b) rem we come here on each start... start: worms(0) = 3 rem a place to re-enter... rem reset the game for another pass. restart: dela(0) = 100 tim(1) = 0 tim(0) = 1 running = 0 whoa = timer() way(1) = 0 way(0) = 0 for x = 0 to wormsize(0) worm(x,0) = 0 worm(x,1) = 0 next x for y = 0 to ysize(2) for x = 0 to xsize(2) world(x, y) = 0 next x next y for x = 0 to 6 targets(x, 0) = 0 targets(x, 1) = 0 targets(x, 2) = 0 targets(x, 3) = 0 next x ts(0) = 0 rem print the title.... cls gray(0) ink white(0), 0 d = text size() set text font "Arial" set text size 30 center text screen width()/2,10,"Nibbles by SandraD v1.1" set text size d rem set up play area... ink green(0), 0 c = (xsize(1)*xsize(2)) d = (ysize(1)*ysize(2)) sbox(1, 1, c, d) ink brtgrn(0), 0 sbox(0, 0, c, ysize(1)) sbox(0, 0, xsize(1), d) sbox(c, 0, xsize(1), d+ysize(1)) sbox(0, d, c, ysize(1)) rem init starting values... worm(0, 0) = rnd(xsize(2)-2) + 1 worm(0, 1) = rnd(ysize(2)-2) + 1 world(worm(0, 0), worm(0, 1)) = 1 head(0) = 0 tail(0) = 0 lag(0) = 3 rem show starting position ink white(0), 0 sbox(worm(0, 0) * xsize(1), worm(0, 1) * ysize(1), xsize(1), ysize(1)) rem because this is a simple game, let's do rem everything in the main loop .... rem loop music 1 do rem I do this for user input... rem way() is set to inc/dec loop1: if upkey() if running = 0 then running = 1 way(0) = 0 way(1) = -1 endif if downkey() if running = 0 then running = 1 way(0) = 0 way(1) = 1 endif if leftkey() if running = 0 then running = 1 way(0) = -1 way(1) = 0 endif if rightkey() if running = 0 then running = 1 way(0) = 1 way(1) = 0 endif rem this is a testing display..... rem it shows the world map in game colors, rem then waits for a key to continue if spacekey() for y = 0 to ysize(2) for x = 0 to xsize(2) a = world(x,y) if a = 0 then ink green(0),0 if a = 1 then ink white(0),0 if a = 2 then ink blue(0),0 if a>2 or a<0 then ink 0, 0 sbox(x*xsize(1), y*ysize(1), xsize(1), ysize(1)) next x next y sync suspend for key endif rem this slows the proggie down a little.... if whoa + dela(0) < timer() whoa = timer() else goto loop1 endif rem now we handle movement... rem the worm() array is a ring buffer rem with the head as input and the tail rem as output, using the tail for eraser. rem when the worm grows, the tail rem lags further and further behind rem the head. if running = 1 head(0) = head(0) + 1 if head(0) > wormsize(0) head(0) = 0 worm(head(0), 0) = worm(wormsize(0), 0) + way(0) worm(head(0), 1) = worm(wormsize(0), 1) + way(1) else worm(head(0), 0) = worm(head(0)-1, 0) + way(0) worm(head(0), 1) = worm(head(0)-1, 1) + way(1) endif tim(0) = tim(0) + 1 rem locals to make box comand less complex to read. ink white(0), 0 a = worm(head(0), 0) * xsize(1) b = worm(head(0), 1) * ysize(1) sbox(a, b, xsize(1), ysize(1)) if lag(0) lag(0) = lag(0) - 1 else ink green(0), 0 a = worm(tail(0), 0) * xsize(1) b = worm(tail(0), 1) * ysize(1) sbox(a, b, xsize(1), ysize(1)) world(worm(tail(0), 0), worm(tail(0), 1)) = 0 tail(0) = tail(0) + 1 ink white(0), 0 if tail(0) > wormsize(0) then tail(0) = 0 endif rem now confine to the sides... if worm(head(0),0) < 1 or worm(head(0),0) > xsize(2)-1 then running = 3 if worm(head(0),1) < 1 or worm(head(0),1) > ysize(2)-1 then running = 3 endif rem next up, creating targets to gobble... rem first an empty world location is found, rem then a target value and display time rem is selected at random. if running = 1 and ts(0) < 4 and tim(1) < tim(0) tim(1) = tim(0) + rnd(100) if rnd(75) > 10 a = rnd(xsize(2) - 4) + 1 b = rnd(ysize(2) - 4) + 1 v = 0 if ts(0) <> 0 for w = 0 to ts(0) if (targets(w, 2) => a) and (targets(w, 2) + 2 <= a) and (targets(w, 3) => b) and (targets(w, 3) + 2 <= b) then v = 1 next w endif if v = 0 c = 0 for y = 0 to 3 for x = 0 to 3 c = c + world(a + x, b + y) next x next y if c=0 targets(ts(0), 0) = rnd(80) + 100 targets(ts(0), 1) = rnd(14) + 1 targets(ts(0), 2) = a targets(ts(0), 3) = b for y = 0 to 2 for x = 0 to 2 world(a+x, b+y) = 2 next x next y ink blue(0), 0 x = a*xsize(1) y = b*ysize(1) sbox(x, y, xsize(1)*3, ysize(1)*3) ink white(0), 0 f# = .85 if targets(ts(0), 1) > 9 then f# = .15 set cursor x+xsize(0)+xsize(1)*f#, y+ysize(0)+ysize(1)*.15 print targets(ts(0), 1); ts(0) = ts(0) + 1 endif endif endif endif rem here we detect hits.... rem do targets first.... if running = 1 if world(worm(head(0), 0), worm(head(0), 1)) = 2 v = 0 for w = 0 to ts(0) if (worm(head(0),0) => targets(w, 2)) and (worm(head(0),0) <= (targets(w, 2) + 3)) if (worm(head(0),1) => targets(w, 3)) and (worm(head(0),1) <= (targets(w, 3) + 3)) then v = w + 1 endif next w prise: if v play sound 1 score(0) = score(0) + targets(v - 1, 1) lag(0) = targets(v - 1, 1) targets(v - 1, 0) = 2 world(worm(head(0), 0), worm(head(0), 1)) = 1 rem this speeds up movement for each target hit if dela(0) > 1 then dela(0) = dela(0) - 1 endif else rem and now we do the body test... if world(worm(head(0), 0), worm(head(0), 1)) = 1 running = 2 else rem if nothing found, set head as body... world(worm(head(0), 0), worm(head(0), 1)) = 1 endif endif endif rem now we have to un-target... rem because targets have time values, rem we decrement them, then remove rem any target when the time is up. rem if a target is hit, it's time is dropped rem to two, so this code removes them rem too. if running = 1 and ts(0) <> 0 v = 0 for w = 0 to 5 if targets(w, 0) > 0 then targets(w, 0) = targets(w, 0) - 1 if targets(w, 0) = 1 and targets(w, 1) <> 0 a = targets(w, 2) b = targets(w, 3) for y = 0 to 2 for x = 0 to 2 if world(a+x, b+y) = 2 ink green(0), 0 world(a+x, b+y) = 0 sbox((a+x)*xsize(1), (b+y)*ysize(1), xsize(1), ysize(1)) endif if world(a+x, b+y) = 1 ink white(0), 0 world(a+x, b+y) = 0 sbox((a+x)*xsize(1), (b+y)*ysize(1), xsize(1), ysize(1)) endif next x next y v = 1 endif next w if v loop2: v = 0 for w = 0 to 5 if targets(w, 0) = 1 and targets(w, 1) <> 0 then v = 1 if v targets(w, 0) = targets(w+1, 0) targets(w, 1) = targets(w+1, 1) targets(w, 2) = targets(w+1, 2) targets(w, 3) = targets(w+1, 3) endif next w ts(0) = ts(0) - 1 if ts(0) < 0 then ts(0) = 0 if v = 1 then goto loop1 endif endif rem score printing... ink gray(0), 0 box 0, 0, 70, 25 ink white(0), 0 set text size 25 center text 35, 5, str$(score(0)) a$ = "Worms: " + str$(worms(0)) center text screen width() - 85, 5, a$ rem message box calculations... a = xsize(2)/4*xsize(1) b = ysize(2)/4*ysize(1) c = xsize(2)/2*xsize(1) d = ysize(2)/3*ysize(1) rem Now we come to the win/lose... rem running = 0 if not started rem = 1 if crawling rem = 2 if biting self rem = 3 if at edges rem = 4 if exiting if running = 2 ink red(0), 0 sbox(a-xsize(1), b-ysize(1), c, d) ink 0, 0 sbox(a, b, c-2*xsize(1), d-2*ysize(1)) ink white(0), 0 set text size 80 center text 2*xsize(1)+a+c/2, b+d/2, "Ouch!" play sound 2 wait 5000 running = 4 endif if running = 3 ink red(0), 0 sbox(a-xsize(1), b-ysize(1), c, d) ink 0, 0 sbox(a, b, c-2*xsize(1), d-2*ysize(1)) ink white(0), 0 set text size 80 center text 6*xsize(1)+a+c/2, b+d/2, "Myopia?" play sound 2 wait 5000 running = 4 endif if running = 4 then exit sync loop rem stop music 1 rem come here after crashing or quitting.... worms(0) = worms(0) - 1 if worms(0) > 0 then goto restart if worms(0) = 0 ink 0, 0 sbox(a, b, c-2*xsize(1), d-2*ysize(1)) ink white(0), 0 set text size 50 center text 6*xsize(1)+a+c/2, b+d/2, "Play Again?"; getit: sync a$ = inkey$() if a$ = "" then goto getit if mid$(a$,1) = "y" then goto start if mid$(a$,1) = "Y" then goto start endif rem though unnecessary, I like unloading things before exit... bubye: undim head(0) undim tail(0) undim way(1) undim lag(0) undim score(0) undim worms(0) undim targets(6,3) undim ts(0) undim tim(1) undim white(0) undim green(0) undim blue(0) a = xsize(2) + 1 b = ysize(2) + 1 undim worm(a, 1) undim wormsize(0) undim world(a, b) undim xsize(2) undim ysize(2) delete sound 1 delete sound 2 rem delete music 1 show mouse set display mode 640, 480, 16 end rem I don't like end-point box commands, they rem confuse me. So this one is x, y, wide & high... function sbox(x, y, w, h) box x+xsize(0), y+ysize(0), x+w+xsize(0)-1, y+h+ysize(0)-1 endfunction |