An attempt to create a first person adventure game engine

Game development specific discussions.
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: An attempt to create a first person adventure game engine

Post by ron77 »

hello :)

well i added some .wav files that @mrToad send me and added "fbsound1.1" bi file and lib files to the project and code now when the player moves forwards or backwards there is a sound of steps and in location 2 "outside - yard" you can hear a harp playing for 3 minutes...

still need some ideas about improving the movement of the player (changed navigation to "r" = right "l" = left "f" forwards "b" = backwards)

updated code"
file "main.bas"

Code: Select all

#INCLUDE "fbgfx.bi"
#INCLUDE ONCE "fbsound_dynamic.bi"

CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants

TYPE locations
   AS STRING _location
   AS FB.Image PTR _view(1 TO 4)
END TYPE


TYPE position
   PRIVATE:
   DIM AS locations map(1 TO 7)
   AS STRING _direction(1 TO 4)
   PUBLIC:
   DECLARE CONSTRUCTOR()
   DECLARE DESTRUCTOR()
   DECLARE SUB display_screen(x AS INTEGER,z AS INTEGER)
   DECLARE SUB main()
   DECLARE SUB make_sound(f AS STRING, hWave AS INTEGER,t AS INTEGER)
END TYPE

CONSTRUCTOR position
   DIM r AS STRING
   
   FOR x AS INTEGER = 1 TO 4
     READ r
     _direction(x) = r 
   NEXT
   
   
   FOR ii AS INTEGER = 1 TO 7
   READ r
   map(ii)._location = r
   NEXT
   
   
   FOR m AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            map(m)._view(i) = IMAGECREATE(800, 600)
            BLOAD("art\0" & m & "-" & i & ".bmp"), map(m)._view(i)
         
         NEXT
      
   NEXT
END CONSTRUCTOR

'directions data
DATA "north", "east", "south", "west"


''locations data
DATA "stable", "outside - yard", "yard", "yard road", "yard road", "up-stairs", "up-stairs" 


DESTRUCTOR position
   FOR y AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            IMAGEDESTROY(map(y)._view(i))
         NEXT
      
   NEXT
END DESTRUCTOR

Sub centerPrint(row AS INTEGER, s AS STRING)
   LOCATE row ,(LOWORD(width) - LEN(s)) Shr 1 : PRINT s
END SUB

SUB position.display_screen(x AS INTEGER, z AS INTEGER)
   
   SCREENLOCK
   PUT (0,0), map(x)._view(z), TRANS
   centerprint 1, _direction(z)
   CENTERPRINT 3, map(x)._location
   
   SCREENUNLOCK
   SLEEP 1
END SUB

SUB position.make_sound(f AS STRING, hWave AS INTEGER, t AS INTEGER)
   
   fbs_Load_WAVFile(f , @hWave)
   fbs_Play_Wave(hWave , t)
   
END SUB

SUB position.main()
   DIM AS INTEGER harpWav, stepsWav, knockWav
   DIM direc AS STRING
   DIM z AS INTEGER = 1, x AS INTEGER = 1
   'DIM AS boolean isenter = FALSE 
   DO
   centerprint 15, "press any key to begin..."
   SLEEP
   DO
      CLS
      IF direc = "q" THEN
         fbs_Destroy_Wave(@harpWav)
         fbs_Destroy_Wave(@knockWav)
         fbs_Destroy_Wave(@stepsWav)
         END
      ENDIF
     
      display_screen(x,z)
            
      IF x = 2 THEN
         make_sound("sound\harp.wav" ,harpWav, 1)
      ENDIF
      'IF next_room = 1 ANDalso index = 4 ANDalso direc = "open door" THEN
      '   centerprint 16, "cell door open! you can exit the cell!"
      '   isenter = TRUE
      '
      'ELSEIF next_room = 1 ANDALSO index = 4 THEN
      '   centerprint 15, "type 'open door' to open door"   
      '   isenter = FALSE
      '   IF direc = "f" then
      '      centerprint 14, "door closed you cannot move forwards"
      '   ENDIF
      'ENDIF
      'IF next_room = 3 ANDALSO index = 4 ANDALSO direc = "open door" THEN
      '   centerprint 16, "from the room an armed gurde come and stab you with a sward you die! - RIP"
      'ELSEIF next_room = 3 ANDALSO index = 4 THEN
      '   centerprint 15, "should we try to forcely open this door? if so type 'open door'"
      'ENDIF
      'IF next_room = 4 ANDALSO index = 2 ANDALSO direc = "open gate" THEN
      '   centerprint 16, "you made it! you are free! out of the prison cell!"
      '   isenter = TRUE 
      'ELSEIF next_room = 4 ANDALSO index = 2 THEN
      '   centerprint 15, "shell we try to open this gate? type 'open gate'"
      '   isenter = FALSE
      '   IF direc = "f" THEN
      '      centerprint 14, "first we most open the gate!"
      '   ENDIF
      '
      'ENDIF
      
      
      LOCATE 36, 1
      INPUT "choose direction('r' = right, 'l' = left, 'f' = forward, 'b' = backwards) or an action or key 'q' to quit: ", direc
      IF direc = "r" THEN z += 1
      IF direc = "l" THEN z -= 1
      IF direc = "f" THEN
         x += 1
         make_sound("sound\step_02.wav" ,stepsWav, 1)
      ENDIF
      IF direc = "b" THEN
         x -= 1
         make_sound("sound\step_02.wav" ,stepsWav, 1)
      ENDIF
      IF z < 1 THEN z = 4
      IF z > 4 THEN z = 1
      IF x < 1 THEN x = 1
      IF x > 7 THEN x = 7 
   LOOP
   
   LOOP UNTIL INKEY = CHR(27)
END SUB

IF fbs_Init()=false THEN
PRINT "error: FBS_INIT() " & FBS_Get_PlugError()
BEEP : SLEEP : END 1
END IF

SCREENRES scr_w, scr_h, 32
WIDTH scr_w \ 8, scr_h \ 16
DIM game AS position
game.main()
any help / suggestions will be greatly appreciated :)

