/* Copyright 2009 by Sean Luke Licensed under the Academic Free License version 3.0 See the file "LICENSE" for more information */ package sim.app.asteroids; import sim.engine.*; import sim.util.*; import sim.field.continuous.*; import java.awt.geom.*; /** Asteroids is the SimState of the game. It contains a single field, which holds all the Elements in the game (Ships, Asteroids, Bullets, Shards), plus an array of actions[] which tell Ships what their users want them to do. */ public class Asteroids extends SimState { private static final long serialVersionUID = 1; /** How long, in ticks, should we wait after the asteroids and/or ship have been entirely destroyed before resetting? */ public static final int WAIT_PERIOD = 60; /** How far should a ship or asteroid be placed from one another so as not to be too unfair on the user? */ public static final double SAFE_DISTANCE = 30; /** Field of all Elements in the game. */ public Continuous2D field; /** Width of the field. */ public double width = 150; /** Height of the field. */ public double height = 150; /** Number of initial asteroids. */ public int numAsteroids = 5; /** Number of initial ships. */ public int numShips= 1; /** Current score. */ public int score = 0; /** Lives lost. */ public int deaths = 0; /** Level. */ public int level = 0; /** Remaining Asteroids */ public int asteroidCount = 0; /** Array of actions, one per ship, indicating what the user wishes the ship to do. Actions are ORed constants: the LEFT, FORWARD, RIGHT, FIRE, and HYPERSPACE constants in the Ship class. */ public int actions[] = new int[numShips]; /** Ships */ public Ship[] ships = new Ship[numShips]; /** Creates a Asteroids simulation with the given random number seed. */ public Asteroids(long seed) { super(seed); } /** Generate Ship */ public void createShip(int tag) { // make the ship ships[tag] = new Ship(this, new MutableDouble2D(0,0), new Double2D(width / 2, height/ 2), tag); } /** Generate Asteroids */ public void createAsteroids() { level++; // make a bunch of asteroids on the periphery for(int x=0;x<numAsteroids;x++) { double angle = random.nextDouble() * Math.PI * 2; Double2D loc = null; for(int i = 0; i < 1000; i++) // try 1000 times, so as to break theoretical deadlock { if (random.nextBoolean()) loc = new Double2D(0, random.nextDouble() * height); else loc = new Double2D(random.nextDouble() * width, 0); boolean bad = false; for(int j = 0; j < numShips; j++) if (ships[j] != null && field.getObjectLocation(ships[j]).distance(loc) < SAFE_DISTANCE) { bad = true; break; } if (!bad) break; } new Asteroid(this, Asteroid.MAXIMUM_SIZE, new MutableDouble2D( Asteroid.INITIAL_VELOCITY * Math.cos(angle), Asteroid.INITIAL_VELOCITY * Math.sin(angle)), loc); } } /** Starts the Asteroids simulation. */ public void start() { super.start(); // set up the asteroids fields field = new Continuous2D(width,width,height); for(int x=0;x < numShips; x++) createShip(x); createAsteroids(); } /** Default main loop for MASON. */ public static void main(String[] args) { doLoop(Asteroids.class, args); System.exit(0); } }