Lab 1 - Introduction to GameX
The Computer Game Design Project - Part 1, Fall
2004
This week's lab is an introduction to
GameX. We'll learn how to use GameX,
in the Visual Studio .NET environment, to make a basic game by compiling a
sample program called ShipDemo, and then modifying it
in various ways.
You may work in pairs if you wish. This lab is not due during this lab period, but it is to your advantage to work through as much as you can now, while assistance is immediately available.
If you run into problems finishing the lab project later, remember to make use of the course newsgroup for help.
Getting Started Using GameX with VS.NET
The GameX official homepage is http://www.rchoetzlein.com/gamex/
(but you should use the mirror at www.cs.cornell.edu/projects/game/GameX/ ).
There you will find an overview of GameX and a description
of its interface. It also has links to download GameX
and the ShipDemo, in the event that they aren't
already on your machine. (They probably aren't, in which case you should download and unzip "GameXR5Pack.zip" from the Downloads section.)
For this lab we will be using GameX version 5.04.
The first time you run Visual Studio .NET, it may prompt you with various
questions about what kind of environment you want. I recommend you indicate you
are a C++ developer.
We could just load the ShipDemo solution from the
project file, but let's recreate the project for practice:
1) From the file menu,
select a new project, and choose Win32 project under Visual C++ projects. Make
sure you choose the location you want for the project (the default is
fine as long as you know where it is). Name the project "MyShipDemo".
2) After hitting OK, in the next window go to the
application settings tab, and make sure "Windows Application" and
"Empty Project" are both checked. (NOTE: This step is very easy to forget,
but your project will initially fail to compile if you don't do it.)
3) We need to specify the directories that VC++ will
find the GameX files in. In the Tools
menu, select Options. Under Projects->VC++ Directories, Select "Include
files" in the pull-down menu, and the directories for GameX
(wherever you put it on the machine, for instance "Z:\GameXR5Pack\GameXR5").
Then select "Library files" from the pull-down, and add the same GameX directory
there too. Alternatively, if you want these changes to be saved within your project
so you don't need to make them every time you switch to a new computer,
you can set GameX as an include and library directory in your project properties:
Right-click on the Project (not the solution) in the "Solution Explorer" pane
and choose Properties, change Configuration to "All Configurations", then set the
C/C++ -> General -> Additional Include Directories field and the
Linker -> General -> Additional Library Directories field to the same GameX directory.
4) You'll now have an empty project. Now we need to
add the source and header files. First, physically copy the .cpp and .hpp files into whatever
directory your project is in (so we're using fresh copies of the code, rather
than just the original code files). You'll also need to copy the Images folder
and Sounds folder into that same directory. Then you can add the source files
by either dragging them to the Source (or Header) files folder on the left side
of the development environment, or by right-clicking on the Source (or Header)
Files folder item and choosing "Add Existing Item" to browse for
files to add. Add the three .cpp files to the Source
Files, and the two .hpp files to the Header Files.
5) Make sure your display is set to 16-bit color so
that your game will start up faster. Then compile and run the demo by hitting
F5.
For future reference: Pressing Shift-F5 from VS.NET will immediately stop your game from running even if it has crashed or frozen,
F9 adds/removes breakpoints, F10 steps (runs one line),
F11 steps into a function call, Shift-F11 steps out of a function, and F5 continues (or starts) running normally (with debugging).
Also, Ctrl-Shift-S can be used to save everything at once (all open code files, project settings, etc.).
Lab Project
To help get familiarized with how GameX
works, we're going to be making a series of modifications to ShipDemo.
Before doing so, it might be helpful to look
through the code and see how it works. The GameX
official page details a good chunk of similar code in its examples. After you
understand the code to some degree, make the following changes (in the order
given):
1) In shipdemox-main.cpp,
add an extra parameter (an int of 60) to the call to GameX.Initialize,
right after the parameter that starts as 400. If you run the game now, there
should be no change. Now change the 60 to different values such as 100, 30,
600, and 5. Describe briefly what happens, i.e. the effect these have on the
gameplay and/or graphics (in a file called readme.txt you
will submit later). Leave the extra parameter at 60. If you wish to know more
about what GameX is doing here, see the section
"About Game Speed and Frame Rate" in the GameX
documentation.
2) Modify the size of the game
window, which starts as 800x400. Try several sizes, including 400x300,
100x1000, and 2000x2000, to see what happens. Try running the
game in both windowed and full-screen mode for the various sizes, and fly the
ship around and fire a little for each one. How do the ships and photons
know to change where they bounce off of when you change the size of the screen?
Does the game perform worse and/or look worse with some sizes than others? Is
there a minimum or maximum size? Is there a "best" width to height
ratio, and if so, in what way is it best? (Answer these questions either now or
later, in your readme.txt.) Leave the game window set to 800x600 when done.
3) In shipdemox-ship.cpp,
in the Ship::Draw method, change the size of the
ships by changing each "1.0f" to a different value, and describe what
the trend is for what different values do. Make sure to change the size of the
ship's shadow by the same amount you change the size of the ship. Leave the size
at 125% of normal, and also change the collision detection radius of the ships
accordingly to be 125% of what it was before. The collision detection code is in
the same file, in the Ship::CollideCheck method.
4) Implement "wrap-around" (this means when
an object hits the edge of the playfield, it should keep going and reappear on
the other side). To do this you may want to modify the lifespan of shots, and
you may want to implement a "max speed" for the ships (perhaps by
changing the "drag" to always affect them even when they are
accelerating). Also, be aware that there are "clipping" issues:
ideally you want a ship that's in the process of wrapping around to be drawn
partially on one side, and partially on the other, which you can do by drawing
the image twice (once on each side of the screen) for each screen edge that it
is near. Don't worry if you can't get this working quite right yet, but try to
get it working as well as possible.
5) In Photons::Draw, you
will notice the constant DRAW_ADD is used. Look this constant up in the
GameX documentation, and in the
code, replace DRAW_ADD one-at-a-time with each of the other nine Image Drawing
Mode constants such as DRAW_PLAIN and DRAW_BURN, and try them all out in
separate runs of the game. Describe (in readme.txt) what visual effect each one
causes as best as you can (including DRAW_ADD). You do not need to test any of
the constants starting with DRAWOP, although these are useful too. Return the
constant to DRAW_ADD when you are done testing the drawing modes, unless you
think one of the other modes makes the photons look better.
6) Change the shots to fade out as they get older, so
they don't seem to suddenly disappear when they are removed. Hint: Use
"SetDrawShading". Also, make the shots look better by
doing some or all of the following: Make them spin quickly using
SetDrawAngle. Make certain color components fade out faster
than others. Draw each shot an extra time with a larger size (try
4x) and lower or faster-fading opacity to make for a glowing
light effect around each photon.
7) Implement collisions for shots. Make each
connecting photon disappear, and also make it knock back the ship a little if
you can. Make sure each ship is immune to its own
photons (you might want to wait until part of question #10 below is done before doing this last part).
8) Change the blue ship (but not the red ship) to
play its photon firing sound at a slightly lower frequency/pitch, such as 75%
of normal. See the GameX documentation about playing
sounds for information on how to do this. Also, make the photon sound
"pan" (for both ships) depending on the x location of the ship that
fired it (make sure it fades smoothly from left to middle to right).
9) Comment out the line of code that draws the
background, run the game and describe what happens, then un-comment the
background-drawing code to re-enable it. Change the appearance of the
background (hopefully to something you think looks better or interesting) by
running one or several of GameX's image filters on it
when it is first loaded. See section 10 of the
GameX documentation for details of how to do this.
Also, remove the translation offsets given to DrawTiled
and call GameX.SetDrawAngle beforehand with a
changing angle value to make the background spin, but *please* make sure it
spins very slowly, such as 1/100th of a degree every game loop. You can use
GameX.GetGlobalCounter to get a value that increases
continuously, which you can modify to be the changing rotation angle. A common
problem you may encounter is that it spins jerkily or doesn't seem to spin
continuously, in which case you probably forgot to cast to float or double
before dividing (and so were unintentionally performing integer division).
Finally, make the background drawn shaded with a high degree of transparency
(i.e. low alpha such as 32 or 64) and describe what happens and why you think
it's happening (it's related to the very first thing you did
for this question #9). Leave the background this way, with all of these changes
in effect at once. This will probably change the way your photons look,
such as by obliterating most visible details inside them,
in which case go back and change how photons are drawn so that they look more like they
did before the background change. (Reducing their brightness may be enough.)
10) Change the red ship (but not the blue ship) to
fire lasers instead of photons. Do this by giving the Photon
struct an extra variable called "type", and
changing AddPhoton to take in and assign the photon
type. The red ship should then be made to add photons of a different
"type" than the blue ship does. Once this is done, change the
Photons::Draw function to draw the photons of the blue
ship's type the same way as before, but to draw the photons of the red ship's
type in a different way so they look like laser beams. To draw the
"lasers", use the GameX.DrawLine function
and any color or drawing mode you think looks best. Note that, since
DrawLine takes two sets of (x,y) coordinates, you will need to decide on where the
laser beam starts and where it ends. You could change the photons to keep track
of some previous positions, but an easier way in this case is to subtract the
photon's velocity from it's current position to come
up with a second point's coordinates, and draw the line from that point to the
current position. If the laser beam is too short, multiply the velocity when
you subtract it by a higher number until the beam looks adequately long. If the
laser beam is too thin, call GameX.SetDrawScale(width_in_pixels) before the call
to DrawLine. If you want to try making the laser beams look prettier, you may use
DrawLineImage (with the photon image) instead of DrawLine, but you must pass in
"true" as the extra/optional parameter of DrawLineImage so that it still looks
line-like.
11) Change a ship's controls so that moving the mouse
leftward turns the ship counter-clockwise, moving the mouse right turns the ship
clockwise, moving the mouse up accelerates forward, moving the mouse down
accelerates backward, and left-click fires the photons. Make sure the ship does
not respond hypersensitively to mouse movement, but
moving the mouse quickly should cause more of a reaction than moving it slowly.
Also make sure that you can hold down the mouse button for rapid-fire as it was
before. As much as possible, make the mouse control "feel natural" to use, which can be
achieved with some tweaking (changes elsewhere to turning speed etc. may be necessary).
See the GameX documentation for information
about getting mouse input with GameX.
This might seem like a lot of tasks, but hopefully you will find all of them
reasonably simple and straightforward. To turn in the lab, hand in (using CMS: http://cms.csuglab.cornell.edu) your code
which completes all eleven tasks at once, along with a readme
that answers questions and describes anything directly asked in the above tasks,
and also describes how you handled each task and where in the code it was
handled. You should submit the following files:
shipdemox-main.cpp
shipdemox-photons.cpp
shipdemox-ship.cpp
shipdemox-photons.hpp
shipdemox-ship.hpp
readme.txt
and if for some reason you need to add a new file,
shipdemox-extras.cpp
shipdemox-extras.hpp
For this first lab, you may NOT
add or change (or submit) any graphics files or sound files, however.
(If you work in a pair, hand in a combined lab as a group.)
This lab project is due Wednesday, September 8th at 12:01pm.