ron77
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: An attempt to create a first person adventure game engine

Post by ron77 »

hello all...

although the movement of the player in the game is fixed on a one dimensional array (so there is only forward or backward movement) i added a hard coded boolean net map of where the player can move if the value of the boolean is TRUE then you can move if not you get a message that you are blocked...

Image

here is the updated code:

file "main.bas"

Code: Select all

#INCLUDE "fbgfx.bi"
#INCLUDE ONCE "fbsound_dynamic.bi"

CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants

TYPE locations
   AS STRING _location
   AS FB.Image PTR _view(1 TO 4)
   AS boolean enteries(1 TO 4)
END TYPE


TYPE position
   PRIVATE:
   AS STRING message
   AS locations map(1 TO 7)
   AS STRING _direction(1 TO 4)
   PUBLIC:
   DECLARE CONSTRUCTOR()
   DECLARE DESTRUCTOR()
   DECLARE SUB display_screen(x AS INTEGER,z AS INTEGER)
   DECLARE SUB main()
   DECLARE SUB make_sound(f AS STRING, hWave AS INTEGER,t AS INTEGER)
END TYPE

CONSTRUCTOR position
   DIM r AS STRING
   
   FOR x AS INTEGER = 1 TO 4
     READ r
     _direction(x) = r 
   NEXT
   
   
   FOR ii AS INTEGER = 1 TO 7
   READ r
   map(ii)._location = r
   NEXT
   
   
   FOR m AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            map(m)._view(i) = IMAGECREATE(800, 600)
            BLOAD("art\0" & m & "-" & i & ".bmp"), map(m)._view(i)
         
         NEXT
      
   NEXT
   
   map(1).enteries(1) = FALSE
   map(1).enteries(2) = FALSE 
   map(1).enteries(3) = TRUE
   map(1).enteries(4) = FALSE 
   map(2).enteries(1) = TRUE  
   map(2).enteries(2) = TRUE  
   map(2).enteries(3) = FALSE 
   map(2).enteries(4) = FALSE 
   map(3).enteries(1) = FALSE 
   map(3).enteries(2) = TRUE  
   map(3).enteries(3) = FALSE 
   map(3).enteries(4) = TRUE  
   map(4).enteries(1) = TRUE  
   map(4).enteries(2) = FALSE   
   map(4).enteries(3) = TRUE  
   map(4).enteries(4) = TRUE
   map(5).enteries(1) = FALSE
   map(5).enteries(2) = FALSE
   map(5).enteries(3) = TRUE  
   map(5).enteries(4) = FALSE
   map(6).enteries(1) = TRUE
   map(6).enteries(2) = FALSE 
   map(6).enteries(3) = FALSE 
   map(6).enteries(4) = TRUE
   map(7).enteries(1) = FALSE 
   map(7).enteries(2) = TRUE
   map(7).enteries(3) = FALSE
   map(7).enteries(4) = FALSE
   
END CONSTRUCTOR

'directions data
DATA "north", "east", "south", "west"


''locations data
DATA "stable", "outside - yard", "yard", "yard road", "yard road", "up-stairs", "up-stairs" 


DESTRUCTOR position
   FOR y AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            IMAGEDESTROY(map(y)._view(i))
         NEXT
      
   NEXT
END DESTRUCTOR

Sub centerPrint(row AS INTEGER, s AS STRING)
   LOCATE row ,(LOWORD(width) - LEN(s)) Shr 1 : PRINT s
END SUB

SUB position.display_screen(x AS INTEGER, z AS INTEGER)
   
   SCREENLOCK
   PUT (0,0), map(x)._view(z), TRANS
   centerprint 1, _direction(z)
   CENTERPRINT 3, map(x)._location
   CENTERPRINT 15, message
   SCREENUNLOCK
   SLEEP 1
END SUB

SUB position.make_sound(f AS STRING, hWave AS INTEGER, t AS INTEGER)
   
   fbs_Load_WAVFile(f , @hWave)
   fbs_Play_Wave(hWave , t)
   
END SUB

SUB position.main()
   DIM AS INTEGER harpWav, stepsWav, knockWav
   DIM direc AS STRING
   DIM z AS INTEGER = 1, x AS INTEGER = 1
   'DIM AS boolean isenter = FALSE 
   DO
   centerprint 15, "press any key to begin..."
   SLEEP
   DO
      CLS
      IF direc = "q" THEN
         fbs_Destroy_Wave(@harpWav)
         fbs_Destroy_Wave(@knockWav)
         fbs_Destroy_Wave(@stepsWav)
         END
      ENDIF
      IF direc = "r" THEN z += 1
      IF direc = "l" THEN z -= 1
      IF direc = "f" THEN
         IF map(x).enteries(z) = TRUE THEN
            x += 1
            make_sound("sound\step_02.wav" ,stepsWav, 1)
            message = ""
         ELSE
            message = "PATH IS BLOCKED! OR YOU CANNOT GO THERE!"
         ENDIF
      ENDIF
      IF direc = "b" THEN
         IF map(x).enteries(z) = TRUE THEN
            x -= 1
            make_sound("sound\step_02.wav" ,stepsWav, 1)
            message = ""
         ELSE
            message = "YOU CANNOT GO BACK IN THAT DIRECTION - SOMETHING IS BLOCKING YOUR BACK"
         ENDIF
         
      ENDIF
      IF z < 1 THEN z = 4
      IF z > 4 THEN z = 1
      IF x < 1 THEN x = 1
      IF x > 7 THEN x = 7 
      display_screen(x,z)
            
      IF x = 2 THEN
         make_sound("sound\harp.wav" ,harpWav, 1)
      ENDIF
      'IF next_room = 1 ANDalso index = 4 ANDalso direc = "open door" THEN
      '   centerprint 16, "cell door open! you can exit the cell!"
      '   isenter = TRUE
      '
      'ELSEIF next_room = 1 ANDALSO index = 4 THEN
      '   centerprint 15, "type 'open door' to open door"   
      '   isenter = FALSE
      '   IF direc = "f" then
      '      centerprint 14, "door closed you cannot move forwards"
      '   ENDIF
      'ENDIF
      'IF next_room = 3 ANDALSO index = 4 ANDALSO direc = "open door" THEN
      '   centerprint 16, "from the room an armed gurde come and stab you with a sward you die! - RIP"
      'ELSEIF next_room = 3 ANDALSO index = 4 THEN
      '   centerprint 15, "should we try to forcely open this door? if so type 'open door'"
      'ENDIF
      'IF next_room = 4 ANDALSO index = 2 ANDALSO direc = "open gate" THEN
      '   centerprint 16, "you made it! you are free! out of the prison cell!"
      '   isenter = TRUE 
      'ELSEIF next_room = 4 ANDALSO index = 2 THEN
      '   centerprint 15, "shell we try to open this gate? type 'open gate'"
      '   isenter = FALSE
      '   IF direc = "f" THEN
      '      centerprint 14, "first we most open the gate!"
      '   ENDIF
      '
      'ENDIF
      
      
      LOCATE 36, 1
      INPUT "choose direction('r' = right, 'l' = left, 'f' = forward, 'b' = backwards) or an action or key 'q' to quit: ", direc
      
   LOOP
   
   LOOP UNTIL INKEY = CHR(27)
