class Bubble
{
public PVector pos;
public float rad;
public float colorHue;
private PVector speed;
Bubble() {
pos = new PVector(random(width), rad*-1);
colorHue = random(360);
rad = random(10,30);
speed = new PVector(0, random(1,2));
}
public void update() {
pos.add(speed);
}
public void display() {
noFill();
noStroke();
colorMode(HSB, 360, 100, 100, 100);
stroke(colorHue, 100, 100, 50);
strokeWeight(2);
// fill(colorHue, 100, 100, 50);
ellipse(pos.x, pos.y, rad*2, rad*2);
strokeWeight(1);
}
public boolean isOutOfDisplay() {
if ( pos.y-rad > height ) {
return true;
}
return false;
}
}
class Bullet
{
private PVector pos;
private int h = 3;
Bullet(PVector pos) {
this.pos = pos;
}
public void update() {
pos.add(new PVector(0,-5));
}
public void display() {
noFill();
stroke(255);
line(pos.x, pos.y, pos.x, pos.y+h);
}
public boolean isOutOfDisplay() {
if ( pos.y+h < 0 ) {
return true;
}
return false;
}
public boolean intersect(Bubble bubble) {
if ( pos.dist(bubble.pos) <= bubble.rad ) {
return true;
}
return false;
}
}
class Particle
{
private PVector pos;
private PVector speed;
private float colorHue;
private float colorBrightness;
Particle(PVector pos, PVector speed, float colorHue) {
this.pos = pos;
this.speed = speed;
this.colorHue = colorHue;
this.colorBrightness = 100;
}
public void update() {
pos.add(speed);
colorBrightness -=.4;
}
public void display() {
colorMode(HSB, 360, 100, 100);
stroke(colorHue, 100, colorBrightness);
point(pos.x, pos.y);
}
public boolean isOutOfDisplay() {
if (colorBrightness <= 0 ||pos.x < 0 || pos.x > width || pos.y < 0 || pos.y > height) {
return true;
}
return false;
}
}
class Ship
{
public PVector pos;
private PVector posTarget;
private PVector speed;
private int lastShot;
private int gunPause;
public boolean isFiring = false;
Ship() {
pos = new PVector(width/2, height-30);
posTarget = new PVector(width/2, height-30);
speed = new PVector(0,0);
gunPause = 100;
lastShot = gunPause * -1;
}
public void update() {
posTarget.add(speed);
if (posTarget.x > width ) {
posTarget.x = width;
}
else if (posTarget.x < 0 ) {
posTarget.x = 0;
}
PVector diff = PVector.sub(posTarget, pos);
diff.mult(.075);
pos.add(diff);
}
public void display() {
noStroke();
fill(255, 200);
triangle(pos.x, pos.y, pos.x+3, pos.y+10, pos.x-3, pos.y+10);
}
public void navigate(PVector direction) {
speed = direction;
speed.mult(5);
}
public boolean gunReady() {
if ( millis() >= lastShot + gunPause ) {
return true;
}
return false;
}
public void fire() {
lastShot = millis();
}
}
ArrayList stars = new ArrayList();
int starsNum = 100;
ArrayList bullets = new ArrayList();
ArrayList bubbles = new ArrayList();
ArrayList particles = new ArrayList();
Ship ship;
Timer bubbleTimer;
void setup() {
size(360, 480);
smooth();
background(0);
// bubble timer
bubbleTimer = new Timer(500);
// stars
for ( int i = 0; i < starsNum; i++ ) {
stars.add(new Star());
}
// ship
ship = new Ship();
}
void draw() {
// background
rectMode(CORNER);
noStroke();
fill(0);
rect(0, 0, width, height);
// stars
for ( int i = 0; i < starsNum; i++ ) {
Star star = (Star) stars.get(i);
star.update();
if ( star.isOutOfDisplay() ) {
star.reset();
}
star.display();
}
// particles
for ( int i = particles.size()-1; i >= 0; i-- ) {
Particle particle = (Particle) particles.get(i);
particle.update();
particle.display();
if (particle.isOutOfDisplay() ) {
particles.remove(i);
}
}
// bubbles
if ( bubbleTimer.hasFinished() ) {
bubbles.add(new Bubble());
}
for ( int i = bubbles.size()-1; i >= 0; i-- ) {
Bubble bubble = (Bubble) bubbles.get(i);
bubble.update();
bubble.display();
if ( bubble.isOutOfDisplay() ) {
bubbles.remove(i);
}
}
// ship
ship.update();
ship.display();
// bullets
if (ship.isFiring && ship.gunReady()) {
ship.fire();
bullets.add(new Bullet(new PVector(ship.pos.x, ship.pos.y)));
}
for ( int i = bullets.size()-1; i >= 0; i-- ) {
Bullet bullet = (Bullet) bullets.get(i);
bullet.update();
bullet.display();
if ( bullet.isOutOfDisplay() ) {
bullets.remove(i);
}
else {
for ( int j = bubbles.size()-1; j >= 0; j-- ) {
Bubble bubble = (Bubble) bubbles.get(j);
if ( bullet.intersect(bubble) ) {
// bullets.remove(i);
bubbles.remove(j);
for ( int k = 0; k < bubble.rad*20; k++ ) {
float angle = random(TWO_PI);
PVector particlePos = new PVector(bubble.pos.x + sin(angle)*bubble.rad,
bubble.pos.y + cos(angle)*bubble.rad);
PVector particleSpeed = PVector.sub(particlePos, bubble.pos);
particleSpeed.limit(1);
particleSpeed.mult(random(.5,1.5));
particles.add(new Particle(particlePos, particleSpeed, bubble.colorHue));
}
}
}
}
}
}
void keyPressed() {
if (keyCode == LEFT) {
ship.navigate(new PVector(-1,0));
}
else if (keyCode == RIGHT) {
ship.navigate(new PVector(1,0));
}
else if (key == ' ') {
ship.isFiring = true;
}
}
void keyReleased() {
if (keyCode == LEFT || keyCode == RIGHT) {
ship.navigate(new PVector(0,0));
}
else if (key == ' ') {
ship.isFiring = false;
}
}
class Star
{
private float zPos;
private PVector pos;
private PVector speed;
Star() {
this.reset();
pos = new PVector(int(random(width)), int(random(height)));
}
public void update() {
pos.add(speed);
}
public void display() {
noFill();
stroke(255 * zPos);
point(pos.x, pos.y);
}
public boolean isOutOfDisplay() {
if ( pos.y > height ) {
return true;
}
return false;
}
public void reset() {
zPos = random(1);
pos = new PVector(int(random(height)), 0);
speed = new PVector(0, 1*zPos);
}
}
class Timer
{
int then; // last saved time
int interval; // in ms
Timer(int interval) {
this.interval = interval;
}
void start() {
then = millis();
}
boolean hasFinished() {
if ( millis() - then >= interval ) {
then = millis();
return true;
}
return false;
}
}
- Click the applet to activate keyboard control.
- Use left/right arrow to move
- space to shoot
Good luck!