
class Enemy {
int mySize = 4;
public float x;
public float y;
public float speed;
public Enemy(float xPos, float yPos, float sp) {
x = xPos;
y = yPos;
speed = sp;
}
public void draw() {
ellipse(x, y, mySize, mySize);
}
public void moveTowards(float xPos, float yPos)
{
}
}
class Player
{
//Player member variables, passed to constructor
private int mySize;
private float speed;
private float easing;
public float x;
public float y;
//Player member variables, set in constructor (but not passed in)
private float arcX;
private float arcY;
private float targetX;
private float targetY;
private float theta;
public Player(float xPos, float yPos, float sp, float ease, int pSize)
{
x = xPos;
y = yPos;
speed = sp;
easing = ease;
mySize = pSize;
arcX = 0;
arcY = 0;
targetX = xPos;
targetY = yPos;
theta = 0.0;
}
public void draw()
{
move();
}
//Move the player based on key presses and orbit parameters
//Return true if the player is pressing a key, false otherwise
public void move()
{
if (keyPressed) {
if (key == CODED) {
progress = sORp;
if (keyCode == UP) {
targetY -= speed;
if (targetY < 0) targetY = 0;
}
if (keyCode == DOWN) {
targetY += speed;
if (targetY > height) targetY = height;
}
if (keyCode == LEFT) {
targetX -= speed;
if (targetX < 0) targetX = 0;
}
if (keyCode == RIGHT) {
targetX += speed;
if (targetX > width) targetX = width;
}
}
}
else
{
progress = !sORp;
}
float d = dist(centerX, centerY, targetX, targetY);
if (d > 1.0) {
x += (targetX - x) * easing;
y += (targetY - y) * easing;
}
theta += .1;
if (theta > TWO_PI) {
theta = 0;
if (!progress) {
time++;
}
else {
//Trigger the tick sound effect
tick.trigger();
}
fill(255);
text(time, width - 75, 50);
}
arcX = x + mySize*cos(theta);
arcY = y + mySize*sin(theta);
fill(255, 255, 255);
ellipse(arcX, arcY, mySize, mySize);
}
public void collide(float x1, float y1)
{
if (dist(x1, y1, arcX, arcY) <= (mySize + enemySize)/2) {
collided = true;
setupGame();
}
}
public void reset()
{
time = 0;
x = centerX;
y = centerY;
targetX = x;
targetY = y;
}
}
/* Author: Joshua Fishburn
* Date: 8/11/2009
* Survive/Progress Version 0.1
* - Combining the functionality of Survive and Progress into one game
* - Allow the player to choose which version to play
* - Track record times for both versions of the game
*
* Date: 08/11/2009
* Survive Version 0.4
* - Condensed createEnemies function so that it works with only one for loop
*
* Date: 08/10/2009
* Survive Version 0.3
* - Separated functionality out to Enemy and Player classes
* - Added comments and cleaned up unnecessary variables
*/
//Import for minim sound library
import ddf.minim.*;
import ddf.minim.signals.*;
//Define the sound objects we need for the beep
Minim minim;
AudioSample tick;
AudioOutput out;
//Font for displaying stuff on the screen
PFont font;
//Main control variables for the win/lose survive/progress conditions
boolean sORp;
boolean progress;
boolean collided = true;
//The center of the game screen, no matter the resolution
int centerX;
int centerY;
//The radii and other parameters of both Player and Enemy
int playerSize = 8;
float playerSpeed = 2.0;
float playerEasing = 0.05;
int enemySize = 4;
//Record keeping
int time = 0;
int timePreviousProgress = 0;
int timePreviousSurvive = 0;
int timeRecordProgress = 0;
int timeRecordSurvive = 0;
//Enemy Waves - Allows for dynamic addition of enemy waves with the numWaves variable
int numEnemies = 25;
int numWaves = 5;
int numTotalEnemies = (int)(numEnemies*(pow(2, numWaves) - 1));
int enemyRadii;
//Setup a main array to hold all enemies, regardless of location (distribution of enemies is a MAIN-specific algorithm)
Enemy[] enemies = new Enemy[numTotalEnemies];
//The main player object
Player player;
void setup() {
size(800, 600);
centerX = width/2;
centerY = height/2;
noStroke();
smooth();
ellipseMode(CENTER);
font = loadFont("Krungthep-48.vlw");
//Pick a random mode to start the game in (Between Survive and Progress)
int rand = int(random(2));
if (rand == 1) sORp = true; else sORp = false;
progress = sORp;
//sORp = boolean(int(random(2)));
//Setup audio sample for beep
minim = new Minim(this);
tick = minim.loadSample("hospital_monitor_beep.mp3", 8192);
if ( tick == null ) println("Didn't get tick!");
out = minim.getLineOut(Minim.STEREO);
//Create the player instance
player = new Player(centerX, centerY, playerSpeed, playerEasing, playerSize);
}
void draw() {
// Create the background
fill(0, 12);
rect(0, 0, width, height);
if (!collided)
{
// Move the circle
player.draw();
// Move Lines to attack circle
moveEnemies();
}
else
{
fill(255);
textFont(font, 45);
//Display different text depending on the player's game choice
if (sORp)
{
text("Use Arrow Keys to SURVIVE", centerX - 350, centerY - 50);
}
else
{
text("Use Arrow Keys to PROGRESS", centerX - 350, centerY - 50);
}
textFont(font, 25);
text("Press 'M' to Switch Game Modes", centerX - 200, centerY);
text("Press 'S' to Start a New Game", centerX - 200, centerY + 30);
if (sORp)
{
text("Previous time was " + timePreviousSurvive, centerX-200, centerY + 60);
text("Record time is " + timeRecordSurvive, centerX - 200, centerY + 90);
}
else
{
text("Previous time was " + timePreviousProgress, centerX-200, centerY + 60);
text("Record time is " + timeRecordProgress, centerX - 200, centerY + 90);
}
}
}
void keyReleased()
{
if (key == 's' || key == 'S') {
collided = false;
//Setup all of the enemies and player position
setupGame();
}
if (key == 'm' || key == 'M') {
//Switch between Survive and Progress gameplay
if (sORp) sORp = false; else sORp = true;
}
}
void createEnemies()
{
numEnemies = 25;
enemyRadii = 200;
float increment = TWO_PI/numEnemies;
float theta = 0;
int i = 0;
int iterations = 1;
int speed = 1000;
for (i = 0; i < numTotalEnemies; i++)
{
// Get the coordinates around the circle
float nx = enemyRadii*cos(theta) + centerX;
float ny = enemyRadii*sin(theta) + centerY;
enemies[i] = new Enemy(nx, ny, random(speed) + 100);
//Increment theta
theta += increment;
//If we filled the circle, then reset and push out the radius for the next wave
if (theta > TWO_PI)
{
theta = 0;
numEnemies *= 2;
enemyRadii *= 4;
increment = TWO_PI/numEnemies;
speed -= 250/iterations;
iterations++;
}
}
}
//For each enemy, chase the player by finding the distance from it to the player and following that line
void moveEnemies() {
fill(255);
for (int i = 0; i < numTotalEnemies; i++) {
if (!progress) {
//Now, move along that line with the appropriate speed
float dx = enemies[i].x - player.x;
float dy = enemies[i].y - player.y;
enemies[i].x -= dx/enemies[i].speed;
enemies[i].y -= dy/enemies[i].speed;
}
enemies[i].draw();
player.collide(enemies[i].x, enemies[i].y);
}
}
void setupGame() {
//Reset the time, record the new record, reset the player to the center, and recreate the waves of enemies
if (sORp)
{
timePreviousSurvive = time;
if (timePreviousSurvive > timeRecordSurvive) timeRecordSurvive = timePreviousSurvive;
}
else
{
timePreviousProgress = time;
if (timePreviousProgress > timeRecordProgress) timeRecordProgress = timePreviousProgress;
}
player.reset();
//Pick a random mode to start the game in (Between Survive and Progress)
createEnemies();
}
//Properly close out the sound objects
void stop()
{
tick.close();
out.close();
minim.stop();
super.stop();
}
OpenProcessing is an online community platform devoted to sharing and discussing Processing sketches in a collaborative, open-source environment.
Download Processing
Terms of Service
To contact, send an email to:

See the feedback forum and vote!
Follow OpenProcessing on Twitter.
All sketches are licensed under Creative Commons Attribution-Share Alike 3.0.
Syntax highlighting and Processing brush under LGPL 3.
All the source code is licensed under Creative Commons GNU GPL.
Comments engine by Scriptsmill Comments Script.
