Archive

Monthly Archives: March 2011

I spent the last two days wallowing in sorrow, trying to get my computer to run again.

Two days ago, I decided to install ArchLinux. I was attracted by its minimalist design. All I wanted was a terminal, so that I could build it up however I liked. Plus, it’d be useful to be able to use Linux natively. Currently, I use Putty to connect to the CS Linux machines to do homework. Its fine and all, but I can’t do as much as I like that way. For example, its nigh impossible to work on GUI applications this way. Plus, Arch is what the cool kids use.

The Arch installation process is a far cry from Ubuntu’s. It’s not pretty and involves a lot of low-level wrangling with partitions and configuration files. First off, I had to search for an hour online to find the correct kernel flags that allowed me to even start the installation process. Setting up the clock was the only simple part about the process. Then came the partition selection step. Since I didn’t know the Linux names for the partitions on my system, I had to use the  Ubuntu LiveCD’s gparted utility to find out. I also used it to create a partition for the Linux install. It was much easier using the LiveCD’s  lovely colorful interface than having to endure the process of doing it on the command line.

Then, I had to configure the mount points. I had never heard of a mount point in my life. At this point, I probably should have called it quits, but I kept going. I did as Lifehacker’s guide suggested and set the swap and root partitions. Choosing and installing the packages was a breeze after I discovered how to select the ones I wanted. Then, I had to go through a bunch of config files and make minor changes. No biggie.

The final part was installing Grub, which lets you choose which OS to boot into, and that failed spectacularly. By spectacular, I mean without any cause and an inexplicable error message. I tried for another hour or two to find the golden solution on the internet to no avail. Arch had conquered me for I was not worthy.

At this point, I could still boot into Windows as if Arch didn’t even exist on the drive. Since GRUB wasn’t installed, it went straight into booting Windows.

Since I was defeated by Arch, I decided to install Ubuntu. I wanted to run some Linux distro. Besides, installing Ubuntu would partially redeem me, I thought. The installation process was a million times simpler than Arch’s for sure. It took care of most of the details for me.

But alas, I fire up the system and I can’t get into Windows! It gave me a blue screen. Isn’t it ironic that the supposedly beginner-friendly distro was the one to mangle my computer? Ubuntu, on the other hand ran fine and dandy. I proceeded to spent the next day feeling depressed at the situation.

The first thing that came to my mind was recovering it with the Windows 7 installation disk. I go through the maneuvers and try to do startup repair, but it doesn’t recognize that I have Windows installed on the disk. What? Ludicrous! Unfortunate…

I used Ubuntu to mount my Windows partition and was glad to see that everything was there. If worse came to worse, I could just backup my files and nuke the drive, or so I thought. It became obvious that it was a problem with booting up. All of the Windows files were fine as they hadn’t been modified in any way. The bootup information was messed up. Somehow.

I just cared about making Windows boot up again at this point. Linux was nice to have but definitely not as essential as Windows. So, I proceeded to recreate the boot information for Windows via the command prompt on the recovery console. Or tried to, at least. That process pretty gave me a bunch of error messages. But, hey! It made me lose access to Ubuntu and fated me to bluescreen when loading Windows over and over. What a productive effort!

Then, I backed up my files, realizing that repairing the master boot record was probably not going to happen. I deleted the Windows partition and tried to install Windows using the CD. But it wouldn’t recognize my partitions! Essentially, I couldn’t tell it where to install! I tried for a while to find drivers to get it to recognize, but to no avail. Then, I tried to change the BIOS settings to change the hard drive controllers. Nope. The setting couldn’t be found at all!

Let me take a second to explain my disk’s structure at this point. The first partition was about 100 kb and gparted didn’t recognize it. I have and never will have any clue about why it was there. Next, comes the 200 mb boot partition that Windows made for some reason. Then, the 450 gb main Windows partition. The 25 gb Ubuntu partition and the 1 gb swap came after.

So there was a bunch of weirdness going on with the drive. I read on some Windows forum that in an attempt to make the disk play nice with the installer, wiping the entire thing with zeroes would be a good idea. I decided to try the next best thing; I deleted all of the partitions and created one NTFS gigantor. I was ecstatic when the installer recognized the partition. Can’t argue with Gigantor staring you in the face, eh Windows?

