Ever looked at a Wii or Xbox game and thought 'I wish I could make a game that my kids would want to play'. Well, this instructable will show you how. We'll begin with the game concept before moving on to game design, hardware and firmware development. Then we'll cover the software development and finally a clip of the final product. So jump in and make something fun!
Step 1: Step 1. What's Our Concept? Part A
My son Ben was about to turn 5 years old, and interested in anything space. He REALLY wanted to be an astronaut. So my wife and I decided that we'd have an astronaut birthday party. We modified fed-ex boxes to become astronaut backpacks, complete with 2 liter bottle air tanks and utility belts, built a rocketship tent and decorated the backyard with stars and planets overhead. I even strung a cable zipline up for their very own space ride.
But we wanted something more.
As a result, I decided to create a virtual space pilot game for Ben. The only guiding principles I wanted to stand by are:
1. It had to be a cooperative game- meaning 2 players had to play together.
2. It had to be fun and interesting
3. It had to be geared towards 5 year olds
4. It had to play quick, so we could rotate through kids pretty rapidly at a birthday party.
Step 2: Step 2. What's Our Concept? Part B
So I came up with the idea of a spaceship that required both a gunner and a pilot to operate. The game would take place in our own solar system (since Ben was studying the solar system, this would be familiar turf). I was afraid the gunner would be having all the fun, so I made sure the pilot had a limited number of guided missiles at his disposal. In the best of cases, this would cause the gunner and the pilot to work even more closely together. With this in mind, I created some rules for the concept:
1. You are in a spaceship, defending your solar system from invading alien spacecraft
2. While your field of view is 3D, your play area is 2 dimensional, roughly in line with the planets in the solar system (I felt that 3D piloting would just be too hard for a 5 year old pilot)
3. The game will be levelled. Each level will mean that an additional alien spacecraft spawns, and it will be faster (so will their shots)
4. When the spacecraft spawn, it will be in a random place, at a minimum distance from where you are.
5. You start with 3 shields. Each strike on your ship, either from an alien spacecraft or one of their shots, will knock off a shield. if you have no shields, a strike ends the game.
6. The only object you can run into is the sun. You'll get verbal warnings before this happens, but if it does, the game is over no matter how many shields you have.
That was pretty much all I started out with, figuring time was short and everything else would become obvious as I developed it. Turns out, I was able to stick to this pretty closely. Read on to find out how!
Step 3: The Spaceship
I can't say this is the first thing that I developed, but to the kids, it was the most important. I called Ben in as my creative consultant. This is what we came up with given the pile of scrap wood in my shop. What you can't see in this picture is the step on the back that allows a 5 year old to stand at a comfortable height to properly operate the photon cannon. In front is the joystick operated by the pilot. The joystick allows turning left and right as well as forward and backward movement. The trigger fires guided missiles if you still have any, but I'll get into more detail on those when we cover the software development.
Step 4: The Hardware Part 1: the Laser
Figuring out the joystick is no mystery, it's just a cheap USB joystick plugged into my home theatre PC with a USB extension cord (it was a 15' cord and has an integrated USB hub at the end functioning as a repeater). The Photon cannon is fired by a simple button on the back (you can hold it down to fire at a rate of 5 shots / second) and point it at the screen where you see alien spaceships! But how do we pick up the turret mounted photon cannon? Lasers. I decided to use an infrared laser. If you choose to go this way, please remember to keep the energy of your laser well below eye safe levels, as defined by the FDA. This is kind of strange, but an invisible laser is considered eye safe at 10% of the dose at which the average person stands a 50% chance of incurring any damage at all. I used an arduino to change the button trigger to a 5Hz laser pulse, limited to 1mS on. I also limited the output power of my laser with the following circuit (click the attached image under this one). This is to guarantee that even in the event of a failure, the laser can't get stuck in the ON position. You want this because, unlike a red laser, an infrared laser is invisible and you can't tell you're supposed to blink if one shines in your eye. The laser that I'm using is a 5mW IR laser module ordered straight out of digikey.
This puts us at .001S exposure time if you stick your eye on the front of the laser (it grows in area from the front of the laser, so it lessens in intensity), and the time increases a lot as the beam diverges towards the screen (where the area is about .8cm^2 and the power number you use is .006). Note this number is for class 1 MPE, which means it is 10% of the dose at which you have a 50% chance of incurring damage.
If this bothers you, no problem. Stick with a visible laser! The hardware I have outlined here will work fine with any color laser, you'll just have to set the sensor threshold higher to block room light and whatever color your projector is throwing.
Step 5: The Hardware Part II: Locating the Laser
Now comes the fun part. How in the world are we going to figure out where we just put a 1mS 5mW eye safe laser blink on a 9' diagonal screen?
The quick answer is: A camera.
Turns out, as long as there's not too much extra infrared light in your room, you just have to put a nice IR pass filter over your average everyday cheap CCD camera, and you've got a detection device! This picture below shows the camera that I used, mounted next to my projector.
Next, I'll detail the hardware that I designed to translate what the camera is telling us in a way that the PC can understand.
Step 6: The Hardware Part III: an Arduino-based Translator
This circuit below is something I came up with to locate the laser. You'll notice that the circuit below looks a LOT like a standard arduino. This is because when I breadboarded the whole thing up, an arduino is exactly what I used. When I eventually crafted a custom PCB, I actually burned the arduino bootloader onto it. Turns out it was easy and convenient to do it that way. One note- pins 2 and 3 on the FTDI-232 chip are transposed, and I had to cut and jump these on the final board.
Here's how it works. composite TV signals are all timing based, and interlaced. I used an LM1881 NTSC decoder to tell the AVR if we were on an odd or even line, as well as when the Hsync and Vsync occurred. For those of you not electronically inclined, I used the LM1881 to give me an index of where we were getting picture information from. The laser is filtered by U1, which I'm just comparing to the voltage at the wiper of R3 to pick up the first pixel on screen bright enough to pass my manual threshold. Hopefully, this is our laser. The AVR picks this up as an interrupt, and remembers the time from the last reported Hsync. We've been counting vertical lines since the Vsync, so now we have an exact position (well, +/- quarter inch). Interested in the source? Here it is:
The end product of this board is to register as a serial port at 115200, and crank out 2 bytes (X and Y) every time it sees a pixel bright enough to be considered a laser. You set the threshold with R3.
Other pictures on this step illustrate NTSC composite signal information, and a picture of the final PCB.
Step 7: The Software Part I: Choosing a 3D Engine
The only 3D programming experience I had previously was writing mods for the Quake series of games, but I didn't feel as if that engine would be able to adequately perform a convincing outer space simulation.
So I started downloading, compiling, and looking into some of the bigger free 3D engines available like Ogre, Crystal Space, and Irrlicht. My home theater PC is linux based (Mythbuntu) so I needed to be able to compile for that.
After a bit of research and tinkering, I chose Irrlicht. Mostly because it seemed to have a quicker learning curve on getting started, and the folks on the Irrlicht forums are absolutely great at handling questions from newbies and experienced programmers alike.
Although I have written various assembly and C (although mostly embedded stuff) for years, this was to be my first adventure in C++. What's the best way to learn a new language? Try something in it!
I grabbed one of the simple examples, tore out the old code and in no time at all I had a gray world full of spheres that I could create on the fly, and navigate around (and through) them using the mouse and keyboard.
Step 8: The Software Part II: Try Something!
Now I had all the ingredients to try and make something. I knew how to create a moveable camera, a sphere, and a skybox. My son was studying the solar system in school- why not make a solar system to explore!
I started by creating the skybox in Gimp (GNU Image Manipulation Program- it's free! Try it!) using this tutorial:
Next, I turned it into a cubemapped skybox by making it seamless using this tutorial:
At first I thought I would simply hang the planets in a static location, with the sun in the middle of the universe, but it turns out that with Irrlicht, it was very easy to create the planets, and to make those planets circle the sun. It was also easy to create moons, and assign those moons to a planet so they would orbit the planet. Of course, it's way faster than real time, in that it only takes about a minute for the earth to completely orbit the sun. To see exactly how I did this, proceed to the end of this instructable and I'll provide the source code which remains in the final version of the game.
How about those planet textures? THOSE aren't mine. With permission, I used the 'Free to Download' versions of James Hastings-Trew's planet textures, and they are terrific. He even had a few moon shapes and textures (Phobos and Deimos) which I put in orbit around Mars. You can find those here. For the remainder of the moons, I fabricated imaginary textures using LunarCell by FlamingPear software. This is a plugin for Photoshop or Gimp (I'm using the gimp) that allows you to make imaginary planet and moon textures based on features and factors that you choose. There's a full version, but I limited my use to the time limited demo.
Step 9: The Art
At this point, we've already got a nice spacey background, and a set of planet and moon textures. What's left? For starters, the bullets that the alien spacecraft shoots, then the guided missiles that YOU shoot, rocket smoke, a nice hyperspace graphic that occurs when the aliens warp into on a new level, and alien spacecraft. Don't forget some explosion animations when you get hit, as well as when you blast an alien out of the sky!
The alien bullets I created from scratch in the gimp. I created a blank transparent image, then followed THIS lightning tutorial, then superimposed a few of these on top of each other. Afterwards, I superimposed a gradient flare in the center. After creating 3 or 4 of these, I had a nice graphic that I could rotate through to look like an animated electric ball. A little 'zzzt' sound from freesound.org we have a scary alien bullet.
Next was the guided missiles. I created these pretty quickly as static 3d models in Blender (picture below). Same for the alien spaceraft.
So now I needed some cool hyperspace and explosion animations. How to do this? Animated billboard. How to create it? LHfire, by LordHavoc (originally created for the darkplaces engine)
And finally, lumped in with the art, is the sound. I used drPetter's sfxr for many of the effects sounds, freesound.org for some of the more complicated ones, and I recorded my family for voiceovers and wingmen ("Captain! You're getting too close to the sun!")
Step 10: The Animation
Now that I have a solar system, I need some animation in my game. I won't have to animate the spaceship since, well, you're sitting in it, but I DO need some laser beams, smoke for the missiles, believable missile flight, a way to spin and move the attacking alien spaceships, and a way to animate their shots at you. Turns out the spinning is easy, but the rest is pretty math intensive. Even the camera itself is a bugger to move around, because you need to move the camera when you move, but you need to move the target that the camera looks at to change your angle of view. All of this is accomplished with vector based math. Note that all of the source code, art, models, and content are available from svn (link on the last page)
So how does the animation work? How about that nice hyperspace flare when alien ships are warping in? And those animated explosions and electric bullets? All of these are done with an animated billboard. You load a series of pictures (usually in a format that supports transparency) and tell the engine how fast to cycle through them. The billboard will always be oriented towards you, so it's very easy to make the object or event seem 3D instead of 2D, even if you're moving.
Step 11: Pulling It All Together
And here's a video of the game in action. Please excuse the poor video, I just pointed a flip at the screen:
The birthday was a blast! The kids automatically lined up behind the spaceship, and took turns as gunner and pilot. The game lasted an average of about 5 minutes, the kids would switch to the next position, and play would continue.
Step 12: The Source
And here's a link to the various source files. I was able to compile on both Windows and Linux up through the solar system, but then made it posix-only (I've compiled under Ubunto 9.04 - 11.10 with no problem) once I developed beyond that.
You'll need to get irrlicht here:
You'll need IrrKlang (Sound engine):
You'll need the svn source. Go where you want it to populate, and from the command line type:
svn co https://alienplanetwars.svn.sourceforge.net/svnroot/alienplanetwars alienplanetwars
You'll need the source for the hit detect board
That's it! Got any questions, fire away!