END SUB

IF fbs_Init()=false THEN
PRINT "error: FBS_INIT() " & FBS_Get_PlugError()
BEEP : SLEEP : END 1
END IF

SCREENRES scr_w, scr_h, 32
WIDTH scr_w \ 8, scr_h \ 16
DIM game AS position
game.main()
any help or suggestions will be greatly appreciated

ron77 :)
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: An attempt to create a first person adventure game engine

Post by paul doe »

Wouldn't it be nice to have mouse navigation? Like, you point with your mouse at an exit, and clicking would take you there. Like the adventure games of yore...
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: An attempt to create a first person adventure game engine

Post by ron77 »

hello all...

in order for you also to be able to compile and run this game engine with all the media files i'm giving a link to a zip .rar file on dropbox so you can download and just extract the sounds and images to the program folder...

https://www.dropbox.com/s/ydwk1rd2he3nz ... e.rar?dl=0

i hope this link works and you be able to download the media... can any one please tell me if it's working?

ron77 :)
badmrbox
Posts: 664
Joined: Oct 27, 2005 14:40
Location: Sweden
Contact:

Re: An attempt to create a first person adventure game engine

Post by badmrbox »

It works just fine :)
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: An attempt to create a first person adventure game engine

Post by BasicCoder2 »

Dropbox requires a sign in and it is a .rar file rather than a .zip file so I can't test it.
badmrbox
Posts: 664
Joined: Oct 27, 2005 14:40
Location: Sweden
Contact:

Re: An attempt to create a first person adventure game engine

Post by badmrbox »

BasicCoder2 wrote:Dropbox requires a sign in and it is a .rar file rather than a .zip file so I can't test it.
You dont need to log in. Just click the download icon on the topright side of the screen.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: An attempt to create a first person adventure game engine

Post by BasicCoder2 »

@badmrbox
Thanks I didn't look hard enough!
@ron77
Your program worked for me on Window10.
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: An attempt to create a first person adventure game engine

Post by ron77 »

hello @BasicCoder2 and @BadMrBox and thanks for letting me know :)

i asked for help in the FB discord server and someone suggested hat i'd make every location as a UDT and then use linked lists to link them all together... another advice that was given is that i need some sort of mechanism in the code to remember from where i entered the location (that way i won't have to use the key "b" for backwards... i'd could just turn backwards and press forwards to return to the last locations...

can anyone help me with this?

ron77
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: An attempt to create a first person adventure game engine

Post by ron77 »

okay i revise my conversations with the people on FB discord server and i implemented this advice:
make enteries(j) a long data type. set it to "-1" to make no connection. this is like "false". if you do want a connecting room set it to "x room number" which is like true. then when you send a move command, set the next room to that "x room number" as long as it is not "-1"
instead of "IF map(x).enteries(z) = TRUE THEN x += 1" you would "IF map(x).enteries(z) <> -1 then x = map(x).enteries(z)"
i'd tried it and it works perfectly :) no need for the "b" = backwards options...

here is the updated code.

file "main.bas"

Code: Select all

#INCLUDE "fbgfx.bi"
#INCLUDE ONCE "fbsound_dynamic.bi"

CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants

TYPE locations
   AS STRING _location
   AS FB.Image PTR _view(1 TO 4)
   AS LONG enteries(1 TO 4)
END TYPE


TYPE position
   PRIVATE:
   AS STRING message
   AS locations map(1 TO 7)
   AS STRING _direction(1 TO 4)
   PUBLIC:
   DECLARE CONSTRUCTOR()
   DECLARE DESTRUCTOR()
   DECLARE SUB display_screen(x AS INTEGER,z AS INTEGER)
   DECLARE SUB main()
   DECLARE SUB make_sound(f AS STRING, hWave AS INTEGER,t AS INTEGER)
END TYPE

CONSTRUCTOR position
   DIM r AS STRING
   
   FOR x AS INTEGER = 1 TO 4
     READ r
     _direction(x) = r 
   NEXT
   
   
   FOR ii AS INTEGER = 1 TO 7
   READ r
   map(ii)._location = r
   NEXT
   
   
   FOR m AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            map(m)._view(i) = IMAGECREATE(800, 600)
            BLOAD("art\0" & m & "-" & i & ".bmp"), map(m)._view(i)
         
         NEXT
      
   NEXT
   
   map(1).enteries(1) = -1
   map(1).enteries(2) = -1 
   map(1).enteries(3) = 2
   map(1).enteries(4) = -1 
   map(2).enteries(1) = 1  
   map(2).enteries(2) = 3  
   map(2).enteries(3) = -1 
   map(2).enteries(4) = -1 
   map(3).enteries(1) = -1 
   map(3).enteries(2) = 4  
   map(3).enteries(3) = -1 
   map(3).enteries(4) = 3  
   map(4).enteries(1) = 5  
   map(4).enteries(2) = -1   
   map(4).enteries(3) = 6  
   map(4).enteries(4) = 2
   map(5).enteries(1) = -1
   map(5).enteries(2) = -1
   map(5).enteries(3) = 4  
   map(5).enteries(4) = -1
   map(6).enteries(1) = 4
   map(6).enteries(2) = -1 
   map(6).enteries(3) = -1 
   map(6).enteries(4) = 7
   map(7).enteries(1) = -1 
   map(7).enteries(2) = 6
   map(7).enteries(3) = -1
   map(7).enteries(4) = -1
   
