Click to See Complete Forum and Search --> : I'm creating a text adventure game, and would like some help
Marble
Dec 18th, 2000, 09:36 AM
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.
theroper
Dec 19th, 2000, 11:33 AM
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!
Jotaf98
Dec 19th, 2000, 07:23 PM
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:
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... ;)
Jotaf98
Dec 19th, 2000, 07:25 PM
Sorry, forgot one thing in the middle of the type tZone:
Description As String
Uh-oh, really gotta go now. I'll explain the rest later.
Jotaf98
Dec 20th, 2000, 05:09 PM
(I typed this before going online, I looked at the file's size and it's above 9kb! :p)
Let me explain what I was trying to do:
'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.
'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:
'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:
'The zone where the player is
Dim CurrentZone As Long
Now we need a function to test the player's input:
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).
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...).
markman
Dec 21st, 2000, 12:38 PM
This is exactly like that old game where you guide this man to find a lover. Its out there somewhere (search for abandonware).
Jotaf98
Dec 21st, 2000, 03:55 PM
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...
Marble
Dec 21st, 2000, 06:04 PM
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!
Jotaf98
Dec 21st, 2000, 06:20 PM
It's ok, it happens to me a lot too ;)
MoMad
Dec 21st, 2000, 11:03 PM
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.
Jotaf98
Dec 22nd, 2000, 05:51 PM
Thanks!
My biggest problem is making them work in Netscape, so if you can help me, e-mail me to jotaf98@hotmail.com .
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? :)
MoMad
Dec 22nd, 2000, 05:54 PM
We have a similar problem dont we?
I dont like Netscrapp too...
but i think i can help!!
Why? --because im da man!!
lol.
Marble
Dec 26th, 2000, 01:02 PM
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:
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 :)
Marble
Dec 26th, 2000, 05:58 PM
Sure, it would be great if you could help me out with .ini files. I have heard that they are very useful in games.
Jotaf98
Jan 2nd, 2001, 06:02 PM
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).
M@rk
Jan 3rd, 2001, 01:47 PM
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
MoMad
Jan 4th, 2001, 12:11 AM
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...
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.