'=========================================================================== ' Subject: PACMAN LIVES! Date: 07-18-96 (23:20) ' Author: Steven Hanov Code: QB, QBasic, PDS ' Origin: hanovs@wchat.on.ca Packet: GAMES.ABC '=========================================================================== '************************************************************************** '** PACMAN LIVES! ** '**** By Steven Hanov (hanovs@wchat.on.ca) ** '************************************************************************** '** July 1996 ** '** Well, here's MY attempt at Pacman for QBASIC. I derived this game ** '** from the Commodore 64 version, which was probably based on the Atari ** '** version. Quite a long history! I think it even had a cartoon show... ** '** On a 386, like mine :-(, a speed factor of zero should be used. The ** '** graphics routines are slower than I'd have liked, but that's life. ** '** If anyone manages to speed it up greatly, I'd appreciate a copy. ** '** Just e-mail it to me. ** '************************************************************************** DECLARE SUB pacprint (y!, text$) DECLARE SUB KillPac () DECLARE SUB DisplayLives (lives!) DECLARE SUB UpdateScore () DECLARE SUB RedGhost () DECLARE SUB GreenGhost () DECLARE SUB BlueGhost () DECLARE SUB CreateGhost (colour!, frame!) DECLARE SUB DrawPac (xx!, yy!, dr!) DIM SHARED pf(-1 TO 81, 25) AS STRING, PacGraph(628) DIM SHARED BGhost1(628), rGhost1(628), gGhost1(628), ZGhost1(628) DIM SHARED BGhost2(628), rGhost2(628), GGhost2(628), ZGhost2(628) DIM SHARED death, PowerUp, PTimer, xx, yy, Score, DontCallGhosts DIM SHARED GameSpeed '********************************************************************* '** VARIABLE Dictionary ********************************************** 'pf(x,y) contains the playing field, * for walls, . for dashes, o for powerup 'PacGraph, and the Ghosts store the "sprites" of pacman circle and ghosts 'death - Set by ghost sub to notify main that Pacman has been killed 'PowerUp - 1 if currently Powered Up, zero otherwise 'PTimer - The timer at the time Pacman got powerup. 'xx,yy - usually The current 320x200 screen position 'x,y - usually the current 40x25 screen position 'DontCallGhosts - Flag used to make DrawPac not call Ghosts 'GameSpeed - Slow down factor rt$ = CHR$(0) + "M" 'define right, left, up, down keys lt$ = CHR$(0) + "K" up$ = CHR$(0) + "H" dn$ = CHR$(0) + "P" SCREEN 12 CIRCLE (150, 200), 150, 14 PAINT (150, 200), 14 LINE (150, 200)-(300, 160), 15 LINE -(300, 240), 15 LINE -(150, 200) PAINT (160, 200), 0, 15 'The next several lines draw LINE (150, 200)-(300, 160), 0 'the title screen... LINE -(300, 240), 0 LINE -(150, 200), 0 CIRCLE (175, 125), 30, 0 PAINT (175, 125), 15, 0 CIRCLE (180, 130), 20, 0 PAINT (180, 130), 0, 0 CIRCLE (500, 150), 100, 4 PAINT (500, 150), 4 LINE (400, 150)-(400, 400), 4 LINE (600, 150)-(600, 400), 4 DRAW "BM600,400 H20 G20 H20 G20 H20 G20 H20 G20 H20 G20" PAINT (500, 300), 4 CIRCLE (450, 150), 25, 0 CIRCLE (550, 150), 25, 0 PAINT (450, 150), 15, 0 PAINT (550, 150), 15, 0 CIRCLE (440, 150), 12, 0 CIRCLE (540, 150), 12, 0 PAINT (440, 150), 0 PAINT (540, 150), 0 CIRCLE (500, 225), 30, 0, , , .5 PAINT (500, 225), 0, 0 COLOR 9 x = 25 y = 0 LINE (x, y)-(x + 30, y + 100), 9, BF CIRCLE (x + 35, y + 31), 30, 9 PAINT (x + 35, y + 31), 9, 9 CIRCLE (x + 35, y + 31), 2, 0 PAINT (x + 35, y + 31), 0, 0 x = x + 60 LINE (x + 40, y)-(x, y + 100) LINE -(x + 80, y + 100) LINE -(x + 40, y) PAINT (x + 40, y + 50), 9, 9 CIRCLE (x + 40, y + 50), 2, 0 PAINT (x + 40, y + 50), 0, 0 x = x + 90 CIRCLE (x + 40, y + 50), 50 PAINT (x + 40, y + 50), 9, 9 LINE (x + 40, y + 50)-(x + 90, y + 20), 0 LINE -(x + 90, y + 80), 0 LINE -(x + 40, y + 50), 0 PAINT (x + 60, y + 50), 0, 0 x = x + 90 LINE (x + 10, y + 40)-(x + 40, y + 60), 9, BF x = x + 50 LINE (x, y)-(x, y + 100), 9 LINE -(x + 90, y + 100), 9 LINE -(x + 90, y), 9 LINE -(x + 45, y + 50), 9 LINE -(x, y), 9 PAINT (x + 45, y + 75), 9, 9 x = x + 100 LINE (x + 40, y)-(x, y + 100) LINE -(x + 80, y + 100) LINE -(x + 40, y) PAINT (x + 40, y + 50), 9, 9 CIRCLE (x + 40, y + 50), 2, 0 PAINT (x + 40, y + 50), 0, 0 x = x + 90 LINE (x, y)-(x, y + 100), 9 LINE -(x + 90, y + 100), 9 LINE -(x + 90, y), 9 LINE -(x + 60, y), 9 LINE -(x + 60, y + 50), 9 LINE -(x, y), 9 PAINT (x + 30, y + 30), 9, 9 COLOR 15 LOCATE 8, 36 PRINT "Lives!" LOCATE 28, 20 COLOR 9 PRINT "Coded by Steven Hanov (hanovs@wchat.on.ca)" WHILE INKEY$ = "": WEND SCREEN 7 'OK, now the real program begins! RANDOMIZE TIMER CLS CIRCLE (12, 12), 5, 14 PAINT (12, 12), 14 GET (7, 7)-(17, 17), PacGraph CreateGhost 9, 1 'Create and store "sprites" GET (1, 0)-(11, 9), BGhost1 CreateGhost 9, 2 GET (1, 0)-(11, 9), BGhost2 CreateGhost 4, 1 GET (1, 0)-(11, 9), rGhost1 CreateGhost 4, 2 GET (1, 0)-(11, 9), rGhost2 CreateGhost 2, 1 GET (1, 0)-(11, 9), gGhost1 CreateGhost 2, 2 GET (1, 0)-(11, 9), GGhost2 CreateGhost 1, 1 GET (1, 0)-(11, 9), ZGhost1 CreateGhost 1, 2 GET (1, 0)-(11, 9), ZGhost2 CLS pacprint 5, "Enter a delay factor, to" pacprint 6, "slow down the game for" pacprint 7, "fast computers. (0-15)" LOCATE 9, 18: INPUT ">", a$ GameSpeed = VAL(a$) * 100 Start: CLS RESTORE lives = 3 y = 0 xx = 0 yy = 0 DO READ a$ 'Read in, store, and display IF a$ = "STOP" THEN EXIT DO 'the playing field. (Stored in pf()) yy = yy + 1 FOR xx = 1 TO LEN(a$) y = yy * 8 - 8 x = xx * 8 - 8 B$ = MID$(a$, xx, 1) IF B$ = "." THEN LOCATE yy, xx + 1 LINE (x + 3, y + 4)-(x + 5, y + 5), 14, B pf(xx, yy) = B$ dots = dots + 1 ELSEIF B$ = "o" THEN LOCATE yy, xx + 1 CIRCLE (x + 4, y + 4), 3, 14 PAINT (x + 4, y + 4), 14, 14 pf(xx, yy) = B$ ELSEIF B$ = " " THEN PRINT " "; pf(xx, yy) = " " ELSE COLOR 1 'For simplicity, all wall blocks are PRINT B$; 'stored in pf() array as "*"'s pf(xx, yy) = "*" END IF NEXT PRINT LOOP DO x = 20 y = 18 xx = x * 8 - 8 yy = y * 8 - 8 dr = 4 DisplayLives lives PCOPY 0, 1 DrawPac xx + 1, yy, 4 DrawPac xx, yy, 4 a$ = "" DO 'This big DO-LOOP is the heart of the IF LEN(c$) = 0 THEN 'program, detecting keys and moving B$ = INKEY$ 'pacman. ELSE B$ = c$ c$ = "" END IF DrawPac xx, yy, dr IF LEN(B$) > 0 THEN IF B$ = CHR$(27) THEN CLS : GOTO Quit free = 0 IF B$ = up$ AND pf(x, y - 1) <> "*" THEN free = free + 1 IF B$ = rt$ AND pf(x + 1, y) <> "*" THEN free = free + 1 IF B$ = dn$ AND pf(x, y + 1) <> "*" THEN free = free + 1 IF B$ = lt$ AND pf(x - 1, y) <> "*" THEN free = free + 1 IF free > 0 THEN a$ = B$ c$ = "" END IF END IF IF a$ = rt$ AND pf(x + 1, y) <> "*" THEN dr = 2 FOR s = 1 TO 8 xx = xx + 1 DrawPac xx, yy, dr NEXT x = x + 1 IF x = 39 THEN x = 1: xx = 1: DrawPac xx, yy, dr ELSEIF a$ = lt$ AND pf(x - 1, y) <> "*" THEN dr = 4 FOR s = 1 TO 8 xx = xx - 1 DrawPac xx, yy, dr IF xx = 1 THEN x = 40: xx = 39 * 8 - 8 NEXT x = x - 1 ELSEIF a$ = up$ AND pf(x, y - 1) <> "*" THEN dr = 1 FOR s = 1 TO 8 yy = yy - 1 DrawPac xx, yy, dr NEXT y = y - 1 ELSEIF a$ = dn$ AND pf(x, y + 1) <> "*" THEN dr = 3 FOR s = 1 TO 8 yy = yy + 1 DrawPac xx, yy, dr NEXT y = y + 1 END IF IF pf(x, y) = "." THEN Score = Score + 10 pf(x, y) = " " dots = dots - 1 SOUND 800, .25 SOUND 900, .25 UpdateScore IF dots = 0 THEN EXIT DO ELSEIF pf(x, y) = "o" THEN PowerUp = 1 pf(x, y) = " " Score = Score + 100 UpdateScore FOR s = 37 TO 4000 STEP 20 SOUND s, .05 SOUND s + 100, .05 SOUND s + 200, .05 SOUND s + 300, .05 NEXT PTimer = TIMER END IF IF xx MOD 8 = 1 THEN xx = xx - 1 IF death = 1 THEN KillPac: EXIT DO LOOP IF dots = 0 THEN EXIT DO lives = lives - 1 DisplayLives lives death = 0 LOOP UNTIL lives = -1 CLS COLOR 4 IF lives = -1 THEN pacprint 10, "You LOSE!" ELSE pacprint 10, "You WIN!" END IF SLEEP 1 Quit: COLOR 15 pacprint 15, "Final Score:" + STR$(Score) COLOR 9 pacprint 20, "ENTER to play again, or ESC to exit" DO a$ = INKEY$ LOOP UNTIL a$ = CHR$(27) OR a$ = CHR$(13) IF a$ = CHR$(27) THEN SCREEN 0: COLOR 7: END IF a$ = CHR$(13) THEN GOTO Start ' 1234567890123456789012345678901234567890 DATA "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»" DATA "º..................º..................º" DATA "º.ÚÄÄÄÄ¿.ÚÄÄÄÄÄÄÄ¿.º.ÚÄÄÄÄÄÄÄ¿.ÚÄÄÄÄ¿.º" DATA "º.³ ³.³ ³.º.³ ³.³ ³.º" DATA "ºoÀÄÄÄÄÙ.ÀÄÄÄÄÄÄÄÙ.º.ÀÄÄÄÄÄÄÄÙ.ÀÄÄÄÄÙoº" DATA "º.....................................º" DATA "º.ÍÍÍÍÍÍ.ÚÄ¿.ÍÍÍÍÍÍËÍÍÍÍÍÍ.ÚÄ¿.ÍÍÍÍÍÍ.º" DATA "º........³ ³.......º.......³ ³........º" DATA "ÈÍÍÍÍÍÍ».³ ÆÍÍÍÍÍÍ º ÍÍÍÍÍ͵ ³.ÉÍÍÍÍÍͼ" DATA " º.³ ³ ³ ³.º " DATA "ÍÍÍÍÍÍͼ.ÀÄÙ ÚÄÄÄÄÄ ÄÄÄÄÄ¿ ÀÄÙ.ÈÍÍÍÍÍÍÍ" DATA " .......... ³ ³ .......... " DATA "ÍÍÍÍÍÍÍ».ÚÄ¿ ÀÄÄÄÄÄÄÄÄÄÄÄÙ ÚÄ¿.ÉÍÍÍÍÍÍÍ" DATA " º.³ ³ ³ ³.º " DATA "ÉÍÍÍÍÍͼ.ÀÄÙ ÍÍÍÍÍÍËÍÍÍÍÍÍ ÀÄÙ.ÈÍÍÍÍÍÍ»" DATA "º..................º..................º" DATA "º.ÍÍÍÍÍ».ÍÍÍÍÍÍÍÍÍ.º.ÍÍÍÍÍÍÍÍÍ.ÉÍÍÍÍÍ.º" DATA "ºo.....º.......................º.....oº" DATA "ÌÍÍÍÍÍ.º.ÚÄ¿.ÍÍÍÍÍÍËÍÍÍÍÍÍ.ÚÄ¿.º.ÍÍÍÍ͹" DATA "º........³ ³.......º.......³ ³........º" DATA "º.ÍÍÍÍÍÍÍÏÍÏÍÍÍÍÍÍ.º.ÍÍÍÍÍÍÏÍÏÍÍÍÍÍÍÍ.º" DATA "º.....................................º" DATA "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ" DATA STOP 'Takes care of blue ghost. 'And I mean it takes care of EVERYTHING: 'Drawing, artificial intelligence, killing Pacman, Killing itself...etc. ' SUB BlueGhost 'VARIABLES: 'px,py - current pixel position 'PrevX,PrevY - previous pixel position (for erasing) 'flag - First time called? 'xdir, ydir - Which direction am I going in? (incremental values) STATIC frame, PrevX, PrevY, flag, px, py, xdir, ydir IF flag = 0 THEN flag = 1 'If first time called, PrevX = 17 * 8 - 8 'Set ghost to default position PrevY = 12 * 8 - 8 px = PrevX py = PrevY xdir = 1 'Start off going right ydir = 0 END IF IF PowerUp = 1 THEN speed = .5 'Powerup means half speed of ghosts ELSE speed = 1 END IF LINE (PrevX, PrevY)-(PrevX + 10, PrevY + 9), 0, BF 'ERase previous draw IF px MOD 8 = 0 AND py MOD 8 = 0 THEN 'If you're centered on 8x8 box, x = (px \ 8) + 1 'Calculate real 40x25 screen position y = (py \ 8) + 1 IF pf(x - xdir, y - ydir) = "." THEN 'Redraw the pellet you passed xp = CINT(px) - 8 * xdir 'over yp = CINT(py) - 8 * ydir LINE (xp + 3, yp + 4)-(xp + 5, yp + 5), 14, B ELSEIF pf(x - xdir, y - ydir) = "o" THEN 'redraw the powerup you passed xp = CINT(px) - 8 * xdir 'over yp = CINT(py) - 8 * ydir CIRCLE (xp + 4, yp + 4), 3, 14 PAINT (xp + 4, yp + 4), 14, 14 END IF IF pf(x, y + 1) <> "*" THEN free = free + 1 'Count the number of choices IF pf(x + 1, y) <> "*" THEN free = free + 1 'of directions without walls IF pf(x, y - 1) <> "*" THEN free = free + 1 IF pf(x - 1, y) <> "*" THEN free = free + 1 IF free > 2 OR pf(x + xdir, y + ydir) = "*" THEN 'IF you HAVE a choice, DO IF RND > .5 THEN xdir = 1 ydir = 0 'Keep picking a random direction until ELSE 'you find one without a wall. ydir = 1 xdir = 0 END IF IF RND > .5 THEN xdir = -xdir: ydir = -ydir IF pf(x + xdir, y + ydir) <> "*" THEN EXIT DO LOOP END IF END IF px = px + xdir * speed 'Move the px,py co-ordinate py = py + ydir * speed IF px > 309 THEN px = 1 'Scroll from one side of screen to other IF CINT(px) = 0 THEN px = 304 frame = frame + 1: IF frame = 2 THEN frame = 0 'Ghosts have two frames for IF frame = 0 THEN 'animation IF PowerUp = 1 THEN PUT (px, py), ZGhost1 'You have powerup, show scared ghost ELSE PUT (px, py), BGhost1 'Show regular ghost END IF ELSE IF PowerUp = 1 THEN 'OR frame 2 of same. PUT (px, py), ZGhost2 ELSE PUT (px, py), BGhost2 END IF END IF PrevX = CINT(px) PrevY = CINT(py) gx = (px \ 8) + 1 gy = (py \ 8) + 1 IF gx = xx \ 8 + 1 AND gy = yy \ 8 + 1 THEN 'If you hit Pacman, IF PowerUp = 1 THEN Score = Score + 200 'And he has powerup, kill ghost UpdateScore FOR s = 37 TO 5000 STEP 500 SOUND s, 1 NEXT flag = 0 ELSE death = 1 'OR else kill Pacman. END IF END IF END SUB SUB CreateGhost (colour, frame) CLS CIRCLE (6, 3), 5, colour, 0, 6.28, .5 LINE (1, 3)-(11, 8), colour, BF PAINT (6, 2), colour, colour CIRCLE (3, 3), 1, 15 CIRCLE (9, 3), 1, 15 PSET (3, 3), 15 PSET (9, 3), 15 SELECT CASE frame CASE 1 DRAW "BM1,9 C" + STR$(colour) + " e1f1e1f1e1F1e1f1e1f1" PSET (4, 3), 0 PSET (10, 3), 0 CASE 2 DRAW "BM1,8 C" + STR$(colour) + " f1e1f1e1f1e1f1e1f1e1" PSET (2, 3), 0 PSET (8, 3), 0 END SELECT IF colour = 1 THEN DRAW "BM2,7 C0 e1r1f1r1e1r1f1r1" END IF END SUB SUB DisplayLives (lives) x = 308 y = 187 LINE (x + 5, y - 5)-(x - 100, y + 5), 0, BF FOR s = 1 TO lives GOSUB TinyPac x = x - 16 NEXT EXIT SUB TinyPac: CIRCLE (x - 1, y), 4, 14 PAINT (x - 1, y), 14, 14 LINE (x, y)-(x - 5, y - 2), 0 LINE (x, y)-(x - 5, y + 2), 0 LINE -(x - 5, y - 2), 0 PAINT (x - 3, y), 0, 0 RETURN END SUB SUB DrawPac (xx, yy, dr) STATIC a, PrevX, PrevY, flag, adir FOR s = 1 TO GameSpeed: NEXT IF flag = 0 THEN 'If first time called, set PrevX,Y to same as xx,yy adir = 1 flag = 1 PrevX = xx PrevY = yy END IF IF xx = 0 THEN xx = 1 'Solves mysterious problem. IF PrevX <> xx OR PrevY <> yy THEN 'Don't redraw if standing still. a = a + adir '"a" value moves mouth IF a = 5 OR a = 0 THEN adir = -adir LINE (PrevX - 1, PrevY)-(PrevX + 10, PrevY + 8), 0, BF PUT (xx - 1, yy - 1), PacGraph SELECT CASE dr 'dr is direction:1=up, clockwise. CASE 1 LINE (xx + 4, yy + 5)-(xx + 4 - a, yy), 0 LINE (xx + 4, yy + 5)-(xx + 4 + a, yy), 0 LINE -(xx + 4 - a, yy), 0 PAINT (xx + 4, yy + 1), 0, 0 CASE 2 LINE (xx + 3, yy + 4)-(xx + 9, yy + 4 - a), 0 LINE (xx + 3, yy + 4)-(xx + 9, yy + 4 + a), 0 LINE -(xx + 9, yy + 4 - a), 0 PAINT (xx + 7, yy + 4), 0, 0 CASE 3 LINE (xx + 4, yy + 3)-(xx + 4 - a, yy + 8), 0 LINE (xx + 4, yy + 3)-(xx + 4 + a, yy + 8), 0 LINE -(xx + 4 - a, yy + 8), 0 PAINT (xx + 4, yy + 7), 0, 0 CASE 4 LINE (xx + 5, yy + 4)-(xx - 1, yy + 4 - a), 0 LINE (xx + 5, yy + 4)-(xx - 1, yy + 4 + a), 0 LINE -(xx - 1, yy + 4 - a), 0 PAINT (xx, yy + 4), 0, 0 END SELECT END IF PrevX = xx PrevY = yy IF TIMER - PTimer > 10 THEN PowerUp = 0 'Powerup lasts 10 seconds IF DontCallGhosts = 0 THEN RedGhost GreenGhost 'Move the three ghosts BlueGhost END IF END SUB 'For comments, see BlueGhost sub SUB GreenGhost STATIC frame, PrevX, PrevY, flag, px, py, xdir, ydir IF flag = 0 THEN flag = 1 PrevX = 17 * 8 - 8 PrevY = 12 * 8 - 8 px = PrevX py = PrevY xdir = 1 ydir = 0 END IF IF PowerUp = 1 THEN speed = .5 ELSE speed = 1 END IF LINE (PrevX, PrevY)-(PrevX + 10, PrevY + 9), 0, BF IF px MOD 8 = 0 AND py MOD 8 = 0 THEN x = (px \ 8) + 1 y = (py \ 8) + 1 IF pf(x - xdir, y - ydir) = "." THEN xp = CINT(px) - 8 * xdir yp = CINT(py) - 8 * ydir LINE (xp + 3, yp + 4)-(xp + 5, yp + 5), 14, B ELSEIF pf(x - xdir, y - ydir) = "o" THEN xp = CINT(px) - 8 * xdir yp = CINT(py) - 8 * ydir CIRCLE (xp + 4, yp + 4), 3, 14 PAINT (xp + 4, yp + 4), 14, 14 END IF IF pf(x, y + 1) <> "*" THEN free = free + 1 IF pf(x + 1, y) <> "*" THEN free = free + 1 IF pf(x, y - 1) <> "*" THEN free = free + 1 IF pf(x - 1, y) <> "*" THEN free = free + 1 IF free > 2 OR pf(x + xdir, y + ydir) = "*" THEN DO IF RND > .5 THEN xdir = 1 ydir = 0 ELSE ydir = 1 xdir = 0 END IF IF RND > .5 THEN xdir = -xdir: ydir = -ydir IF pf(x + xdir, y + ydir) <> "*" THEN EXIT DO LOOP END IF END IF px = px + xdir * speed py = py + ydir * speed IF px > 309 THEN px = 1 IF CINT(px) = 0 THEN px = 304 frame = frame + 1: IF frame = 2 THEN frame = 0 IF frame = 0 THEN IF PowerUp = 1 THEN PUT (px, py), ZGhost1 ELSE PUT (px, py), gGhost1 END IF ELSE IF PowerUp = 1 THEN PUT (px, py), ZGhost2 ELSE PUT (px, py), GGhost2 END IF END IF PrevX = CINT(px) PrevY = CINT(py) gx = (px \ 8) + 1 gy = (py \ 8) + 1 IF gx = xx \ 8 + 1 AND gy = yy \ 8 + 1 THEN IF PowerUp = 1 THEN Score = Score + 200 UpdateScore FOR s = 37 TO 5000 STEP 500 SOUND s, 1 NEXT flag = 0 ELSE death = 1 END IF END IF END SUB 'Makes Pacman eat himself. ' SUB KillPac LINE (xx - 1, yy)-(xx + 10, yy + 8), 0, BF 'Blank out background PUT (xx - 1, yy - 1), PacGraph 'Put the PacCircle there freq = 1500 'Sound values freq2 = 500 FOR y = -5 TO 5 STEP .2 LINE (xx + 4, yy + 5)-(xx + 4 + SQR(25 - y ^ 2), yy + 5 + y), 0 LINE (xx + 4, yy + 5)-(xx + 4 - SQR(25 - y ^ 2), yy + 5 + y), 0 '^ Wow! I actually found a use for grade 12 math! SOUND freq, .5 SOUND freq2, .5 freq = freq - 10 freq2 = freq2 + 10 NEXT END SUB SUB pacprint (y, text$) DontCallGhosts = 1 yy = y * 8 - 8 x = 20 - LEN(text$) \ 2 xx = x * 8 - 7 FOR letter = 1 TO LEN(text$) FOR xx = xx TO xx + 7 DrawPac xx, yy, 2 NEXT LOCATE y, x x = x + 1 PRINT MID$(text$, letter, 1) SOUND 800, .25 SOUND 900, .25 NEXT DontCallGhosts = 0 END SUB 'For comments, see BlueGhost sub SUB RedGhost STATIC frame, PrevX, PrevY, flag, px, py, xdir, ydir IF flag = 0 THEN flag = 1 PrevX = 17 * 8 - 8 PrevY = 12 * 8 - 8 px = PrevX py = PrevY xdir = 1 ydir = 0 END IF IF PowerUp = 1 THEN speed = .5 ELSE speed = 1 END IF LINE (PrevX, PrevY)-(PrevX + 10, PrevY + 9), 0, BF IF px MOD 8 = 0 AND py MOD 8 = 0 THEN x = (px \ 8) + 1 y = (py \ 8) + 1 IF pf(x - xdir, y - ydir) = "." THEN xp = CINT(px) - 8 * xdir yp = CINT(py) - 8 * ydir LINE (xp + 3, yp + 4)-(xp + 5, yp + 5), 14, B ELSEIF pf(x - xdir, y - ydir) = "o" THEN xp = CINT(px) - 8 * xdir yp = CINT(py) - 8 * ydir CIRCLE (xp + 4, yp + 4), 3, 14 PAINT (xp + 4, yp + 4), 14, 14 END IF IF pf(x, y + 1) <> "*" THEN free = free + 1 IF pf(x + 1, y) <> "*" THEN free = free + 1 IF pf(x, y - 1) <> "*" THEN free = free + 1 IF pf(x - 1, y) <> "*" THEN free = free + 1 IF free > 2 OR pf(x + xdir, y + ydir) = "*" THEN DO IF RND > .5 THEN xdir = 1 ydir = 0 ELSE ydir = 1 xdir = 0 END IF IF RND > .5 THEN xdir = -xdir: ydir = -ydir IF pf(x + xdir, y + ydir) <> "*" THEN EXIT DO LOOP END IF END IF px = px + xdir * speed py = py + ydir * speed IF px > 309 THEN px = 1 IF CINT(px) = 0 THEN px = 304 frame = frame + 1: IF frame = 2 THEN frame = 0 IF frame = 1 THEN IF PowerUp = 1 THEN PUT (px, py), ZGhost1 ELSE PUT (px, py), rGhost1 END IF ELSE IF PowerUp = 1 THEN PUT (px, py), ZGhost2 ELSE PUT (px, py), rGhost2 END IF END IF PrevX = CINT(px) PrevY = CINT(py) gx = (px \ 8) + 1 gy = (py \ 8) + 1 IF gx = xx \ 8 + 1 AND gy = yy \ 8 + 1 THEN IF PowerUp = 1 THEN Score = Score + 200 UpdateScore FOR s = 37 TO 5000 STEP 500 SOUND s, 1 NEXT flag = 0 ELSE death = 1 END IF END IF END SUB SUB UpdateScore LOCATE 24, 1 COLOR 15 PRINT Score; END SUB