Results 1 to 17 of 17

Thread: I'm creating a text adventure game, and would like some help

  1. #1

    Thread Starter
    New Member
    Join Date
    Nov 2000
    Posts
    10
    Well, I've got the basic layout for the adventure game. The playing area is going to be a form with two text boxes. One for input, one for output. There are also other forms, such as the inventory and start form.

    The input is going to be like this. For example, let's say the user wanted to look at the tree:

    Private Sub Text1_KeyPress(KeyAscii As Integer)
    Dim Look, Tree
    Look = InStr(Text1, "look")
    Tree = InStr(Text1, "tree")

    If (Look > 0 And Tree > 0) And (KeyAscii = 13) Then
    Text1.Text = ""
    Text2.Text = ("Description of tree")
    ElseIf KeyAscii = 13 Then
    Text2.Text = ("I don't understand")
    Text1.Text = ""
    End If
    End Sub

    To move from screen to screen, I'll simply call a new procedure. So if there's two rooms, a castle and a forest, there would be two procedures. If the user types "north" or "south", then the game would change to the appropriate procedure.

    So... what I want to know is, is this a good way of doing an adventure game? Should I use arrays, or API calls? I'd appreciate any help I could get on this, as I would like to start making adventure games that are coded correctly.

  2. #2
    New Member
    Join Date
    Aug 2000
    Posts
    15

    Smile

    O.k. heres a bit of quick info on how i would do it.

    If you need any more info let me know

    Use classes for Room,Player,Item etc

    These will have properties for things like name,description etc.

    use a multi-dimensional array to put these items into a map.

    i.e.

    so for instance in (1,1) top corner of map you could have a room a player and a number of items etc. (hope that makes sense!)

    then you just move around the array etc.

    This way you can create as many rooms as you want and put them where you want in the map.

    you can also drop things in a room etc and they will stay there.

    I hope this makes some sense. If you need any more help let me know and i will explain better when i have more time!




  3. #3
    Frenzied Member Jotaf98's Avatar
    Join Date
    Jun 2000
    Location
    I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
    Posts
    1,457
    Hum... the best way would be to keep the whole adventure in a file, under a file format made by you, instead of hard-coding it (but if you're not an experienced programmer, you should continue doing it like you're doing it now).

    I saw a demo on this in Unlimited Realities - http://www.ur.co.nz/ - look for Adventure Game or something. It's because this way, the user could even make his own adventure!

    It's kinda complex, so your best bet would be this one: try to find an easy-to-use module with a function to read from an INI file. If you can't, I'll e-mail you mine.

    What you do is have an array of a custom type like this:

    Code:
    Private Type tZone
        LinkKeywords() As String
        LinkDestination() As Integer
    End Type
    
    Dim Map() as tZone
    Wow, this is getting better than I expected. I might make one game like this myself, it's easy and cool!

    But I don't have more time right now, it's late and my mom is telling me to go to bed. I'll explain you the rest tomorrow, don't worry. And all you pros out there that would like to answer, please let me answer at least this one, please...

  4. #4
    Frenzied Member Jotaf98's Avatar
    Join Date
    Jun 2000
    Location
    I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
    Posts
    1,457
    Sorry, forgot one thing in the middle of the type tZone:

    Code:
        Description As String
    Uh-oh, really gotta go now. I'll explain the rest later.

  5. #5
    Frenzied Member Jotaf98's Avatar
    Join Date
    Jun 2000
    Location
    I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
    Posts
    1,457
    (I typed this before going online, I looked at the file's size and it's above 9kb! )

    Let me explain what I was trying to do:

    Code:
    'The map
    Private Type tZone
        LinkKeywords() As String
        LinkDestination() As Long
        Description As String
    End Type
    
    Dim Map() as tZone
    Basically, you have a 1-dimension array, called Map. Each element of this array is of type tZone.

    Each zone has a description to display when you enter it ("Description"), an array with the keywords the user must type for each link of this zone ("LinkKeywords"), and another array with the destination zone of each of these links ("LinkDestination").

    This is how the map will be kept in memory. With this in mind, it's much easier to figure out the rest of the program!



    Now, imagine an INI file like this, where the whole adventure would be kept:

    ----------------------------------------

    [Map]

    NumZones=5



    Zone1Description=You wake up in your bed and look at the rest of your room. Perhaps you should go pick up your gun, just in case it's not a dream and the aliens are real...

    Zone1NumLinks=1

    Zone1Link1Keywords=gun,pistol
    Zone1Link1Destination=2



    Zone2Description=Good! Now you feel more safe. But you can't stay here the rest of your life, you should go outside and see what's happened to the city. Or maybe you could have breakfast and think it was only a dream...

    Zone2NumLinks=2

    Zone2Link1Keywords=breakfast,dream
    Zone2Link1Destination=3

    Zone2Link2Keywords=outside,out
    Zone2Link2Destination=5



    Zone3Description=You feel much better! That dream seems each time farther and farther away... Suddenly, you see something in the window. It's an alien! You point your gun to it, what are you waiting for?

    Zone3NumLinks=1

    Zone3Link1Keywords=attack,kill,shoot,fire
    Zone3Link1Destination=4



    Zone4Description=One bullet in the head was enough to kill it. Maybe it was just luck. You should go outside and see what's happening.

    Zone4NumLinks=1

    Zone4Link1Keywords=outside,out
    Zone4Link1Destination=5



    Zone5Description=You can't believe in what your eyes are seeing! Lots of UFOs coming from the skies and some of them have already started burning houses! You see one of them landing about 100 meters from you. An alien comes out, but it seems that it didn't notice you. There's also a trash can right next to you, if you're quick enough he might not notice you. Or you could just kill him with your gun and stop this once and for all!

    Zone5NumLinks=2

    Zone5Link1Keywords=trash,can,jump
    Zone5Link1Destination=6

    Zone5Link2Keywords=attack,kill,shoot,fire
    Zone5Link2Destination=7

    ----------------------------------------

    That seems like a decent adventure! Of course it wouldn't stop there, you need zones 6 and 7 and the rest of the story. You should also give the user lots more options. But it seems OK just for testing. It's also very intuitive so I think there's no need to explain it to you

    The module with the functions is here, just open VB, create a new module, paste this in it and save it. Then add it to your project. I think modules with functions are waaay better than classes because they're faster. Calling a function is faster than modifying a property, you can read it in VB's documentation.

    Code:
    'This module has a function to read from INI files. The function to write them is not necessary here, so I deleted it.
    
    'APIs:
    Private Declare Function GetPrivateProfileString Lib "kernel32" _
        Alias "GetPrivateProfileStringA" _
        (ByVal lpApplicationName As String, _
        ByVal lpKeyName As Any, ByVal lpDefault As String, _
        ByVal lpReturnedString As String, ByVal nSize As Long, _
        ByVal lpINIPath As String) As Long
    
    Public Function ReadINI(ByVal Section As String, ByVal Key As String, ByVal INIPath As String) As String
        Dim RetStr As String
        
        If Dir(INIPath) = "" Then Exit Function
        
        RetStr = String(255, Chr(0))
        ReadINI = Left(RetStr, GetPrivateProfileString(Section, ByVal Key, "", RetStr, Len(RetStr), INIPath))
    End Function
    Now you're ready to code! First, add another module (just to keep things organised) that will have the program's core functions. It's also where you should paste the type and the Map array I gave you above.

    This is a function to load a map into memory:

    Code:
    'Simple loop counters
    Dim i As Long, j As Long
    
    Public Sub LoadMap(Path As String)
        'These variables are only temporary
        Dim NumZones As Long
        Dim NumLinks As Long
        Dim TempStr As String
        
        'Read the number of zones: NumZones
        NumZones = ReadINI("Map", "NumZones", Path)
        
        'Resize the Map to make space for all the zones
        ReDim Map(1 To NumZones)
        
        'Loop trough all zones...
        For i = 1 To NumZones
            'Get the description: Zone[zone-number]Description
            Map(i).Description = ReadINI("Map", "Zone" & i & "Description", Path)
            
            'Get the number of links this zone has:
            'Zone[zone-number]NumLinks
            NumLinks = ReadINI("Map", "Zone" & i & "NumLinks", Path)
            
            'Resize this zone's links' array to make space for them
            ReDim Map(i).LinkKeywords(1 To NumLinks)
            ReDim Map(i).LinkDestination(1 To NumLinks)
            
            'Now, loop trough all of this zone's links and load them
            For j = 1 To NumLinks
                'Load this link's keywords:
                'Zone[zone-number]Link[link-number]Keywords
                Map(i).LinkKeywords(j) = _
                  ReadINI("Map", "Zone" & i & "Link" & j & "Keywords", Path)
                
                'Load this link's destination:
                'Zone[zone-number]Link[link-number]Destination
                Map(i).LinkDestination(j) = _
                  ReadINI("Map", "Zone" & i & "Link" & j & "Destination", Path)
            Next j
        Next i
        
        'Also, set the current zone to the first one and display the
        'first zone's text
        CurrentZone = 1
        frmGame.lblText.Caption = Map(1).Description
    End Sub
    That was complicated! But don't worry, it was the most difficult part of your game. I'm also assuming the game's form is frmGame and the label (or text box) where the text will be displayed is lblText.

    Before we do anything else, we need to know what's happening in the program. Normally you'd keep the player's X/Y coordinates, his ammo, weapons, etc. But we only need one thing: the zone where he is right now. Add this right before the previous function:

    Code:
    'The zone where the player is
    Dim CurrentZone As Long
    Now we need a function to test the player's input:

    Code:
    Public Sub ExecCommand(Command As String)
        Dim CommandWords() As String
        Dim LinkKeywords() As String
        
        'Separate the words into an array (using spaces as the
        'delimiters)
        CommandWords = Split(Command, " ")
        
        'Now, loop trough all of this zone's links and check if
        'the player's words match any one of these
        For i = 1 To UBound(Map(CurrentZone).LinkKeywords)
            'A link's keywords are separated by a comma (,) so
            'separate them into an array
            LinkKeywords = Split(Map(CurrentZone).LinkKeywords(i), ",")
            
            'Loop trough all keywords...
            For j = 0 To UBound(LinkKeywords)
                'Loop trough all of the player's words...
                For k = 0 To UBound(CommandWords)
                    'If these words match...
                    If LCase(CommandWords(k)) = LCase(LinkKeywords(j)) Then
                        'Execute this link by setting the current zone to
                        'the current link's destination...
                        CurrentZone = Map(CurrentZone).LinkDestination(i)
                        
                        '...displaying the new zone's text...
                        frmGame.lblText.Caption = Map(CurrentZone).Description
                        
                        '...and finally exiting our loop
                        GoTo ExitLoop
                    End If
                Next k
            Next j
        Next i
        
    ExitLoop:
    End Sub
    It's done! Ever imagined a game with only two functions? Here it is!

    Now we need to setup the rest. Make the label where the player will read what's happening (lblText) and the text box where he gives the program some input (txtInput).

    Now paste this code into the form (the form's name should be frmGame).

    Code:
    Private Sub Form_Load()
        'Load the default map...
        LoadMap App.Path & "\Adventure.ini"
    End Sub
    
    Private Sub txtInput_KeyPress(KeyAscii As Integer)
        'User pressed Enter
        If KeyAscii = vbKeyReturn Then
            'Execute this command
            ExecCommand txtInput.Text
            
            'Clear the text box
            txtInput.Text = ""
        End If
    End Sub
    There you have! Your very own game! Go ahead, test it - it works!

    Now you could add more stuff to it - allow the INI file to change the colors, the form's caption, display an image, maybe an about box, whatever you want!

    Also make sure the INI file I gave you is in the game's folder, with the name Adventure.ini (you can change it above).

    And if you test it until zone 5, you'll notice that the text is cut in half. That's because the API we used to read the INI file reads only the first 254 characters and cuts the rest. This can be fixed with a "hand-crafted" function to read the INI file, I'll try to do it later.

    Hope you liked this and found it useful! Maybe I'll post it in my web page as a tutorial (once I get the JavaScripts to work in Netscape... grrr...).

  6. #6
    Frenzied Member markman's Avatar
    Join Date
    Nov 2000
    Location
    Florida.
    Posts
    1,197
    This is exactly like that old game where you guide this man to find a lover. Its out there somewhere (search for abandonware).
    retired member. Thanks for everything

  7. #7
    Frenzied Member Jotaf98's Avatar
    Join Date
    Jun 2000
    Location
    I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
    Posts
    1,457
    I spent 3 hours making that, writing all the comments and explaining what I was doing (I'm not that good!), it would've been nice someone thanking me...

  8. #8

    Thread Starter
    New Member
    Join Date
    Nov 2000
    Posts
    10
    Whoops! I posted this message a few days ago, and nobody seemed to be replying to it. So I kind of forgot about this site and the topic I posted, and when I came back I had all these replies

    Anyway, thanks a lot for all your help, Jotaf! I definitely appreciate it. Although I haven't tested the whole thing yet, I'll let you know how your code works as soon as I've got a test adventure game up and running.

    Well, thanks again!

  9. #9
    Frenzied Member Jotaf98's Avatar
    Join Date
    Jun 2000
    Location
    I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
    Posts
    1,457
    It's ok, it happens to me a lot too

  10. #10
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625

    Thumbs up Chuka-Laka!!

    Nice work Jotaf98,
    As for the Javascript part of ur site, if you need help, just ask me (MoMad the NoMad)

    anyways you did well guiding him through the whole process, step by step!!-- you are really good, (at least better than me) because my tut would suck real bad and i would just give up and say mumble-jumble!!

    so u see, u did real good and i am thanking you for you generousity.

    Keep up the good work M8.
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  11. #11
    Frenzied Member Jotaf98's Avatar
    Join Date
    Jun 2000
    Location
    I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
    Posts
    1,457
    Thanks!

    My biggest problem is making them work in Netscape, so if you can help me, e-mail me to [email protected] .

    I'm also making a small software team (the javascripts are for our page) and you could enter it if you want, just send me your best VB project

    PS: Where do you get all those cool words from?

  12. #12
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625

    Yepp!!

    We have a similar problem dont we?

    I dont like Netscrapp too...

    but i think i can help!!

    Why? --because im da man!!

    lol.
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  13. #13

    Thread Starter
    New Member
    Join Date
    Nov 2000
    Posts
    10
    Jotaf98, here's the game I said I would make. I have you to thank for this game. All the room descriptions and everything are yours from the previous posts you made in this topic. As I'm only a beginner at programming, I don't understand about .ini files or even arrays yet, but what you did write down was very helpful. So, I hope you enjoy this game, even if I did code it very badly

    Your resolution should be set to 1024*768.

    To play this game, set the form and objects as follows:

    Form
    height: 5775
    left: 240
    top: 9255
    width: 9930

    Label
    name: lblinfo
    height: 3855
    left: 240
    top: 9255
    width: 9255

    Textbox
    name: txtInput
    height: 975
    left: 240
    top: 4200
    width: 9255

    And here's the code for the game:

    Code:
    Option Compare Text
    Option Explicit
    
    Dim Roomletter As String
    
    Private Sub txtInput_KeyPress(KeyAscii As Integer)
        
        If (Roomletter = "A") And (KeyAscii = 13) Then
            Call room1
        End If
        
        If (Roomletter = "B") And (KeyAscii = 13) Then
            Call room2
        End If
        
        If (Roomletter = "C") And (KeyAscii = 13) Then
            Call room3
        End If
        
        If (Roomletter = "D") And (KeyAscii = 13) Then
            Call room4
        End If
        
        If (Roomletter = "E") And (KeyAscii = 13) Then
            Call room5
        End If
        
    End Sub
    
    Private Sub Form_Load()
        
        lblInfo = "You wake up in your bed and look at the rest of your room. Perhaps you should go pick up your gun, just in case it's not a dream and the aliens are real..."
        Roomletter = "A"
    
    End Sub
    
    Private Sub room1()
    
        Dim gun, pistol
        
        gun = InStr(txtInput, "gun")
        pistol = InStr(txtInput, "pistol")
        
        lblInfo = "You wake up in your bed and look at the rest of your room. Perhaps you should go pick up your gun, just in case it's not a dream and the aliens are real..."
        
        If (gun > 0) Or (pistol > 0) Then
            Roomletter = "B"
        Else
            Clear
        End If
        
    End Sub
    
    Private Sub room2()
    
        Dim breakfast, dream
    
        Roomletter = "B"
        
        breakfast = InStr(txtInput, "breakfast")
        dream = InStr(txtInput, "dream")
        
        lblInfo = "Good! Now you feel more safe. But you can't stay here the rest of your life, you should go outside and see what's happened to the city. Or maybe you could have breakfast and think it was only a dream... "
        
        If (breakfast > 0) Or (dream > 0) Then
            Roomletter = "C"
        Else
            Clear
        End If
        
    End Sub
    
    Private Sub room3()
    
        Dim attack, shoot, fire
        
        Roomletter = "C"
        
        attack = InStr(txtInput, "attack")
        shoot = InStr(txtInput, "shoot")
        fire = InStr(txtInput, "fire")
        
        lblInfo = "You feel much better! That dream seems each time farther and farther away... Suddenly, you see something in the window. It's an alien! You point your gun to it, what are you waiting for?"
        
        If (attack > 0) Or (shoot > 0) Or (fire > 0) Then
            Roomletter = "D"
        Else
            Clear
        End If
        
    End Sub
    
    Private Sub room4()
    
        Dim outside, out
        
        Roomletter = "D"
        
        outside = InStr(txtInput, "outside")
        out = InStr(txtInput, "out")
        
        lblInfo = "One bullet in the head was enough to kill it. Maybe it was just luck. You should go outside and see what's happening."
        
        If (outside > 0) Or (out > 0) Then
            Roomletter = "E"
        Else
            Clear
        End If
        
    End Sub
    
    Private Sub room5()
    
        Dim trash, can, jump
        Dim attack, shoot, fire
        
        Roomletter = "E"
        
        trash = InStr(txtInput, "trash")
        can = InStr(txtInput, "can")
        jump = InStr(txtInput, "jump")
        
        attack = InStr(txtInput, "attack")
        shoot = InStr(txtInput, "shoot")
        fire = InStr(txtInput, "fire")
        
        lblInfo = "You can't believe in what your eyes are seeing! Lots of UFOs coming from the skies and some of them have already started burning houses! You see one of them landing about 100 meters from you. An alien comes out, but it seems that it didn't notice you. There's also a trash can right next to you, if you're quick enough he might not notice you. Or you could just kill him with your gun and stop this once and for all!"
        
        If (attack > 0) Or (shoot > 0) Or (fire > 0) Then
            lblInfo = "You missed! The alien quickly turns and zooms after you... Well done, you completed the demo!"
        ElseIf (trash > 0) Or (can > 0) Or (jump > 0) Then
            lblInfo = "You quickly hide behind the trash can. Well done, you completed the demo!"
        Else
            Clear
        End If
        
    End Sub
    
    Private Sub Clear()
        txtInput.Text = ""
    End Sub
    And that's it. That's about the limits of my very basic programming knowledge

    Of course, it could be more advanced than that. There could be a form for handling inventory. A counter which monitors which room you are at. If you notice in this game, you only have a choice of going in one direction. Whereas you could make it so that you could revisit rooms by perhaps having buttons, or keyboard commands which move you to different rooms.

    Anyway, hope you enjoy the game. Remember, it is only a very small test, so don't expect it to be good

  14. #14

    Thread Starter
    New Member
    Join Date
    Nov 2000
    Posts
    10
    Sure, it would be great if you could help me out with .ini files. I have heard that they are very useful in games.

  15. #15
    Frenzied Member Jotaf98's Avatar
    Join Date
    Jun 2000
    Location
    I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
    Posts
    1,457
    Well, basically it's an easy way of storing string vars in a file. Call the function to read a key (variable) at a section (to keep things organized) and that's it. Look at my other explanation because right now I have no more time (just came back from holidays).

  16. #16
    Member
    Join Date
    Nov 2000
    Location
    Palma de Mallorca, Spain
    Posts
    39

    Just a sugestion

    To store data for a game use your own file extension so that people can open the .ini and mess with the data(Well people can always open it with Word but this will work until they realize of that)
    To save just:
    Open filepath for output as #1
    Write #1 , "BlaBlaBlaBlaBla"
    Let's supose filepath is "C:\game\File.data"
    You'll be creating a File.data file in that folder
    To get info from it use the Get function
    Code:
    On Error goto Hell

  17. #17
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625

    Talking Chuka-Laka!!


    Good Programming Tip: Always use relative path....

    App.Path & "/folder/file.ext"

    This is a good tip and very useful.... infact you can dim a variable called filePath = app.path so that you can just say filepath & something...
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width