Writing an Adventure Game 05

Continuing our posts on learning programming through a simple adventure game.  In previous posts we have looked at creating a world that our player can explore; prevented the player from walking off the edge of the map, and provided a simple health system.

Today we shall look at implementing objects that the player can encounter - and later pick up and use.

As these posts are intended to be a simple introduction to programming we will use a simple data type - the array - to hold the information about objects - we wont introduce structures (or indeed objects in the object oriented sense yet - and yes, BB4W is, or can be object oriented : there are some links provided for the interested student).  If you want to see a more complicated adventure game, then do check out Goliath.

Most of the new code is contained in this image.  Showing the initialisation of objects and the modification of the main program.


Data is stored in four arrays - the prefix (whether it is 'a', 'an', 'the old' etc object); the object name itself, and the object's current x and y coordinate.

The PROC_showObjects procedure shown below loops through all the possible objects and checks whether they are visible to the player - ie in this sense, are they at the same location as the player.

Checking whether an object is at the player's current location.
In pseudocode the above procedure works as follows:

FOR EACH OBJECT
    IF THE PLAYER'S LOCATION IS THE SAME AS THE OBJECT LOCATION
        TELL PLAYER THAT THIS OBJECT IS HERE

We have also added a procedure for adding the objects initial positions to the game.
Reading in data about the objects.  This simple set of data should be sufficient to show how you could build up more complicated games with loads of objects.  Remember, if you want to add more objects then you must change the value of numObjects% accordingly!

In pseudocode the above procedure works as follows:

FOR EACH OBJECT
    READ THE OBJECT PREFIX, NAME, X AND Y COORDINATE

Now, when we play the game we may encounter some objects in our path:

Look, an apple!

Next time - letting the player pick up objects.

Source code follows:

     REM an adventure game in BB4W
     REM by Mr Street

     REM version 1.0.0.1 setting up the world
     REM version 1.0.0.2 moving around the world
     REM version 1.0.0.3 fixing it so you can't walk out of the grid
     REM version 1.0.0.4 health decreases each turn (because you get hungry)
     REM version 1.0.0.5 set-up some objects for the player to interact with

     
SIZE% = 3
     REM let's set up a 'world'
     
DIM World$( SIZE%, SIZE% ) : REM creates a 3x3 grid
     REM now 'populate' the grid with some space names
     
PROC_populateWorld
     REM now some data about our player
     REM player's starting position
     
x% = 2
     y% = 2
     REM player's health
     
health% = 50

     REM the objects
     
numObjects% = 2 : REM start with just a small number of objects
     
DIM prefix$( numObjects% )   : REM eg "a" or "an" or "the"
     
DIM object$( numObjects% )   : REM object name, eg "sword"
     
DIM objectx%( numObjects% )  : REM object x position
     
DIM objecty%( numObjects% )  : REM object y position
     
PROC_createObjects
     PROC_main


     DEFPROC_main
     LOCAL command$ : REM user's input
     REM the main program
     REM repeat until the player is dead
     
REPEAT
       
REM show the player's current position
       
PROC_showCurrent
       REM show objects here
       
PROC_showObjects
       REM get some input from the player
       
PRINT REM a blank line
       
INPUT "What now? > " command$
       REM deal with user's input
       
PROC_executeCommand( command$ )
     UNTIL health% <= 0
     REM game over message
     
PRINT "GAME OVER!"
     ENDPROC

     
DEFPROC_executeCommand( command$ )
     REM deals with the users input
     
LOCAL com$, gridError$
     LOCAL ok% : REM checks whether the user's input is acceptable
     
ok% = TRUE REM assume user's input makes sense
     
gridError$ = "You can't go in that direction!" : REM a message for when you move off the grid
     
com$ = FN_convlc( command$ ) : REM convert to lowercase so it is easier

     
CASE TRUE OF
       WHEN 
com$ = "n" OR com$ = "north"
         IF y%<SIZE% THEN
           
y% += 1
         ELSE
           PRINT 
gridError$
           ok% = FALSE
         ENDIF

       WHEN 
com$ = "s" OR com$ = "south"
         IF y% >1 THEN
           
y% -= 1
         ELSE
           PRINT 
gridError$
           ok% = FALSE
         ENDIF

       WHEN 
com$ = "e" OR com$ = "east"
         IF x%<SIZE% THEN
           
x% += 1
         ELSE
           PRINT 
gridError$
           ok% = FALSE
         ENDIF

       WHEN 
com$ = "w" OR com$ = "west"
         IF x%>1 THEN
           
x% -= 1
         ELSE
           PRINT 
gridError$
           ok% = FALSE
         ENDIF

       OTHERWISE
         PRINT 
"I don't understand you!"
         ok% = FALSE

     ENDCASE

     
REM if the user's input was acceptable, then they have
     REM made one 'turn' and should lose one health point
     
IF ok% THEN
       
health% -= 1
     ENDIF

     ENDPROC


     
DEFPROC_showCurrent
     PRINT "You are at the : "World$(x%, y%)
     PRINT "Your health is : "STR$(health%)
     ENDPROC


     
DEFPROC_showObjects
     REM look for any objects here
     
LOCAL n%
     REM look through list of objects
     
FOR n% = 1 TO numObjects%
       REM is the player's location the same as the object location?
       
IF x% = objectx%(n%) AND y% = objecty%(n%) THEN
         
REM objects is here
         
PRINT "There is "prefix$(n%)" "object$(n%)" here."
       ENDIF
     NEXT
     ENDPROC


     
DEF FN_convlc(A$)
     REM converts to lower case
     
SYS "CharLowerBuff", !^A$, LEN(A$)
     = A$


     DEFPROC_populateWorld
     REM puts some names of the spaces into the World
     
LOCAL x%, y%
     REM start with the first row
     
FOR y% = 1 TO SIZE%
       FOR x% = 1 TO SIZE%
         READ World$(x%,y%)
       NEXT
     NEXT
     ENDPROC
     
:
     REM the data for our 3x3 grid
     
DATA "Hills",  "Mountains", "Forest"
     
DATA "Castle", "Village", "Fields"
     
DATA "Woods",  "Swamp",  "Lake"

     
DEFPROC_createObjects
     REM puts the names of objects into a list
     
LOCAL n%
     FOR n% = 1 TO numObjects%
       READ prefix$(n%)
       READ object$(n%)
       READ objectx%(n%)
       READ objecty%(n%)
     NEXT
     ENDPROC
     DATA
 "an", "apple", 1, 3
     
DATA "a",  "sword", 3, 3