on the adventure game

advertisement
unit 7
more on the adventure game
Working with the code

The code is divided into
several files

It is distributed as a .zip file


Download it from the web
Unzip it into the directory of
your choice

The list of files is stored in the
variable source-files in
Adventure.meta

To add a new file



To load the code


Click the file “Adventure.meta”
Choose Execute All from the
Execute menu

Add its name to the end of
source-files
Type Control-E to update the
definition
Run: [reload]
A tour of the code

Adventure.meta




Sound stuff.meta


Basic code for handling
text input
Basic class files


Things.meta, Places.meta,
Actors.meta, Player.meta,
Portals.meta

OS-dependent code for
window updating, and
handling of user events
(clicks and text input)
String utilities.meta


OS-dependent code for
loading and playing .wav
files
User interface.meta
Parsing.meta


List of source files
Code to load other source
files
Code to find art assets
(sound and image files)

Stuff for handling text
Sample game.meta

Example game
You only need to worry about the basic class files and the sample game
Subdirectories

Sounds



Holds any sound files you want (.wav only, sorry)
Files can be accessed using the [sound-file filename] procedure
Images


Holds any images files (.jpg, .gif, .bmp, or .png) you want to use
Files can be accessed using the [image-file filename] procedure
Note:

You don’t have to include the directory names in the filenames
for sound-file and image-file. They know to search in the
Sounds and Images directories, respectively.
Recap: OOP in Meta

[class [Name fields …]
Parent more-fields …]






Makes a new object of type Type
And sets its fields based on args
Defines a method for initializing an
object of type Type before it’s returned
by new



Makes a procedure that can be
specialized with methods
[define-method [generic [Type arg] …]
body …]

