QBASIC GAME : ILLINOIS JOHNSON

QBASIC GAME : ILLINOIS JOHNSON



 ' [LEFT] . . Move left
 ' [RIGHT] . Move right
 ' [UP] . . . Jump up in the direction you're facing, or
 ' move elevator upwards if on one, or move
 ' up whip line
 ' [DOWN] . . Move elevator downwards if on one, or move
 ' down whip line
 ' [CTRL] . . (Yes, the CTRL key works!) Fire Illinois
 ' Johnson's (TM) Neutron Blaster 9000 (TM);
 ' must have at least one charge
 ' [ALT] . . Throw whip upwards to latch onto special
 ' boulders
 ' [ESC] . . Quit
 
 ' You: Wall: Û Boulder: ì Air sucker: 
 ' End-of-level doorway: Special whip boulder: ø
 ' Neutron Blaster 9000 (TM) charge: Elevator: Ñ
 
 ' Notes:
 ' There's only two levels, just to give you an idea
 ' of the controls et al. Any takers on new levels?
 ' Just add more DATA statements at the end of the
 ' program (each level is 40x24) and change the end of
 ' the main program loop (IF level = 2 THEN ReallyQuit).
 ' There's a fake wall if you look closely....
 ' In the level statements, upper case indicates a
 ' solid (wall, elevator); lower case a non-solid (air,
 ' energy charge, doorway).
 ' "Falling into each level" was an accident, but I
 ' think it kinda adds a neat intro to the level....
 ' The whole game is pretty simple; in fact there are
 ' no bugs that I know of. The engine is fairly
 ' straightforward, so you should be able to skim
 ' through the code with little difficulty. It runs
 ' perfectly well in QBASIC 1.x and VBDOS. Have fun!
 ' As always, suggestions, comments, criticisms,
 ' additions, improvements, etc. are welcome.
 
 DEFINT A-Z ' All numeric variables are integers by default
 DECLARE SUB LoadNextLevel ()
 DECLARE SUB MoveBoulders (xpos, ypos)
 DECLARE SUB PrintChar (arg)
 
 CONST FALSE = 0, TRUE = NOT FALSE
 CONST LEFT = -1, RIGHT = 1 ' For player's direction
 CONST AIR.SUCKER = -6
 CONST WHIP.LINE = -5, WALL.FAKE = -4 ' Walls and stuff
 CONST ENERGY.CHARGE = -3, DOORWAY = -2
 CONST BOULDER = 1, WALL = 2, ELEVATOR = 3, ELEV.COLUMN = 4
 CONST WALL.GRAY = 5, STALACTITE = 6
 
 SCREEN 7 ' Text display at 40x25 with 16 colors
 DIM SHARED x, y, AIR
 DIM SHARED grid(1 TO 40, 1 TO 24)
 DIM direction$(LEFT TO RIGHT)
 direction$(LEFT) = CHR$(27) ' Arrows for displaying direction
 direction$(RIGHT) = CHR$(26)
 direction = RIGHT
 level = 0
 DO
 quit = 0
 LoadNextLevel
 GOSUB PrintLevel
 ox = x: oy = y
 ENERGY = 0 ' No spare charges
 whipactive = FALSE ' Not currently using whip
 Display = TRUE: GetInput = TRUE
 level = level + 1
 DO
 GOSUB ProcessInput
 GOSUB DoAir
 GOSUB PrintAll
 i$ = INKEY$ ' Mask out INKEY$
 t! = TIMER: WHILE t! = TIMER: WEND ' Delay
 i$ = INKEY$ ' Mask out INKEY$
 LOOP UNTIL quit > 0
 IF quit <> 3 THEN ReallyQuit = quit ' Not finished level
 IF level = 2 THEN ReallyQuit = 3 ' Last level!
 LOOP UNTIL ReallyQuit > 0
 END
 
 PrintAll:
 IF Display THEN
 Display = FALSE
 LOCATE oy, ox: PrintChar grid(ox, oy) ' Display player's old posit.
 LOCATE y, x: COLOR 15: PRINT CHR$(1); ' Display player
 oy = y: ox = x
 LOCATE 25, 5: PRINT direction$(direction);
 LOCATE 25, 10: PRINT "Air:"; AIR;
 LOCATE 25, 20: PRINT "Energy:"; ENERGY;
 LOCATE 25, 32: PRINT "Level"; level;
 GOSUB CheckPhysics
 END IF
 RETURN
 
 ProcessInput:
 IF GetInput THEN
 kp% = INP(&H60) ' Get keypress in kp%
 IF kp% < 100 THEN ' &H60 is > 100 if no keypresses
 IF kp% = 77 THEN ' [RIGHT]
 direction = RIGHT
 GOSUB MoveLeftOrRight
 ELSEIF kp% = 75 THEN ' [LEFT]
 direction = LEFT
 GOSUB MoveLeftOrRight
 ELSEIF kp% = 72 THEN ' [UP]
 GOSUB InputUp
 ELSEIF kp% = 80 THEN ' [DOWN]
 IF grid(x, y + 2) = ELEV.COLUMN THEN ' We're extended
 Display = TRUE
 y = y + 1
 grid(x, y) = -1
 grid(x, y + 1) = ELEVATOR ' Move elevator down
 LOCATE y + 1, x: PrintChar ELEVATOR ' Display
 ELSEIF grid(x, y - 1) = WHIP.LINE THEN ' On whip
 IF grid(x, y + 1) < 1 THEN ' Have space below us
 Display = TRUE
 grid(x, y) = WHIP.LINE
 y = y + 1
 END IF
 END IF
 ELSEIF kp% = 29 THEN ' [CTRL]
 IF ENERGY > 0 THEN
 IF direction = LEFT THEN
 changex = -1
 ELSE ' direction = RIGHT
 changex = 1
 END IF
 IF grid(x + changex, y) > 0 THEN ' Something to zap?
 FOR cnt = 1 TO 5
 IF RND > .75 THEN
 COLOR 4 ' Red 25% of the time
 ELSEIF RND > .75 THEN
 COLOR 14 ' Yellow 25% of the time
 ELSEIF RND > .75 THEN
 COLOR 12 ' Bright red 25% of the time
 ELSE
 COLOR 8 ' Gray rest of the time
 END IF
 LOCATE y, x + changex: PRINT CHR$(15); ' Display star
 t! = TIMER: WHILE t! = TIMER: WEND ' Delay
 NEXT cnt
 grid(x + changex, y) = -1 ' Zap!
 LOCATE y, x + changex: PrintChar -1 ' Display
 IF grid(x + changex, y - 1) = BOULDER THEN ' Boulder?
 MoveBoulders x + changex, y - 1
 END IF
 ENERGY = ENERGY - 1
 Display = TRUE
 END IF
 END IF ' energy > 0
 ELSEIF kp% = 56 THEN ' [ALT]
 GOSUB InputWhip
 ELSEIF kp% = 1 THEN ' [ESC]
 quit = 1
 END IF
 END IF
 END IF
 RETURN
 
 MoveLeftOrRight:
 IF grid(x + direction, y) < 1 THEN ' Not walking into wall
 Display = TRUE
 IF grid(x, y) <> WALL.FAKE THEN
 IF grid(x, y) <> AIR.SUCKER THEN
 grid(x, y) = -1
 END IF
 END IF
 IF whipactive THEN
 whipactive = FALSE
 xpos = x: ypos = y - 1
 done = FALSE
 DO
 IF grid(xpos, ypos) = WHIP.LINE THEN
 grid(xpos, ypos) = -1 ' Erase whip line
 LOCATE ypos, xpos: PrintChar -1
 ypos = ypos - 1 ' Move up further
 ELSE
 done = TRUE
 END IF
 LOOP UNTIL done
 END IF
 x = x + direction
 IF grid(x, y) = ENERGY.CHARGE THEN
 ENERGY = ENERGY + 1
 ELSEIF grid(x, y) = DOORWAY THEN
 quit = 3
 END IF
 END IF
 RETURN
 
 InputUp:
 IF grid(x, y + 1) = ELEVATOR THEN ' On elevator
 IF grid(x, y - 1) < 1 THEN ' Air above you
 Display = TRUE
 y = y - 1
 grid(x, y + 1) = ELEVATOR ' Move elevator up
 grid(x, y + 2) = ELEV.COLUMN ' Add column
 LOCATE y + 1, x: PrintChar ELEVATOR
 LOCATE y + 2, x: PrintChar ELEV.COLUMN
 END IF
 ELSEIF grid(x, y - 1) = WHIP.LINE THEN
 Display = TRUE
 grid(x, y - 1) = -1 ' Remove whip
 y = y - 1 ' Move up
 ELSE ' Jump
 IF direction = RIGHT THEN
 IF grid(x + 1, y) > 0 THEN ' Air at target position
 IF grid(x + 1, y - 1) < 1 THEN ' Something to land on
 Display = TRUE
 x = x + 1
 y = y - 1
 END IF
 END IF
 ELSE ' direction = LEFT
 IF grid(x - 1, y) > 0 THEN ' Air at target position
 IF grid(x - 1, y - 1) < 1 THEN ' Something to land on
 Display = TRUE
 x = x - 1
 y = y - 1
 END IF
 END IF
 END IF
 END IF ' Elevator/Jump
 RETURN
 
 InputWhip:
 IF NOT whipactive THEN
 xpos = x: ypos = y - 1
 done = FALSE
 DO
 IF grid(xpos, ypos) = STALACTITE THEN
 whipactive = TRUE: done = TRUE
 FOR cnt = y - 1 TO ypos + 1 STEP -1
 grid(xpos, cnt) = WHIP.LINE
 LOCATE cnt, xpos: PrintChar WHIP.LINE
 t! = TIMER: WHILE t! = TIMER: WEND ' Delay
 NEXT cnt
 ELSEIF grid(xpos, ypos) > 0 THEN
 done = TRUE
 ELSE
 ypos = ypos - 1
 END IF
 LOOP UNTIL done
 END IF
 RETURN
 
 DoAir:
 IF t$ <> TIME$ THEN ' A new second!
 t$ = TIME$
 IF SuckingAir THEN
 AIR = AIR - 5
 ELSE
 AIR = AIR - 1
 END IF
 IF AIR < 1 THEN quit = 2 ' Out of air!
 Display = TRUE
 END IF
 RETURN
 
 CheckPhysics: ' Handle physics after new display (i.e. falling)
 GetInput = TRUE ' To handle all ELSEs
 IF grid(x, y + 1) < 1 THEN ' Let him fall!
 IF grid(x, y - 1) <> WHIP.LINE THEN ' Not on whip
 Display = TRUE
 y = y + 1
 IF grid(x, y) = ENERGY.CHARGE THEN
 ENERGY = ENERGY + 1
 ELSEIF grid(x, y) = DOORWAY THEN
 quit = 3
 END IF
 END IF
 END IF
 IF grid(x - 1, y - 1) = BOULDER THEN ' Boulder near...
 IF grid(x - 1, y) < 0 THEN ' Nothing beneath it
 Display = TRUE
 GetInput = FALSE
 MoveBoulders x - 1, y - 1
 END IF
 END IF
 IF grid(x + 1, y - 1) = BOULDER THEN ' Boulder near...
 IF grid(x + 1, y) < 0 THEN ' Nothing beneath it
 Display = TRUE
 GetInput = FALSE
 MoveBoulders x + 1, y - 1
 END IF
 END IF
 IF grid(x, y) = AIR.SUCKER THEN
 SuckingAir = TRUE
 ELSE
 SuckingAir = FALSE
 END IF
 RETURN
 
 PrintLevel: ' Straightforward
 CLS ' Extra line for status at top
 FOR row = 1 TO 24
 FOR col = 1 TO 40
 PrintChar grid(col, row)
 NEXT col
 NEXT row
 RETURN
 
 DATA 3, 3, 60: REM x, y starting coordinates, air
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBaaaaAaaaaaaaaaaaaaaaaaaaFFFFFaBaaaaaBB"
 DATA "BBaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaBaaaaaBB"
 DATA "BBaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaBaaaaaBB"
 DATA "BBaaaaAaaaaaaaaaaaaaaaBBBBaaaaaaBaaaaaBB"
 DATA "BBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBaacaaBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBaaaBBBBBBBBBBBBBBB"
 DATA "BBaaaaaaaaaaaaaaaAaaaaaaBBaaaaaaaaaaaaBB"
 DATA "BBaaaaaaaaaaaaaaaaaaaaaBBBaaaaaaaaaaaaBB"
 DATA "BBaaBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBaaaaaaaaaaaaaaaaaaaaaBBaaaaaaaaaaaaaBB"
 DATA "BBaaaaaaaaaaaaaaaaaaadaeeaadaadadaadaaBB"
 DATA "BBCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEBB"
 DATA "BBEEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBEEBB"
 DATA "BBEEBBEEBBBEEBBBEEEBBEBBBEBBEEEEEBBBEEBB"
 DATA "BBEEBBEBEBBEBEBBEBBBBEEBBEBBBBEBBBBBEEBB"
 DATA "BBEEBBEEBBBEEBBBEEBBBEBEBEBBBBEBBBBBEEBB"
 DATA "BBEEBBEBEBBEBEBBEBBBBEBBEEBBBBEBBBBBEEBB"
 DATA "BBEEBBEEBBBEBEBBEEEBBEBBBEBBBBEBBBBBEEBB"
 DATA "BBEEBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBEEBB"
 DATA "BBEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 
 DATA 7, 3, 60: REM x, y starting coordinates, air
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBaaaaaaFFFFFFFFaaaaaaaaaaaaBBBBBBBBBBBB"
 DATA "BBaaaaaaaaaaaaaaaaaaaaaaaaaaBBBBBBBBBBBB"
 DATA "BBaaaaaaaaaaaaaaaaaaaaaaaaaaBBBBBBBBBBBB"
 DATA "BBaaaaaaaaaaaaaaaaaaaaaaaaaaBBBBBBBBBBBB"
 DATA "BBaaaaaaaaaaaaaaaaaaaaaaaaaaBBBBBBBBBBBB"
 DATA "BBBBBBaaaaaaaaaaaaAaaaaaaaaaBBBBBBBBBBBB"
 DATA "BBaaaBaaaaaaaaaaaaAaaaaaaaaaBBBBBBBBBBBB"
 DATA "BBacaBaaaaaaaaaaaaaaaaaaaaaaBBBBBBBBBBBB"
 DATA "BBBBBBBBBggggggBBBBBBBEaaaEBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBEaaaEBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBEaaaEBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBEaaaEBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBEaddEBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBCBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 DATA "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
 
 SUB LoadNextLevel
 
 READ x, y, AIR
 FOR lin = 1 TO 24
 READ a$
 FOR letter = 1 TO 40
 ascii% = ASC(MID$(a$, letter, 1)) ' Conversion:
 IF ascii% >= 97 THEN ' Lower case
 grid(letter, lin) = -(ascii - 97) ' Convert to negative
 ELSEIF ascii% >= 65 THEN ' Upper case
 grid(letter, lin) = ascii - 64 ' Convert to positive
 END IF
 NEXT letter
 NEXT lin
 
 END SUB
 
 SUB MoveBoulders (xpos, ypos)
 
 ' This routine moves the current boulder, and calls itself for
 ' the one above, if necessary.
 
 grid(xpos, ypos + 1) = BOULDER
 grid(xpos, ypos) = -1
 LOCATE ypos + 1, xpos: PrintChar BOULDER ' Display new boulder
 LOCATE ypos, xpos: PrintChar -1
 IF grid(xpos, ypos - 1) = BOULDER THEN
 MoveBoulders xpos, ypos - 1 ' Recursion
 END IF
 
 END SUB
 
 SUB PrintChar (arg)
 
 SELECT CASE arg
 CASE AIR.SUCKER: COLOR 1: PRINT CHR$(19);
 CASE WHIP.LINE: COLOR 6: PRINT CHR$(179);
 CASE ENERGY.CHARGE: COLOR 14: PRINT CHR$(15);
 CASE DOORWAY: COLOR 9: PRINT CHR$(21);
 CASE -1: PRINT " ";
 CASE 0: PRINT " ";
 CASE BOULDER: COLOR 15: PRINT CHR$(236);
 CASE WALL.FAKE: COLOR 7: PRINT CHR$(219);
 CASE WALL: COLOR 7: PRINT CHR$(219);
 CASE WALL.GRAY: COLOR 8: PRINT CHR$(219);
 CASE ELEVATOR: COLOR 6: PRINT CHR$(209);
 CASE ELEV.COLUMN: COLOR 6: PRINT CHR$(179);
 CASE STALACTITE: COLOR 7: PRINT CHR$(248);
 CASE ELSE: PRINT " ";
 END SELECT
 
 END SUB

Post a Comment

0 Comments