END CONSTRUCTOR

'directions data
DATA "north", "east", "south", "west"


''locations data
DATA "stable", "outside - yard", "yard", "yard road", "yard road", "up-stairs", "up-stairs" 


DESTRUCTOR position
   FOR y AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            IMAGEDESTROY(map(y)._view(i))
         NEXT
      
   NEXT
END DESTRUCTOR

Sub centerPrint(row AS INTEGER, s AS STRING)
   LOCATE row ,(LOWORD(width) - LEN(s)) Shr 1 : PRINT s
END SUB

SUB position.display_screen(x AS INTEGER, z AS INTEGER)
   
   SCREENLOCK
   PUT (0,0), map(x)._view(z), TRANS
   centerprint 1, _direction(z)
   CENTERPRINT 3, map(x)._location
   CENTERPRINT 15, message
   SCREENUNLOCK
   SLEEP 1
END SUB

SUB position.make_sound(f AS STRING, hWave AS INTEGER, t AS INTEGER)
   
   fbs_Load_WAVFile(f , @hWave)
   fbs_Play_Wave(hWave , t)
   
END SUB

SUB position.main()
   DIM AS INTEGER harpWav, stepsWav, knockWav
   DIM direc AS STRING
   DIM z AS INTEGER = 1, x AS INTEGER = 1
   'DIM AS boolean isenter = FALSE 
   DO
   centerprint 15, "press any key to begin..."
   SLEEP
   DO
      CLS
      IF direc = "q" THEN
         fbs_Destroy_Wave(@harpWav)
         fbs_Destroy_Wave(@knockWav)
         fbs_Destroy_Wave(@stepsWav)
         END
      ENDIF
      IF direc = "r" THEN z += 1
      IF direc = "l" THEN z -= 1
      IF direc = "f" THEN
         IF map(x).enteries(z) <> -1 then 
            'x += 1
            x = map(x).enteries(z)
            make_sound("sound\step_02.wav" ,stepsWav, 1)
            message = ""
         ELSE
            message = "PATH IS BLOCKED! OR YOU CANNOT GO THERE!"
         ENDIF
      ENDIF
      'IF direc = "b" THEN
      '   IF map(x).enteries(z) = TRUE THEN
      '      x -= 1
      '      make_sound("sound\step_02.wav" ,stepsWav, 1)
      '      message = ""
      '   ELSE
      '      message = "YOU CANNOT GO BACK IN THAT DIRECTION - SOMETHING IS BLOCKING YOUR BACK"
      '   ENDIF
      '   
      'ENDIF
      IF z < 1 THEN z = 4
      IF z > 4 THEN z = 1
      IF x < 1 THEN x = 1
      IF x > 7 THEN x = 7 
      display_screen(x,z)
            
      IF x = 2 THEN
         make_sound("sound\harp.wav" ,harpWav, 1)
      ENDIF
    
      
      
      LOCATE 36, 1
      INPUT "choose direction('r' = right, 'l' = left, 'f' = forward) or an action or key 'q' to quit: ", direc
      
   LOOP
   
   LOOP UNTIL INKEY = CHR(27)
END SUB

IF fbs_Init()=false THEN
PRINT "error: FBS_INIT() " & FBS_Get_PlugError()
BEEP : SLEEP : END 1
END IF

SCREENRES scr_w, scr_h, 32
WIDTH scr_w \ 8, scr_h \ 16
DIM game AS position
game.main()
what next? - i would like to add the ability to inventory to the player like if he can pick up a key to open the door at the beginning of the game...
there isn't much action in this game and it's very limited just 7 locations - this game engine is limited and meant for learning purposes...

p.s. - i highly recommend you to join the FB discord server (search for it on the forum for a link to join) friendly people good company and good advices and fun conversations :)

ron77 :)
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: An attempt to create a first person adventure game engine

Post by ron77 »

okay added item type and now in the first location you need to "look around" and "pick up key" and then at the door you need to "open door" so you'll be able to get out...

updated code:

file "main.bas"

Code: Select all

#INCLUDE "fbgfx.bi"
#INCLUDE ONCE "fbsound_dynamic.bi"

CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants

TYPE item
   AS INTEGER id
   AS STRING item_name
   AS STRING state(1 TO 2)
   AS INTEGER place
END TYPE



TYPE locations
   AS STRING _location
   AS FB.Image PTR _view(1 TO 4)
   AS LONG enteries(1 TO 4)
   
END TYPE


TYPE position
   PRIVATE:
   AS STRING message
   AS locations map(1 TO 7)
   AS STRING _direction(1 TO 4)
   AS item key
   
   PUBLIC:
   DECLARE CONSTRUCTOR()
   DECLARE DESTRUCTOR()
   DECLARE SUB display_screen(x AS INTEGER,z AS INTEGER)
   DECLARE SUB main()
   DECLARE SUB make_sound(f AS STRING, hWave AS INTEGER,t AS INTEGER)
END TYPE