[define-method [initialize [Type arg]]

[generic-procedure]

[new Type args …]


Creates a new class named Name
With parent class Parent
And fields fields … and more-fields …

Adds/modifies a method for generic
procedure generic
Matches only those calls whose args
have their corresponding Types
When a match is found, executes body
[call-next-method]

When used inside a method, calls the
method of the parent class
An adventure game in Meta

Supports



Pictures (for point-and-click style)
Text output
Sound

You can decide which of these you want to use

Basic ontology




Things (have name, location)
Places (have name, contents)
Player
Portals (have name, location, destination)
The Thing class

Things have:

Name



Location



A string describing the
object
May be null
Place in which the Thing
can be found
May be null
Adjectives


List of strings describing
the object
May be null
[define Thing
[class [Thing name location]
Object
adjectives]]
[define-method [initialize [Thing x]]
[move x x.location]]
The Place class

Places have


Contents
A list of Things inside them
Sound



Sound-loop?


If true, the sound plays
continuously
Image


Buffer to play when the user
enters the room
Can be null if no sound
Bitmap to display when the user
enters the room
Hotspots

A list of places in the image the
player can click and handlers
(procedures to call) for when
they’re clicked
[define Place
[class [Place name]
Thing
contents hotspots
sound sound-loop?
image]]
[define-method [initialize [Place p]]
[call-next-method]
[p.contents ← [new ArrayList]]]
Update:
Handling clicks of the mouse

We’ve made definition of click actions
more versatile since the last lecture
[define click
[generic-procedure]]

The hotspots of a Place is a field with
a list of lists:
[define-method [click [Place p] mouseEventArgs]
[with x = mouseEventArgs.X
y = mouseEventArgs.Y
[unless [null? p.hotspots]
[for-each [hotspot →
[when [and [≥ x [first hotspot]]
[≥ y [second hotspot]]
[≤ x [third hotspot]]
[≤ y [fourth hotspot]]]
[click [fifth hotspot]]]]
p.hotspots]]]]


[list left top
right bottom
handler]
Where:



Left and top give the coordinates of
the upper-left corner of an area of the
image
Right and bottom give the coordinates
of its lower-right corner
handler is either a procedure to call
or a game object such as a place




If it’s a procedure, the system calls it
If it’s a string, the system prints it
If it’s a place, the system moves the
user there
If it’s any other game object, it runs
click on it.
[define-method [click [Place p]]
[move the-player p]
true] «Returning true tells the system to update the
image, replay the sound, and generate new text»
[define-method [click [String s]]
[print-line s]
false] «Returning false means don’t redraw anything»
[define-method [click [Procedure p]]
[p]]
The Portal class

Portals are objects that, when
clicked on, move the player to
a specified destination

However, it looks funny for the
system to print “You see a
portal”

So there’s a subclass called
“Door”
[define Portal
[class [Portal name location
destination]
Thing]]
[define Door
[class [Door name location
destination]
Portal]]
[define-method [click [Portal p]]
[move the-player p.destination]
true]
Handling text input
[define-pattern procedure
pattern …]
 Tells the system to run
procedure when the user types
something that looks like
pattern …
 Elements of pattern can be:


Strings (must be matched
exactly)
Type names


String (the type)
Matches whatever the next
word is
Thing, Place, etc.
System searches the user’s
current location for an object
of this type
[define quit
[→
[current-window.Close]
false]]
[define-pattern quit “quit”]

Tells the system to run the quit
procedure when the player
types “quit”
A fancier example

This example sets the variable
mouse-debug-mode?


To true when the user types
“mouse debug on”
Or false if they type “mouse
debug off”
[define set-mouse-mode
[mode →
[mouse-debug-mode?
← [≠ mode “off”]]
[print-line
[if mouse-debug-mode?
“Mouse hits will display coordinates”

When mouse-debug-mode? is
true



The system prints the image
coordinates of the point you click
on
Rather than running the click
procedure
This lets you easily find
coordinates when you’re making
hotspots in your images
“Mouse hits will call click methods”
false]]
[define-pattern set-mouse-mode
“mouse” “debug” String]
]]
Other built-in handlers

“debug [on/off]”



Turns the variable debug-mode? true or false
Not used by the system but might be useful
for you.
“go back”

Brings the user to the place they were last
A more interesting example

Typing “go to” and a Portal
clicks the Portal (which moves
the user to the portal’s
destination)

You can define behavior for
going to other kinds of things
by writing methods for the goto
procedure.
[define goto [generic-procedure]]
[define-method [goto [Thing p]]
«Nothing happens»
false]
[define-method [goto [Portal p]]
[click p]]
[define-pattern goto
“go” “to” Thing]
[define-pattern goto “go” Thing]
The sample game

Brief highlights of my trip
to AAAI last year



AAAI is an Artificial
Intelligence Conference
Yes, I know this is a lame
example
To run it:


Load: Sample game.meta
Run [sample-game]
[define great-hall null]
[define robot-room null]
[define art-room null]
[define origami-room null]
[define sample-game
[→
[great-hall ← [new Place “the Video Games Symposium”]]
[robot-room ← [new Place “the robot area”]]
[art-room ← [new Place “the art installation”]]
[origami-room ← [new Place null]]
[set-up-hall]
[set-up-robot-room]
[set-up-art]
[set-up-doors]
[start-game “Sample game”
800
600 100 100]]]
Example room: the great hall

It’s best to write a separate
procedure to initialize each
room



Set up sound and image
Set misc-text field



Which we didn’t talk about,
but which prints when you
enter the room
Set hotspots to various
strings and procedures to
run
Make the player


That keeps the top-level
procedure from being too
big and hard to read
And put it in the magic
variable the-player
Make the nerds
[define set-up-hall
[→
«Set up the great hall»
[great-hall.image ← [image-file “Aaron talk.jpg”]]
[great-hall.sound ← [sound-file “clap.wav”]]
[great-hall.misc-text ←
“Aaron Khoo is giving a talk on Mythica.”]
[great-hall.hotspots ←
[list [list 174 392 238 471 ouch]
[list 466 346 585 451 ouch]
[list 46 87 513 440
“Stop that. You'll get finger prints on it.”]
[list 640 320 760 450
“Aaron says Mythica was great until they killed the project.”]]]
[the-player ← [new Player “Emily” great-hall]]
[with nerds = [new Nerds null great-hall]
[nerds.adjectives ← [list “many”]]]]]
The ouch procedure
[define ouch-counter 0]
[define ouch-statements
[list “Ouch”
“Please don't do that.”
“Ouch!”
“Are you having a good time?”
“This is getting a little infantile, isn't it?”]]
[define ouch
[→ [print-line [get ouch-statements ouch-counter]]
[when [< ouch-counter
[− [length ouch-statements] 1]]
[ouch-counter ← [+ ouch-counter 1]]]]]
The Eat procedure

Lets you type “Eat
[Thing]”

Simulates destroying the
Thing by moving it to null
(i.e. nowhere)




Now it’s not in the room
And so it appears to be
destroyed
Prints “Mmmm, yumming
Things …”
Returns false

Which tells the system
not to redraw the
display
[define eat
[thing →
[move thing null]
[print-line
“Mmmm, yummy ”
[[type-of thing].Name.ToLower]
“...”]
false]]
[define-pattern eat
“eat” Thing]
The art and origami rooms

The art room
[define set-up-art
brings you to the
[→
origami room when
«Set up the art room»
you click on it
[art-room.image ← [image-file “Art installation.JPG”]]
[art-room.misc-text
← “It was make by art and robotics students from the University of New Orleans.”]
[art-room.hotspots ← [list [list 130 50 323 360
origami-room]]]
«Set up the origami room»
[origami-room.image ← [image-file “Origami room.jpg”]]
[origami-room.sound ← [sound-file “dog-bark4.wav”]]
[origami-room.adjectives ← [list “origami filled”]]]]
Making doors

Doors in this system are only
one-way




So we need to make doors in
pairs



They live in one room
And lead to the other
But aren’t visible in the other
One from room A to room B
One from room B to room A
So it’s easiest to make a
procedure to do this for us
[define make-door-pair
[place1 name1 place2 name2 →
[new Door name1 place1 place2]
[new Door name2 place2 place1]]]
[define set-up-doors
[→
«Connect the rooms»
[make-door-pair
great-hall null
robot-room “symposium”]
[make-door-pair art-room null
robot-room “art”]]]
Download