Now that we have created a game loop, window, and input manager, we can create a very simple game. This will be a short tutorial, but will demonstrate the use of the components we have created. We will begin by creating the main class AsteroidsInfinity. It will extend Game, the window manager we created earlier.
public class AsteroidsInfinity extends Game
{
private Path2D.Double ssTriangle;
private double shipX;
private double shipY;
Our simple game will require only three members, the shape used to draw the ship, and its x and y position. We will assign these values in the startup method.
public void gameStartup()
{
Log.info(getClass().getSimpleName(), "Starting up game");
// construct our ship
ssTriangle = new Path2D.Double();
ssTriangle.moveTo(0.0, -30.0);
ssTriangle.lineTo(20.0, 20.0);
ssTriangle.lineTo(0.0, 10.0);
ssTriangle.lineTo(-20.0, 20.0);
ssTriangle.closePath();
// assign the initial location of the ship
shipX = getWidth() / 2;
shipY = getHeight() / 2;
}
This creates the arrow shaped ship, and assigns it location to the center of the screen. Next is the update logic.
public void gameUpdate(double delta)
{
Keyboard keyboard = getKeyboard();
// poll the input for the arrow keys to control movement
if(keyboard.isKeyPressed(KeyEvent.VK_UP))
shipY -= 100.0 * delta;
if(keyboard.isKeyPressed(KeyEvent.VK_DOWN))
shipY += 100.0 * delta;
if(keyboard.isKeyPressed(KeyEvent.VK_LEFT))
shipX -= 100.0 * delta;
if(keyboard.isKeyPressed(KeyEvent.VK_RIGHT))
shipX += 100.0 * delta;
// check the list of key events for a pressed escape key
LinkedList<KeyEvent> keyEvents = keyboard.getEvents();
for(KeyEvent event : keyEvents)
{
if((event.getID() == KeyEvent.KEY_PRESSED) &&
(event.getKeyCode() == KeyEvent.VK_ESCAPE))
{
stop();
}
}
}
First we get the keyboard manager. To control the space ships movement we will use the polling style interface. We check each of the of the arrow keys and adjust the ships position appropriately if any of those keys are pressed. If the user presses the escape key, we want our program to exit. We dont want to miss this event, so we will examine every key press during the last update interval. If the escape key was pressed, we will call stop to end the game. Now we need to implement the draw method.
public void gameDraw(Graphics2D g)
{
// offset our drawing to the ships location
g.translate(shipX, shipY);
// draw the ship (fill then outline)
g.setColor(Color.gray);
g.fill(ssTriangle);
g.setColor(Color.white);
g.draw(ssTriangle);
}
The drawing method first translates the canvas to the ships location, then fills and outlines the ships shape. The shutdown method also needs to be implemented, but it does not need to do anything.
public void gameShutdown()
{
Log.info(getClass().getSimpleName(), "Shutting down game");
}
What remains is the constructor and the main method.
public AsteroidsInfinity()
{
// call game constructor
super("Asteroids Infinity", 640, 480);
}
public static void main(String[] args)
{
Game game = new AsteroidsInfinity();
game.run(1.0 / 60.0);
System.exit(0);
}
The constructor calls Games constructor with our desired title and size. The main method first creates an instance of AsteroidsInfinity, then calls run with the target logic rate. Finally, after run returns (after stop is called), we exit the program.
We have now completed a simple game. Next we will re-factor this code into the basis of our game engine. The complete source code for this example can be found in Asteroids Infinity Phase 1.zip, here.
-Eric

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.geom.Path2D;
import java.util.LinkedList;
public class AsteroidsInfinity extends Game
{
private Path2D.Double ssTriangle;
private double shipX;
private double shipY;
public static void main(String[] args)
{
Game game = new AsteroidsInfinity();
game.run(1.0 / 60.0);
System.exit(0);
}
public AsteroidsInfinity()
{
// call game constructor
super("Asteroids Infinity", 640, 480);
}
public void gameStartup()
{
Log.info(getClass().getSimpleName(), "Starting up game");
// construct our ship
ssTriangle = new Path2D.Double();
ssTriangle.moveTo(0.0, -30.0);
ssTriangle.lineTo(20.0, 20.0);
ssTriangle.lineTo(0.0, 10.0);
ssTriangle.lineTo(-20.0, 20.0);
ssTriangle.closePath();
// assign the initial location of the ship
shipX = getWidth() / 2;
shipY = getHeight() / 2;
}
public void gameUpdate(double delta)
{
Keyboard keyboard = getKeyboard();
// poll the input for the arrow keys to control movement
if(keyboard.isKeyPressed(KeyEvent.VK_UP))
shipY -= 100.0 * delta;
if(keyboard.isKeyPressed(KeyEvent.VK_DOWN))
shipY += 100.0 * delta;
if(keyboard.isKeyPressed(KeyEvent.VK_LEFT))
shipX -= 100.0 * delta;
if(keyboard.isKeyPressed(KeyEvent.VK_RIGHT))
shipX += 100.0 * delta;
// check the list of key events for a pressed escape key
LinkedList<KeyEvent> keyEvents = keyboard.getEvents();
for(KeyEvent event : keyEvents)
{
if((event.getID() == KeyEvent.KEY_PRESSED) &&
(event.getKeyCode() == KeyEvent.VK_ESCAPE))
{
stop();
}
}
}
public void gameDraw(Graphics2D g)
{
// offset our drawing to the ships location
g.translate(shipX, shipY);
// draw the ship (fill then outline)
g.setColor(Color.gray);
g.fill(ssTriangle);
g.setColor(Color.white);
g.draw(ssTriangle);
}
public void gameShutdown()
{
Log.info(getClass().getSimpleName(), "Shutting down game");
}
}
Hey thanks a lot for making these tutorials! I really appreciate the hard work you have put into them and look forward to seeing more of them in the future!
- Jeff
Thanks. Unfortunately, my life is kind of busy right now. I will have a lot more free time in a month, and I intend to devote quite a bit of that to this site. If you have any topics that you are interested in, let me know and Ill try and right a tutorial for it.
Ya I totally understand about being busy with life. To be honest, the main things that Im looking for out of this tutorial series is a finished Asteroids-type game b/c I am going to use this engine as the basis for a game that would be similar to the Call of Duty Dead Ops arcade game. So, in addition to the things you are already planning on going over, it would be cool to see a tutorial about implementing powerups into the game. Thanks again for writing these and Ill definitely keep checking back for more tutorials.