CONSTRUCTOR position
   key.place = 1
   key.id = 1
   key.item_name = "golden key"
   key.state(1) = "on the ground"
   key.state(2) = "inside your pocket"
   
   
   DIM r AS STRING
   
   FOR x AS INTEGER = 1 TO 4
     READ r
     _direction(x) = r 
   NEXT
   
   
   FOR ii AS INTEGER = 1 TO 7
   READ r
   map(ii)._location = r
   NEXT
   
   
   FOR m AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            map(m)._view(i) = IMAGECREATE(800, 600)
            BLOAD("art\0" & m & "-" & i & ".bmp"), map(m)._view(i)
         
         NEXT
      
   NEXT
   
   map(1).enteries(1) = -1
   map(1).enteries(2) = -1 
   map(1).enteries(3) = 2
   map(1).enteries(4) = -1 
   map(2).enteries(1) = 1  
   map(2).enteries(2) = 3  
   map(2).enteries(3) = -1 
   map(2).enteries(4) = -1 
   map(3).enteries(1) = -1 
   map(3).enteries(2) = 4  
   map(3).enteries(3) = -1 
   map(3).enteries(4) = 3  
   map(4).enteries(1) = 5  
   map(4).enteries(2) = -1   
   map(4).enteries(3) = 6  
   map(4).enteries(4) = 2
   map(5).enteries(1) = -1
   map(5).enteries(2) = -1
   map(5).enteries(3) = 4  
   map(5).enteries(4) = -1
   map(6).enteries(1) = 4
   map(6).enteries(2) = -1 
   map(6).enteries(3) = -1 
   map(6).enteries(4) = 7
   map(7).enteries(1) = -1 
   map(7).enteries(2) = 6
   map(7).enteries(3) = -1
   map(7).enteries(4) = -1
   
END CONSTRUCTOR

'directions data
DATA "north", "east", "south", "west"


''locations data
DATA "stable", "outside - yard", "yard", "yard road", "yard road", "up-stairs", "up-stairs" 


DESTRUCTOR position
   FOR y AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            IMAGEDESTROY(map(y)._view(i))
         NEXT
      
   NEXT
END DESTRUCTOR

Sub centerPrint(row AS INTEGER, s AS STRING)
   LOCATE row ,(LOWORD(width) - LEN(s)) Shr 1 : PRINT s
END SUB

'APPEND TO the STRING array the STRING item
SUB sAppend(arr() AS STRING , Item AS STRING)
	REDIM PRESERVE arr(LBOUND(arr) TO UBOUND(arr) + 1) AS STRING
	arr(UBOUND(arr)) = Item
END SUB


SUB upper(f AS STRING)
	CLS
	REDIM lines(0) AS STRING
	DIM h AS LONG = FREEFILE()
	DIM AS INTEGER r = 35 , c = 30
	DIM fline AS STRING
	OPEN f FOR INPUT AS #h
	WHILE NOT EOF(h)
        LINE INPUT #h , fline
        sAppend lines() , fline
    WEND
	CLOSE #h
	
	DIM AS INTEGER hi = HIWORD(WIDTH()) 'num columns ON display
	'PRINT closing credits
	FOR i AS INTEGER = 0 TO UBOUND(lines)
        LOCATE hi , 10
        PRINT lines(i)
        SLEEP 500
    NEXT
	'CLEAR SCREEN
	FOR i AS INTEGER = 1 TO hi
        PRINT
        SLEEP 500
    NEXT
	PRINT "END"
	GETKEY()
END SUB


SUB position.display_screen(x AS INTEGER, z AS INTEGER)
   
   SCREENLOCK
   PUT (0,0), map(x)._view(z), TRANS
   centerprint 1, _direction(z)
   CENTERPRINT 3, map(x)._location
   CENTERPRINT 15, message
   SCREENUNLOCK
   SLEEP 1
END SUB

SUB position.make_sound(f AS STRING, hWave AS INTEGER, t AS INTEGER)
   
   fbs_Load_WAVFile(f , @hWave)
   fbs_Play_Wave(hWave , t)
   
END SUB

SUB position.main()
   DIM AS INTEGER harpWav, stepsWav, knockWav
   DIM direc AS STRING
   DIM z AS INTEGER = 1, x AS INTEGER = 1
   DIM AS boolean isOpen = FALSE 
   DO
   centerprint 15, "press any key to begin..."
   SLEEP
   DO
      CLS
      IF direc = "q" THEN
         fbs_Destroy_Wave(@harpWav)
         fbs_Destroy_Wave(@knockWav)
         fbs_Destroy_Wave(@stepsWav)
         EXIT sub
      ENDIF
      
      IF x = 1 ANDalso z = 3 ANDALSO direc = "open door" THEN
         isOpen = TRUE
         message = "YOU OPEN THE LOCKED DOOR WITH THE GOLDEN KEY - THE DOOR IS OPENED"      
      
      ELSEIF x = 1 AND direc = "pick up key" THEN
         message = key.item_name & " " & key.state(2)
      
      ELSEIF x = 1 AND direc = "look around" THEN
         message = key.item_name & " " & key.state(1)
      
      ELSEIF x = 1 ANDALSO isOpen = FALSE THEN
         message = "DOOR IS LOCKED TYPE 'look around' TO FIND KEY"
      ENDIF
      
      IF direc = "r" THEN z += 1
      IF direc = "l" THEN z -= 1
      IF direc = "f" THEN
         IF map(x).enteries(z) <> -1 ANDALSO isOpen = TRUE then 
            'x += 1
            x = map(x).enteries(z)
            make_sound("sound\step_02.wav" ,stepsWav, 1)
            message = ""
         ELSE
            message = "PATH IS BLOCKED! OR YOU CANNOT GO THERE!"
         ENDIF
      ENDIF
      
      IF z < 1 THEN z = 4
      IF z > 4 THEN z = 1
      IF x < 1 THEN x = 1
      IF x > 7 THEN x = 7 
      display_screen(x,z)
            
      IF x = 2 THEN
         make_sound("sound\harp.wav" ,harpWav, 1)
      ENDIF
    
      
      
      LOCATE 36, 1
      INPUT "choose direction('r' = right, 'l' = left, 'f' = forward) or an action or key 'q' to quit: ", direc
      
   LOOP
   
   LOOP UNTIL INKEY = CHR(27)
END SUB

IF fbs_Init()=false THEN
PRINT "error: FBS_INIT() " & FBS_Get_PlugError()
BEEP : SLEEP : END 1
END IF

