October 31, 2010

ISSUE 1: The one hour 3D world

Panda3d Logo

All of the Issues in Volume 1 rely on something called Panda3D.  Panda3D is a 3D game engine provided completely free by the Carnegie Mellon Entertainment Technology Center.  A game engine is a Software Development Kit (SDK) that takes the pain out of the common tasks involved in game development.  For example, Panda3D provides libraries for graphics, physics, lighting, audio, keyboard/mouse/other input and so on.  You really would not want to find yourself having to write all of these routines yourself (you’d never finish a single game on your own!).  There are other game engines out there but we really like Panda3D due it’s ability to run on Windows, Linux and Mac and its support for Python:

Once you have a working game engine, you need a means to tell it what to do.  You need a programming language.  Like other languages, programming languages have their own vocabulary, syntax, semantics and so on.  To communicate with a person, you might choose English.  Though there are, of course, other options and they vary wildly (Russian and Chinese, for example, even have a completely different alphabet).  There are various merits to different languages and, likewise, pitfalls and problems (or ‘limitations’).

Panda3D supports game development using either the C++ or Python programming languages.  We will be using the Python language. In later issues we will discuss and compare other programming languages but for now trust us, Python is a good choice for getting started quickly.  Down the line, you will also learn about programming language versions.  Yes, there are different versions of Python.  Do not worry about this for now as we’ll guide you through a setup that works with Panda3D but if you’re pondering what difference a ‘version’ could make consider the difference between Old English and the English we use today!

Download and install Panda3D

Head over to http://www.panda3d.org/download/ and download the latest version of Panda3D for your operating system.

If you are using Microsoft Windows, there is a “one-step” installer that will install Panda3D and Python in one shot.  Nice and quick!

For Linux and Mac OS X users, again, you should find packages are available for your distribution.  If not, you’re in the land of compiling the source manually and that’s a bit beyond the scope of this issue (though we will likely hit on meddling in the Panda3D source code down the line).

The Panda3D download for Linux does not include the Python programming language but is usually matched to work with the default version of Python available in your package manager (add/remove software).

If you are using Apple Mac OS X there is, again, a one-step installer though, like the Linux version, it does not include the Python programming language.  It also requires you to install the NVIDIA Cg Toolkit. The necessary links are on the Panda3D download page for Mac OS X.

If you run into any problems at all take a little time to read through the Manual on the Panda3D website.  Panda3D is incredibly well documented, you’ll be visiting the site often as you progress to dip in and out of both the manual and SDK reference guide.

Let’s create a world (the easy way!)

As the old saying goes, there’s more than one way to skin a cat (never did understand why you would want to skin a cat, but there you go).  In the interests of getting going quickly, we’re going to use a really simple technique to create your new world.  We are going to create our 3D world from 2 images.  That’s it, 2 regular image files!

  • Image 1 is what we call a height map.  A height map is a grey scale image, no colour.  It represents an overhead view of your landscape (like a map!).  The lighter areas in the image represent high terrain (peaks, mountains).  The darker areas are lower.  It’s that simple.  Thus, any part of the image that is pure white will be ‘as high as is possible’ while anything in black is ‘as low as possible’.
  • Image 2 is our colour map (or ‘texture’).  It is dropped on to our height map like a cloth, colouring the terrain to our design.
Height map plus Colour map yields 3D map

You could create both images in your favourite image editor but we’re a little slicker than that here.  We’re going to use another piece of free software to design our world.

Let’s make it even easier!

As noted, you can make your height/colour maps in almost any image editor.  But, wouldn’t it be nice to have a ‘world designer’ to assist?  There is a free application called L3DT.  Natively, the program only runs on Microsoft Windows.  However, if you are a Linux user it will run admirably using Wine (available in your package manager) while Mac OS X users should Google for ‘mac crossover’ to achieve the same.

L3DT is nice and easy to use.  Essentially, the steps are:

  1. Download and install L3DT from http://www.bundysoft.com/L3DT/
  2. Load L3DT, hit File -> New Project then select ‘Designable Map’.
  3. The inbuilt design wizard will guide you through the rest of the process, the default options are fine (just hit next!) for all but the “Calculation Queue” screen, where you should enable Attributes, Height field and Texture map.
  4. Once finished, select the height map from the available tabs and hit File -> Export map Layer. Export theheight map as an image file (PNG).
  5. Repeat this step again, this time by selecting the colour (texture) map tab. Again, export as a PNG.

L3DT offers a wealth of features including editing your map in full 3D.  We recommend experimenting to achieve the design you want, for your game.

Your first Python program!

Ok, we’re almost there!  We have a 3D world, now we need to pull it in to our game.  Open up a text editor – whichever text editor you like (e.g., Notepad on Windows, GEdit on Linux etc.) and type in the code below exactly as you see it (the colours are just a visual aid, you don’t need to worry about them!).  The indentation is important – in Python, ‘white space’ (spaces, tabs, any non-printing character) means something.  If you do not properly layout the code it will not work (the number of spaces is up to you – use tab if you prefer, but keep the levels of indentation/alignment as per below!).

from direct.showbase.ShowBase import ShowBase   # the core of Panda3D
from panda3d.core import GeoMipTerrain          # Panda3D terrain library

