Writing a Video Game in Java (Part 2) – The Engine

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!

About these ads
12 comments
  1. Anonymous said:

    Thanks for putting up the code! Very helpful :D

    I do have a question, though. Since the Drawables are in a HashSet, and Sets won’t allow duplicates, doesn’t that mean that you wouldn’t be able to have multiple Actables of the same type draw on screen at the same time? Can each Drawable update more than one image?

    Hopefully that question made sense…

    • Sets don’t allow duplicate objects, not duplicate types. You can have objects of type Enemy if they are distinct objects – they were invoked using two new objects. (I’m using the default hashCode function, which computes a hash based on the object’s address in memory.) Each of their act and draw methods are called. What they want to do with those methods when they are called is up to them. Each Drawable is passed in the main graphics object. You can draw to another buffer if you want to. It might be recommended, actually, if you want to make it faster.

      I decided to combine Actable and Drawable in the next iteration. It just adds unnecessary complexity to have both. Very few game objects are just one and not the other, anyway.

      I’m glad someone is using the code! Keep in touch and tell me what you make!

      • Anonymous said:

        Ah, that makes sense. Thanks for clearing that up for me.

        I’ll see what I can make with the code, though I’m not expecting that it’ll be anything too impressive. Looking forward to playing around with it though.

  2. Caleb said:

    Not sure if your still on here, but hey. Im an aspiring college student hoping to learn a bit more about this. Any new tips You’ve gathered in the past year?

    • Prad said:

      Hey Caleb! I am indeed still here. I haven’t updated the blog in a while in anticipation of moving it off WordPress.com.

      Java is an object-oriented language that encourages code reuse through inheritance. For example, you can have a general Bullet class and specific bullet types (torpedo, photon, etc). This is fine if the classes you have are clearly extensions of their superclasses. If torpedo is just a bullet with a different image, damage, and speed, this is fine. But what if we wanted to add something that is similar, but not quite like a bullet? How about something like a laser? A laser does damage, but doesn’t move like bullets do or have a concept of speed (since its instantaneous.) Let’s say you would implement this by checking points along the laser line for intersection with enemies.

      To do this, would you write a subclass of Bullet? A laser shares some functionality with a Bullet, but isn’t quite a clear specialization. So then would you create it at the same level as Bullet? Perhaps, but then you’d have to copy a bunch of the code.

      The general problem is that it’s hard to anticipate what sort of functionality you would like to have in the end. It’s hard to see what kind of superclasses you should create, that share the maximum amount of code.

      In response to this problem, people have created what are called component-based engines. Essentially, you create objects out of components. You can have a component that draws and animates the object, another that keeps track of where it is and does collision detection, another that applies physics, etc. You’re creating behavior in classes by composition vs inheritance. I find that this model is pretty well suited for games where you’re often adding unplanned-for features and content.

      I haven’t written a game like this using components, but it’s on the list of things I’d like to do in the holidays.

      See: http://stackoverflow.com/questions/1901251/component-based-game-engine-design for more info.

      So there’s some of things I’ve been thinking about recently when it comes to game engines. Basically, I’m saying that inheritance can be inflexible and cumbersome sometimes.

  3. test said:

    Hey, I think your site might be having browser compatibility issues.
    When I look at your website in Chrome, it looks fine but when opening in Internet Explorer, it has
    some overlapping. I just wanted to give you a quick heads up!
    Other then that, excellent blog!

  4. Micah said:

    I cannot access Mediafire to get your code. I am in Java programming as a freshman in college. For my final project, a buddy of mine and I are going to write a basic game. I really want to see your code!!!

    Great blog by the way. Really, I’m not one to read blogs, but your a good writer, especially with programming being something so difficult to explain in simple terms. Well done.

    Would love an email ASAP

    • H ey Micah! Not quite sure why you can’t access the Mediafire link, because it works for me.

      You can download the zip alternatively here: https://dl.dropbox.com/u/126505/GladeSource1.zip

      Let me know how your game turns out and feel free to email me with more questions!

      -Prad

      Prad Nelluru

      On Wed, Mar 20, 2013 at 8:10 PM, Prad Nelluru

  5. Telefonsex regt nicht ausschließlich die Fantasie an, sondern lädt viele ebenfalls zum Abspritzen ein.

    Wir benötigen ebenfalls nicht mehr auf unauffällig
    verpackte Päckchen warten. Beim Telefonerotik
    musst du kein Blatt vor den Mund nehmen, weil da ist wirklich alles möglich,
    völlig ohne Tabus.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: