Archive for August, 2008

Space Pirates! – The Gameplan

The Idea

You are the captain of a small space craft. You must head out into the galaxy in search of fame and forture. To this end, you can capture hostile ships, trade goods between planets, and explore uncharted territories. Will you help expand the empire of your own race, or will you be mercenary pirate, plundering any ship foolish enough to cross your path? Something along the lines of Sid Meier’s Pirates, but with space suits and funny looking aliens.

Progress so far

  • Parallax starfield gives nice 3d movement effect
  • Ships move/rotate with proper physics
  • Keyboard controls player ship
  • Ships can shoot lasers
  • Seeker AI that follows player and shoots when close enough

Milestone 0.5 – Basic Combat Test Cases

  • Enemy ships attack, die, and respawn
  • Player can take damage (should respawn after death)

The first step will be to figure out whether combat like this can be fun, or whether I need bigger/more/different ships of some sort. Drawing inspiration from the ship to ship combat in the original Pirates is tricky, since that combat is very slow.  It seems silly to just have big ships sit next to each other and shoot, so we need something a little more interesting.  To start, I am testing small ship dog fights which require a lot more movement. At this point they look cool, but I’m not sure if there is any real strategy or enough fun.

Leave a Comment

A Multi-layer Starfield

Everyone wants to grow up to be an astronaut [citation needed]. Sadly, I don’t think it is in the cards for me, so instead I am working on a little game where I can fly my own spaceship.

There was interest in how to make a parallax style starfield on the slick forums, so I figured I’d share some of my code.

package tspace.gfx;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.util.Log;

/**
 * This creates a starfield effect where different layers of stars scroll by at
 * different speeds as the player moves.
 * @author twood
 *
 */
public class SimpleStars {

	private Image img;
	private int TILESIZE = 512;
	private float x, y;
	private int width, height;
	private float[] depths;

	/**
	 * Creates a new starfield
	 * @param w - width of the canvas to draw to
	 * @param h - height of canvas
	 * @param depths - an array of floats specifying the depths of the star layers.
	 */
	public SimpleStars(int w, int h, float[] depths){
		loadImage();
		width = w;
		height = h;
		this.depths = depths;
	}

	/** Load the images used for different layers of the star field.
	 *
	 * This uses the same image for all layers, but can be extended to use
	 * different ones at different depths.
	 *
	 * @param i the layer to be loaded
	 */
	public Image loadImage()
	{
		if(img == null)
		{
			try
			{
				img = new Image("res/stars.png");
			}
			catch (SlickException e) {
				Log.error("ERR loading star image", e);
			}
		}
		return img;
	}

	/**
	 * Render each layer of the starfied. Works by determining a different offset for
	 * each layer to give the effect that some are moving faster than others.
	 *
	 * @param g the graphics context to draw to.
	 */
	public void render(Graphics g)
	{
		g.setDrawMode(Graphics.MODE_ADD);
		for(int d=0; d < depths.length;d++) {

			float scale = depths[d];
			float cornerX = x/scale-width/2/scale;
			float cornerY = y/scale-height/2/scale;
			float startX = (float) (Math.floor(cornerX/TILESIZE)*TILESIZE);
			float startY = (float) (Math.floor(cornerY/TILESIZE)*TILESIZE);
			float offsetX = -cornerX;
			float offsetY = -cornerY;

			for(int row = (int) startY; row < startY+2*height; row+=TILESIZE)
			{
				for(int col = (int) startX; col < startX+2*width; col+=TILESIZE)
				{
					g.drawImage(img, col+offsetX, row+offsetY);
				}

			}
		}
		g.setDrawMode(Graphics.MODE_NORMAL);
	}

	public void setPos(float x, float y) {
		this.x = x;
		this.y = y;
	}

}

This class can be used to generate the starfield. In an init() function, you might call sometin like this to create a starfield with 5 layers:

float[] depths = {12f, 8f, 5f, 3.5f, 1f};
stars = new Starfield(container.getWidth(), container.getHeight(), depths);

Then in the update() function of your game you must call setPos(x,y) to specify the current position of the camera. Finally, you must call render(g) to actually display the graphics.

You can use this star image, or you can create your own.

How it works: The basic idea is that you have multiple star images which get layered on top of each other with different offsets.  As you move around, the front layer’s offset moves quickly, while the back layers will move more slowly since their offset is adjusted in a different ratio. This ratio is determined by the depths array. Larger numbers are used for further back layers of stars.

Note: This code assumes you are using the Slick library – to learn more about slick, go here.

Comments (2)