SCREENRES scr_w, scr_h, 32
WIDTH scr_w \ 8, scr_h \ 16
DIM game AS position
game.main()
'UPPER("ending.txt")
any help / suggestion will be greatly appreciated

ron77
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: An attempt to create a first person adventure game engine

Post by BasicCoder2 »

It would be a much more pleasant game if you used INKEY instead of INPUT where the arrow keys can turn left/right or forward.
I couldn't figure out how to pick up a key or even see one.
Ideally if there is a key in the image then clicking it with the mouse would be a user friendly way to to pick it up.
I am unable to follow your code logic to actually make the modifications myself.
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: An attempt to create a first person adventure game engine

Post by ron77 »

hello @BasicCoder2 thanks for the advice...

i've modified the code i commented the lines with INPUT and added INKEY to the loop i couldn't figure out what is the ascii code for the arrows so instead i added key "w" for forwards key "d" for right and key "a" for left...

here is the updated the code (p.s, since i don't have INPUT anymore i commented all the code with the "golden key" that opens the door at the first location)

file "main.bas"

Code: Select all

#INCLUDE "fbgfx.bi"
#INCLUDE ONCE "fbsound_dynamic.bi"

CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants

TYPE item
   AS INTEGER id
   AS STRING item_name
   AS STRING state(1 TO 2)
   AS INTEGER place
END TYPE



TYPE locations
   AS STRING _location
   AS FB.Image PTR _view(1 TO 4)
   AS LONG enteries(1 TO 4)
   
END TYPE


TYPE position
   PRIVATE:
   AS STRING message
   AS locations map(1 TO 7)
   AS STRING _direction(1 TO 4)
   AS item key
   
   PUBLIC:
   DECLARE CONSTRUCTOR()
   DECLARE DESTRUCTOR()
   DECLARE SUB display_screen(x AS INTEGER,z AS INTEGER)
   DECLARE SUB main()
   DECLARE SUB make_sound(f AS STRING, hWave AS INTEGER,t AS INTEGER)
END TYPE

CONSTRUCTOR position
   key.place = 1
   key.id = 1
   key.item_name = "golden key"
   key.state(1) = "on the ground"
   key.state(2) = "inside your pocket"
   
   
   DIM r AS STRING
   
   FOR x AS INTEGER = 1 TO 4
     READ r
     _direction(x) = r 
   NEXT
   
   
   FOR ii AS INTEGER = 1 TO 7
   READ r
   map(ii)._location = r
   NEXT
   
   
   FOR m AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            map(m)._view(i) = IMAGECREATE(800, 600)
            BLOAD("art\0" & m & "-" & i & ".bmp"), map(m)._view(i)
         
         NEXT
      
   NEXT
   
   map(1).enteries(1) = -1
   map(1).enteries(2) = -1 
   map(1).enteries(3) = 2
   map(1).enteries(4) = -1 
   map(2).enteries(1) = 1  
   map(2).enteries(2) = 3  
   map(2).enteries(3) = -1 
   map(2).enteries(4) = -1 
   map(3).enteries(1) = -1 
   map(3).enteries(2) = 4  
   map(3).enteries(3) = -1 
   map(3).enteries(4) = 3  
   map(4).enteries(1) = 5  
   map(4).enteries(2) = -1   
   map(4).enteries(3) = 6  
   map(4).enteries(4) = 2
   map(5).enteries(1) = -1
   map(5).enteries(2) = -1
   map(5).enteries(3) = 4  
   map(5).enteries(4) = -1
   map(6).enteries(1) = 4
   map(6).enteries(2) = -1 
   map(6).enteries(3) = -1 
   map(6).enteries(4) = 7
   map(7).enteries(1) = -1 
   map(7).enteries(2) = 6
   map(7).enteries(3) = -1
   map(7).enteries(4) = -1
   
END CONSTRUCTOR

'directions data
DATA "north", "east", "south", "west"


''locations data
DATA "stable", "outside - yard", "yard", "yard road", "yard road", "up-stairs", "up-stairs" 


DESTRUCTOR position
   FOR y AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            IMAGEDESTROY(map(y)._view(i))
         NEXT
      
   NEXT
END DESTRUCTOR

Sub centerPrint(row AS INTEGER, s AS STRING)
   LOCATE row ,(LOWORD(width) - LEN(s)) Shr 1 : PRINT s
END SUB

'APPEND TO the STRING array the STRING item
SUB sAppend(arr() AS STRING , Item AS STRING)
	REDIM PRESERVE arr(LBOUND(arr) TO UBOUND(arr) + 1) AS STRING
	arr(UBOUND(arr)) = Item
END SUB


SUB upper(f AS STRING)
	CLS
	REDIM lines(0) AS STRING
	DIM h AS LONG = FREEFILE()
	DIM AS INTEGER r = 35 , c = 30
	DIM fline AS STRING
	OPEN f FOR INPUT AS #h
	WHILE NOT EOF(h)
        LINE INPUT #h , fline
        sAppend lines() , fline
    WEND
	CLOSE #h
	
	DIM AS INTEGER hi = HIWORD(WIDTH()) 'num columns ON display
	'PRINT closing credits
	FOR i AS INTEGER = 0 TO UBOUND(lines)
        LOCATE hi , 10
        PRINT lines(i)
        SLEEP 500
    NEXT
	'CLEAR SCREEN
	FOR i AS INTEGER = 1 TO hi
        PRINT
        SLEEP 500
    NEXT
	PRINT "END"
	GETKEY()
END SUB


SUB position.display_screen(x AS INTEGER, z AS INTEGER)
   
   SCREENLOCK
   PUT (0,0), map(x)._view(z), TRANS
   centerprint 1, _direction(z)
   CENTERPRINT 3, map(x)._location
   CENTERPRINT 2, "press key 'd' for right key 'a' for left 'w' to move forwards, 'q' to exit"
   CENTERPRINT 15, message
   SCREENUNLOCK
   SLEEP 1
END SUB

SUB position.make_sound(f AS STRING, hWave AS INTEGER, t AS INTEGER)
   
   fbs_Load_WAVFile(f , @hWave)
   fbs_Play_Wave(hWave , t)
   
END SUB

SUB position.main()
   DIM AS INTEGER harpWav, stepsWav, knockWav
   DIM direc AS STRING
   DIM z AS INTEGER = 1, x AS INTEGER = 1
   'DIM AS boolean isOpen = FALSE 
   DIM k AS STRING
   DO
   centerprint 15, "press any key to begin..."
   SLEEP
   DO
      k = INKEY
      CLS
      IF k = "q" THEN
         fbs_Destroy_Wave(@harpWav)
         fbs_Destroy_Wave(@knockWav)
         fbs_Destroy_Wave(@stepsWav)
         EXIT sub
      ENDIF
      
      'IF x = 1 ANDalso z = 3 ANDALSO direc = "open door" THEN
      '   isOpen = TRUE
      '   message = "YOU OPEN THE LOCKED DOOR WITH THE GOLDEN KEY - THE DOOR IS OPENED"      
      '
      'ELSEIF x = 1 AND direc = "pick up key" THEN
      '   message = key.item_name & " " & key.state(2)
      '
      'ELSEIF x = 1 AND direc = "look around" THEN
      '   message = key.item_name & " " & key.state(1)
      '
      'ELSEIF x = 1 ANDALSO isOpen = FALSE THEN
      '   message = "DOOR IS LOCKED TYPE 'look around' TO FIND KEY"
      'ENDIF
      
      IF k = "d" THEN z += 1
      IF k = "a" THEN z -= 1
      IF k = "w" THEN
         IF map(x).enteries(z) <> -1 THEN 'ANDALSO isOpen = TRUE then 
            'x += 1
            x = map(x).enteries(z)
            make_sound("sound\step_02.wav" ,stepsWav, 1)
            message = ""
         ELSE
            message = "PATH IS BLOCKED! OR YOU CANNOT GO THERE!"
         ENDIF
      ENDIF
      
      IF z < 1 THEN z = 4
      IF z > 4 THEN z = 1
      IF x < 1 THEN x = 1
      IF x > 7 THEN x = 7 
      display_screen(x,z)
            
      IF x = 2 THEN
         make_sound("sound\harp.wav" ,harpWav, 1)
      ENDIF
    
      
      
      'LOCATE 36, 1
      'INPUT "choose direction('r' = right, 'l' = left, 'f' = forward) or an action or key 'q' to quit: ", direc
      
   LOOP
   
   LOOP UNTIL INKEY = CHR(27)
END SUB

IF fbs_Init()=false THEN
PRINT "error: FBS_INIT() " & FBS_Get_PlugError()
BEEP : SLEEP : END 1
END IF

SCREENRES scr_w, scr_h, 32
WIDTH scr_w \ 8, scr_h \ 16
DIM game AS position
game.main()
'UPPER("ending.txt")
last edit: fixed code

ron77
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: An attempt to create a first person adventure game engine

Post by BasicCoder2 »

The cursor keys return 255 and some other number.
75 left key
77 right key
72 up key

Code: Select all

dim as string key
do
    key = inkey
    if key<>"" then
        print key;" ";
        if len(key)=2 then
            print asc(key);" ";
            print asc(right(key,1))
        else
            print asc(key)
        end if
    end if
loop until multikey(&H01)
Another option is to use multikey
https://documentation.help/FreeBASIC/KeyPgMultikey.html
Of course the ideal setup would be GUI buttons.
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: An attempt to create a first person adventure game engine

Post by ron77 »

hi @BasicCoder2 thanks! i got it!

here is updated code using the arrow keys to navigate. now when you press the down arrow key you get "INPUT" for typing actions like "pick up key" "open door" etc... i also fixed a few bugs in the map of locations...

file "main.bas"

Code: Select all

#INCLUDE "fbgfx.bi"
#INCLUDE ONCE "fbsound_dynamic.bi"

Const xk = Chr(255)
Const key_up = xk + "H"
Const key_dn = xk + "P"
Const key_rt = xk + "M"
Const key_lt = xk + "K"

CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants

TYPE item
   AS INTEGER id
   AS STRING item_name
   AS STRING state(1 TO 2)
   AS INTEGER place
END TYPE



TYPE locations
   AS STRING _location
   AS FB.Image PTR _view(1 TO 4)
   AS LONG enteries(1 TO 4)
   
END TYPE


TYPE position
   PRIVATE:
   AS STRING message
   AS locations map(1 TO 7)
   AS STRING _direction(1 TO 4)
   AS item key
   
   PUBLIC:
   DECLARE CONSTRUCTOR()
   DECLARE DESTRUCTOR()
   DECLARE SUB display_screen(x AS INTEGER,z AS INTEGER)
   DECLARE SUB main()
   DECLARE SUB make_sound(f AS STRING, hWave AS INTEGER,t AS INTEGER)
END TYPE

CONSTRUCTOR position
   key.place = 1
   key.id = 1
   key.item_name = "golden key"
   key.state(1) = "on the ground"
   key.state(2) = "inside your pocket"
   
   
   DIM r AS STRING
   
   FOR x AS INTEGER = 1 TO 4
     READ r
     _direction(x) = r 
   NEXT
   
   
   FOR ii AS INTEGER = 1 TO 7
   READ r
   map(ii)._location = r
   NEXT
   
   
   FOR m AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            map(m)._view(i) = IMAGECREATE(800, 600)
            BLOAD("art\0" & m & "-" & i & ".bmp"), map(m)._view(i)
         
         NEXT
      
   NEXT
   
   map(1).enteries(1) = -1
   map(1).enteries(2) = -1 
   map(1).enteries(3) = 2
   map(1).enteries(4) = -1 
   map(2).enteries(1) = 1  
   map(2).enteries(2) = 3  
   map(2).enteries(3) = -1 
   map(2).enteries(4) = -1 
   map(3).enteries(1) = -1 
   map(3).enteries(2) = 4  
   map(3).enteries(3) = -1 
   map(3).enteries(4) = 2  
   map(4).enteries(1) = 5  
   map(4).enteries(2) = -1   
   map(4).enteries(3) = 6  
   map(4).enteries(4) = 3
   map(5).enteries(1) = -1
   map(5).enteries(2) = -1
   map(5).enteries(3) = 4  
   map(5).enteries(4) = -1
   map(6).enteries(1) = 4
   map(6).enteries(2) = -1 
   map(6).enteries(3) = -1 
   map(6).enteries(4) = 7
   map(7).enteries(1) = -1 
   map(7).enteries(2) = 6
   map(7).enteries(3) = -1
   map(7).enteries(4) = -1
   
END CONSTRUCTOR

'directions data
DATA "north", "east", "south", "west"


''locations data
DATA "stable", "outside - yard", "yard", "yard road", "yard road", "up-stairs", "up-stairs" 


DESTRUCTOR position
   FOR y AS INTEGER = 1 TO 7
      
         FOR i AS INTEGER = 1 TO 4
      
            IMAGEDESTROY(map(y)._view(i))
         NEXT
      
   NEXT
END DESTRUCTOR

Sub centerPrint(row AS INTEGER, s AS STRING)
   LOCATE row ,(LOWORD(width) - LEN(s)) Shr 1 : PRINT s
END SUB

'APPEND TO the STRING array the STRING item
SUB sAppend(arr() AS STRING , Item AS STRING)
	REDIM PRESERVE arr(LBOUND(arr) TO UBOUND(arr) + 1) AS STRING
	arr(UBOUND(arr)) = Item
END SUB


SUB upper(f AS STRING)
	CLS
	REDIM lines(0) AS STRING
	DIM h AS LONG = FREEFILE()
	DIM AS INTEGER r = 35 , c = 30
	DIM fline AS STRING
	OPEN f FOR INPUT AS #h
	WHILE NOT EOF(h)
        LINE INPUT #h , fline
        sAppend lines() , fline
    WEND
	CLOSE #h
	
	DIM AS INTEGER hi = HIWORD(WIDTH()) 'num columns ON display
	'PRINT closing credits
	FOR i AS INTEGER = 0 TO UBOUND(lines)
        LOCATE hi , 10
        PRINT lines(i)
        SLEEP 500
    NEXT
	'CLEAR SCREEN
	FOR i AS INTEGER = 1 TO hi
        PRINT
        SLEEP 500
    NEXT
	PRINT "END"
	GETKEY()
END SUB


SUB position.display_screen(x AS INTEGER, z AS INTEGER)
   
   SCREENLOCK
   PUT (0,0), map(x)._view(z), TRANS
   centerprint 1, _direction(z)
   CENTERPRINT 3, map(x)._location
   CENTERPRINT 2, "press arrows key to navigate, press arrow key down for making an action, 'q' to exit"
   CENTERPRINT 15, message
   SCREENUNLOCK
   SLEEP 1
END SUB

SUB position.make_sound(f AS STRING, hWave AS INTEGER, t AS INTEGER)
   if fbs_Get_PlayingSounds() = 0 THEN
   fbs_Load_WAVFile(f , @hWave)
   fbs_Play_Wave(hWave , t)
   ENDIF
END SUB

SUB position.main()
   DIM AS INTEGER harpWav, stepsWav, knockWav
   DIM direc AS STRING
   DIM z AS INTEGER = 1, x AS INTEGER = 1
   DIM AS boolean isOpen = FALSE 
   DIM k AS STRING
   DO
   centerprint 15, "press any key to begin..."
   SLEEP
   DO
      k = INKEY
      CLS
      IF k = "q" THEN
         fbs_Destroy_Wave(@harpWav)
         fbs_Destroy_Wave(@knockWav)
         fbs_Destroy_Wave(@stepsWav)
         EXIT sub
      ENDIF
      
      IF x = 1 ANDalso z = 3 ANDALSO direc = "open door" THEN
         isOpen = TRUE
         message = "YOU OPEN THE LOCKED DOOR WITH THE GOLDEN KEY - THE DOOR IS OPENED"      
      
      ELSEIF x = 1 AND direc = "pick up key" THEN
         message = key.item_name & " " & key.state(2)
      
      ELSEIF x = 1 AND direc = "look around" THEN
         message = key.item_name & " " & key.state(1)
      
      ELSEIF x = 1 ANDALSO isOpen = FALSE THEN
         message = "DOOR IS LOCKED TYPE 'look around' TO FIND KEY"
      ENDIF
      
      IF k = key_rt THEN z += 1
      IF k = key_lt THEN z -= 1
      IF k = key_up THEN
         IF map(x).enteries(z) <> -1 ANDALSO isOpen = TRUE then 
            'x += 1
            x = map(x).enteries(z)
            make_sound("sound\step_02.wav" ,stepsWav, 1)
            message = ""
         ELSE
            message = "PATH IS BLOCKED! OR YOU CANNOT GO THERE!"
         ENDIF
      ENDIF
      
      IF k = key_dn THEN
         display_screen(x,z)
         LOCATE 36, 1
         INPUT "choose action ", direc
      ENDIF
      
      IF z < 1 THEN z = 4
      IF z > 4 THEN z = 1
      IF x < 1 THEN x = 1
      IF x > 7 THEN x = 7 
      display_screen(x,z)
            
      IF x = 2 THEN
         make_sound("sound\harp.wav" ,harpWav, 1)
      ENDIF
    
      
      
      'LOCATE 36, 1
      'INPUT "choose direction('r' = right, 'l' = left, 'f' = forward) or an action or key 'q' to quit: ", direc
      
   LOOP
   
   LOOP UNTIL INKEY = CHR(27)
END SUB

IF fbs_Init()=false THEN
PRINT "error: FBS_INIT() " & FBS_Get_PlugError()
BEEP : SLEEP : END 1
END IF

SCREENRES scr_w, scr_h, 32
WIDTH scr_w \ 8, scr_h \ 16
DIM game AS position
game.main()
'UPPER("ending.txt")
last edit: fixed bugs

ron77
Post Reply