Friday, June 29, 2007

Game State Machine

Uses and Purpose:


A state machine has a context which holds the current state. Each state knows which states come next and when to transition to those states. There are many different ways of implementing a state machine. A lot of people like to use a State Manager class that knows which state to transition to and hold concurrent states, however this couples the Manager with each new state you create. This violates extensibility and abstraction principles of good design. The example state machine I have included is very extendable and abstracts the Conext (or State Manager) from the States themselves such that the Context only knows a bare minimum about the States that are running.

Design And Implementation Choices:


One of the concerns that must be addressed when creating a State Machine is whether your application is Multi-threaded or not. Since this example was created in Java your application most likely will have multiple threads. In C++ the code for a State Machine is trivial because most games are not multithreaded. Another concern is will you need substates my example code does not allow for substates but the State class can easily be sub-classed to hold substates or can also be done for concurrent states.


Code Speaks For Itself:


This example also includes Rendering Loop And Double Buffering example.

Friday, June 22, 2007

Double Buffering and Timed Rendering



A Backbuffer

First thing you need before creating a flicker free environment is to have a buffer to draw to. Basically the concept is, draw everything to an offscreen image the same size as the window you are going to be displaying it on. Once the drawing of a single frame is complete then swap or in this case draw the backbuffer onto the screen. And of course you want to do this every 16-33 milliseconds or between (30-60 fps, frames per second) So we need a backbuffer to use for drawing. You want to use a BufferedImage which has a method to get the Graphics object which is what you use to draw to any component or Image in Java.


Timer and TimerTask's

Ok! Now that we have a backbuffer we need a way of timing each frame and rendering (drawing) that frame onto the window. So we need a timer something that will execute after a specified period of milliseconds. There is a Timer class already in the Java API java.util.Timer. This class allows you to schedule TimerTask's which are simply a separate thread with a run method that you need to overload. A typical rendering loop is something like this:
// create the Timer and schedule it with the timer.
TimerTask renderTask = new TimerTask() {
   public void run() {

      // check to see if the backbuffer needs to be
      // initialized. this will help when window is resized.
      if (backbuffer == null wndResized) {
         // create a BufferedImage the size of the JFrame.
         backbuffer = new BufferedImage(getWidth(), getHeight(),
         BufferedImage.TYPE_INT_ARGB);
         wndResized = false;
      }

      // get the Graphics object from the backbuffer.
      Graphics g = backbuffer.getGraphics();

      // TODO: draw things to the screen.
      // example
      g.drawString(DoubleBuffering.DISPLAY_STRING, 100, 100);

      // now we do our page flipping to display the image on the
      // window. So we need the windows Graphics object.
      getGraphics().drawImage(backbuffer, 0, 0, null);

      // after we have drawn what we need on the screen we can clear
      // the backbuffer.
      g.clearRect(0, 0, backbuffer.getWidth(),
      backbuffer.getHeight());
   }
};
Now scheduling the TimerTask is very easy and is done like so:
// start rendering at 60 fps.
timer.schedule(renderTask, 100, 16);
That would be the guts of things you just extends this as you need and make your game.

Resizing Windows

What to do with resizing windows. Whenever a window is resized you need to recreate the backbuffer since the width and height of the image has changed. This really is not a problem if you are in fullscreen mode or you lock the windows resizable property but still in case you really need to do it here is a way to determine if the window has been resized.
// add a listener to detect when the window has been resized by the
// user.
addComponentListener(
new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
wndResized = true; // resize the backbuffer.
}
}
);

That’s about it here is the single file code snippet for you to use:

Thursday, June 21, 2007

Fullscreen & ScreenModes in Java Games

Setting up a JFrame in Fullscreen

To make a JFrame fullscreen you need to first get a valid graphics device which can be obtained from the GraphicsEnvironment object in java.awt package. Here is a quick example call,
GraphicsDevice gd =
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();

The GraphicsDevice object has a method called setFullScreenWindow it has one parameter which is a Window object and JFrame is a subclass of Window so you can pass it as an argument to the method.


Changing Display Modes

Ok so now we have a window that takes up the whole screen but what if you want to change the Screen Resolution to work best with your game. No problem!

The GraphicsDevice object has another method for doing just that. The name of the method is setDisplayMode that takes a single parameter. The parameter is a DisplayMode object. An example creation of a DisplayMode object is shown below:

DisplayMode dm = new DisplayMode(640,480,32,60);

When passed to the GraphicsDevice.setDisplayMode will attempt to change your current default monitors screen resolution to 640 pizels in width by 480 pixels in height with 32 bits of space for storing the color of each pixel on screen and a screen refresh rate of 60 hertz.

Warnings:
1) You cannot change the DisplayMode without a fullscreened window.
2) Changing the DisplayMode to something that is not supported by your monitor or display can cause an exception to be thrown.

Notes:
To get a full listing of supported DisplayModes you can use the GraphicsDevice.getDisplayModes() method which will return an array of valid DisplayMode objects. (good for settings option in Games)

Stripping The JFrame Decorations

Well now you can make a fullscreen window but what about that border thats no good for games. All you need to do is the following:

this.setUndecorated(true);
This call is made on any java.awt.Frame object.

How to Escape

Just add a keyListener to the frame. This may be a problem later on if you include other awt or swing components.

Example: Seeing is Believing

Tuesday, June 19, 2007

Start of Game Programming Snippets

This blog is dedicated to showing quick snippets of Game Programming code from a variety of different languages as well as articles on Game Programming practices and algorithms.

Also there will be current news and game reviews. So stay tuned!