I proceeded to install Windows 7. I was so fearful that it wouldn’t work after everything else going wrong, but it worked perfectly. Then, I realized that I installed the 32-bit version, so I had to redo the install again. I spent more than five hours after that loading my files back and installing the software I needed. The only good thing that came out of this debacle was that all of the tens of gigabytes of random stuff I had accumulated over the past eight months. On the other hand, I spent one day messing up my computer, another day fixing it, and a third day getting it back to how it used to be. Three days in spring break gone down the drain.

What lessons did you learn, children? Don’t mess with a computer that you can’t afford to lose. Install Arch only if you know what you’re doing. Even Ubuntu can mess up your computer. Whose fault is it for not being careful? Mine, all mine. I admit that as a I shed a torrent of tears.

This post is part two of a multipart series journaling the game writing process. You can find the first post here.

The engine of a game consists of all of the components that help you create the game. It includes the graphics renderer, physics, sound, networking, and artificial intelligence, among others. For the simple game that I’m writing, the engine will be correspondingly simple. The key point is that all of the subsystems should be as separated as possible. Since Java is object-oriented, this means separating the components into classes. This facilitates easy modification in the future. I have all of the code in an Eclipse project here, and an executable Jar of the result here. Referencing the code as you read this post will make a lot more sense. I hope you will be able to bring your knowledge of Java to making a game after reading this post. It’s quite long, but I think I’ve put in a ton of detail that might be valuable to somebody out there.

The entry point of the game is the main class named Glade. I usually name my main classes Main, but that’s horrible choice: it’s not descriptive and I already have 10 of them in my workspace. This time, I named it Glade, the code name I have for this project. This class creates the Renderer, the Controller, the Stage, the Display, and the Player. These objects are accessible as static fields of the Glade class. This way, they are easily accessible to every object in the game. I could have passed them in through constructors, but that would have been cumbersome and without any benefit.

Then, Glade starts a timer that fires at a frequency determined by the frame rate. At first, I set the frame rate to be 25 FPS, but that was very sluggish, so I pumped it up to the standard 60 FPS. There is no guarantee that the game will hit his frame rate. It only acts as a maximum. If you don’t cap the frame rate, your game is going to run extremely fast on fast computers, which will make it unplayable. I didn’t do this for my first game that I made several years ago on old school computers. On my modern laptop, it is so fast that I my character dies within seconds.

The Renderer class is responsible for the graphics component of the engine. It extends JFrame which has the paint method. The method gives us a Graphics object that we can draw to in order to display things on the screen. This paint method is called each time the timer hits. The Renderer puts the window into full screen mode if it’s available. Otherwise, it just uses a regular window. The full screen mode is significantly faster because it can bypass the windowing system and draw directly to the screen. Plus, it looks much nicer; people usually don’t want to play games in windowed mode. Renderer implements a double-buffering strategy. If you directly draw to the screen, it is slower and gives you weird flickering. So, we first do all of our drawing onto an off-screen buffer and then draw it to the screen after we’re done.

All of the objects implementing the Drawable interface are stored in a HashSet in Renderer. Drawable requires the object to implement a draw method. Each object is passed in the graphics object to draw to. This way, every game object is responsible for drawing itself. The Renderer clears the screen by drawing the background onto the buffer, and then iterates through all of the Drawable objects, calling their draw methods. Every Drawable gets drawn each time paint is called. However, you are not allowed to add to or remove from a HashSet that you are iterating over. This is because the iterator won’t be able to keep track of where it is and where it’s supposed to go next if we randomly change the HashSet that we are iterating over. But, we need to be able to add and remove Drawables, because enemies and bullets need to be removed all the time. To facilitate this, two other HashSets are maintained. One contains the Drawables that need to be added to the main HashSet, and the other contains the Drawables the need to be removed. So, adding a Drawable to the Renderer doesn’t mean adding to the main HashSet, but adding to the add HashSet. This way, we never add or remove while iterating. All of the objects in the add and remove HashSets are added and removed from the HashSet storing the Drawables before iteration begins.

The Environment object is created by the Renderer. For now, all it does is draw a transparent cyan background. The transparency makes it so that objects leave a smooth shadow in their wake. Although drawing such a huge transparent rectangle each frame is somewhat expensive, it leaves a lovely effect. In the future, this class can be used for all sorts of background effects.
The Controller is responsible for the game logic. Its main job is to iterate through all of the Actables, calling their act methods, when the timer hits. (So, every object’s act and draw methods are called each frame.) The act method is where the main logic for each object is placed. Since it is called each frame, anything that must be done as the game is running must be placed there. This includes moving the object around, checking for collisions, dealing with input, among many other functions. Eventually, the controller will also deal with bigger picture aspects such as level progression, creating enemies, spawning power-ups, managing high scores and the like.

The Stage is what holds and manages the Actables. I usually include this functionality in Controller, but I decided to split it off this time. The Stage is also responsible for facilitating collision detection. Bullets can ask the Stage if its colliding with an enemy. If they are, they would do damage to the enemies and be destroyed. For now, the Stage will naively just run through all of the enemies, asking each one if they collide with the bullet in question. In the future, it can be rewritten to be much more efficient if performance is an issue.

The Display object stores stats like the score and remaining lives and displays them on the screen. It can be extended to create a snazzy display in the future.

The Player class processes keyboard and mouse inputs to manipulate the state of the player’s little ship. In addition to implementing Actable and Drawable, it also implements KeyListener, MouseListener, and MouseMotionListener. Whenever the mouse buttons or the movement keys are pressed, the corresponding boolean variables are flipped. Whenever the mouse is moved, the coordinates are stored. These variables are tested in the Player’s act method and the corresponding action is taken. If the mouse is pressed, a Photon is created at the location of the Player in the direction of the mouse cursor. In the future, the Player will also be responsible for checking if it is colliding with an enemy and reducing the health accordingly. It draws a square at the location specified by its x and y coordinates in its draw method.

A Photon is a subclass of the Bullet class which encompasses all of the projectile weapons the Player has at his disposal. Bullet is given its origin and target at construction and some trig calculates its x and y velocities. It then updates its location each step and kills itself if it is outside the boundaries of the stage. For now, all Bullets follow the same trajectory. I can move that functionality to the subclasses if need be. All sorts of funky bullets can be created this way.

Play with the code. Try changing the colors or the constants. Create new bullet types. That’s how I learned to program games. I took an existing one and changed the graphics and added bullets and power-ups. Leave me any questions or comments!

Geometry Wars

It’s finally Spring Break and since I haven’t written any significant non-school programs in a while, I’ve decided to write a game. My first significant program was an abstract 2d shooter that I wrote in the first semester of my sophomore year of high school. Needless to say, I wasn’t much of a programmer then and my code was horrible and inefficient. But, it was really cool to be able to write a game and watch other people have fun playing it. I’ll be writing a similar game and trust me, it’ll be leaps and bounds above my first attempt years ago. So, I thought I might as well document the process of designing and coding the game. By Friday, I should have a fun little playable game in the vein of Geometry Wars and Everyday Shooter.

I’ve had ideas to incorporate into this game for months now. But, I still haven’t chosen which subset of those game mechanics and features to incorporate. I can’t just put everything in there. They need to consistent. I’m going to sidestep the issue for now. Initially, I’ll focus on the engine and the core game mechanics. This involves setting up the graphics, game controls, and the basic game environment. In a day or two, you should be able to move the ship around and shoot and destroy enemies. All of the other ideas build on top of this core.

Planning is very important to building a game. You want to have a base that can give you a lot of flexibility in the future. I thought of a number of optimizations I can put in the game engine, but I won’t be adding them in the first version. I might not even need to if the game runs as well as I want it to. However, I’ll make sure to build the game so that it won’t be much trouble to add them in later. For example, I’ll initially implement a particle system class that is simple, but inefficient. When I get around to making it more efficient, I can just plug in a different class. I shouldn’t need to change anything else if I designed its interface well. I think I have a pretty good idea of what components I need to create to have a game running. This time around, I’ll split functionality a lot more. I don’t want huge monolithic classes like I had in previous projects.

A key component of planning is choosing the tools to use. I considered using PyGame, but I didn’t want to deal with making sure my audience had Python on their computers. Even converting the game to an executable via Py2exe would have limited my audience to Windows users. Plus, I’ve never used PyGame. Yes, I should be trying new things, but PyGame’s disadvantages are great. I considered using Processing, but I felt like I didn’t need it. It’s meant for people to get started really quickly without having to know much of the technical detail. I’ve coded simple engines in the past and even have the code for all of those projects, so I though Processing would hamper me more than help me. I considered using a Processing plugin for Android, but it wasn’t completely mature, so I didn’t bother. So, I’ll be sticking to what I know: Java. It allows me to reach any platform with minimal effort. I’ll just be using the standard libraries. Sure, I can use JOGL or other libraries, but they are just not needed for this game. My IDE will, of course, be Eclipse.

So, there: I’ll be updating this blog every day or so. The next post should be about how the engine is set up and the basic design decisions I had to make in creating it.

Follow

Get every new post delivered to your Inbox.