class ShooterGame(ShowBase):                    # our 'class' ('object' recipe)
    def __init__(self):                         # initialise object
        ShowBase.__init__(self)                 # initialise panda3d
        terrain = GeoMipTerrain("worldTerrain") # create a terrain
        terrain.setHeightfield("heightmap.png") # set the height map
        terrain.setColorMap("texturemap.png")   # set the colour map
        terrain.setBruteforce(True)             # level of detail
        root = terrain.getRoot()                # capture root
        root.reparentTo(render)                 # render from root
        root.setSz(60)                          # maximum height
        terrain.generate()                      # generate terrain

my_shooter_game = ShooterGame()                 # our object 'instance'
my_shooter_game.run()          

SUGGESTION: Indent your code using TABS or SPACES but be consistent, just use one or the other to avoid ‘indentation errors’.

Now, save the file somewhere as ‘mygame.py’.  The “.py” extension is what indicates the file to be a Python Script (program).  Do not worry too much about what all of this means for now.  We have added some comments to the code above to indicate what is happening but we won’t dissect in detail until the next issue.  While we’re here though, notice that anything following the hash ( ‘#’ ) symbol in Python is considered to be a ‘comment’.  That is – not code for Python to actually execute, just something in the file for any reader/programmer to see.  Adding comments to your code is incredibly good practise – we cannot stress that enough!  Good comments lead to code that is readable by yourself and your peers.

You also need to copy both of the images you created to the same directory as the Python file. If necessary, update the lines where you find ‘setHeightField’ and ‘setColorMap’ to point to your images, whatever you named them.

TOP TIP: For reasons only they know, Microsoft ship Windows with a default setting to ‘hide’ file extensions.  When you’re developing software, editing images/Python files (etc.) it really does not help (in fact, it can cause all manner of confusion).  We recommend Windows users enable file extensions, here’s the procedure straight from the horse’s mouth:  Show or Hide File Extensions

Running your program

Finally, we are ready to run the program!  For now, we will be running the program from a Command Prompt (terminal).  Open up a command prompt and navigate to the same directory as your Python file:

On Windows, you can do this the ‘hard way’ if you know how to work the command prompt.  If the idea of a prompt is entirely new to you – here’s a neat trick that works on Vista/Windows 7:  using Windows Explorer (note – Windows Explorer, not Internet Explorer!) navigate to the directory one-higher than where you saved your file.  Single click the directory to select it.  Hold down the shift key and press the right mouse button.  On the menu that appears, select “Open command Window here”.

Linux and Mac OS X users are likely already somewhat familiar with the idea of a command prompt (or ‘terminal’ as it is called there), it’s a bit more ‘generally important’ to the operating system than it is in Microsoft Windows.  That said, there is a similar ‘open terminal here’ for Mac users, see:  Open Command Window here on a Mac and also for Linux users (in this case, using Ubuntu):  Open a Command Window here on Linux.

If none of the above work but you know where you saved your Python file, you can just open up a command prompt and navigate manually (the so called ‘hard way’, though not that hard really!).

Windows:    cd "c:\some directory\some other directory\my python director"
Linux/Mac:  cd "/home/user/some-directory/my-python directory"

From your command prompt, to run the game, use the command below (side note – “ppython” is simply a Panda3D wrapper to the regular “python”, forcing a suitable Python version among other things):

Windows/Mac:  ppython mygame.py
Linux:        python mygame.py

Hit enter and, after a short while, you should see a screen appear.  Some time later, you should see a small piece of your terrain (don’t worry if not, we’ll move the camera next!) on a grey background.

Your ‘in-game’ controls

Until we reach the stage of adding in our game controls (coming in a future issue, of course!) we strike it lucky because Panda3D includes some ‘default camera controls’ using the mouse if nothing else has been setup.  So, using your mouse:

  • Hold down the left mouse button and you should find you can move the camera left/right and up/down.
  • Hold down the right mouse button and you will be able to zoom in/out.
  • Hold down both mouse buttons and you will be able to rotate the camera.

APPLE MAC users may not have a second mouse button.  To achieve ‘right-click’ hold down the CTRL key and then mouse click.  If you have a multi-touch pad use two fingers to achieve the same.

Wrap up and Summary

So far, you have learnt how to create a virtual world and how to display that using a Python program.  Not a bad start at all!  You may have noticed that the program you just wrote takes a while to load.  Don’t worry about that for now.  In short, we’re ‘generating’ the terrain every time we load the program and this takes a while.  We will, very soon, be showing you how to ‘save out’ that terrain as a Panda3D model to load whenever you need in much greater speed.  Meanwhile, if you ‘comment out’ (prefix with a ‘#’ symbol) the line where setBruteForce is set – you will notice it loads much faster but the level of detail (LOD) on your terrain is not as great.

Join us in the next issue where our aim will be to get your player (main character) on to the scene.  We have opted for an aircraft but you can choose whatever you like!  We will begin by reviewing the code above in greater detail so you understand a bit more about what is happening under the hood.

Oh, before we go, you also picked up a bit of knowledge about both UV Mapping and Mip Mapping! Google either and what you find you should be able to relate to what you just did!  We also snook in some terminology early – SDK, ‘libraries’, ‘routines’, and a few other bits.  We’ll teach you without you even knowing it!

Goto Issue 2 >>>