class Star { float x,y,phase,phaseStep; color col; Star() { phase = random(TWO_PI); phaseStep = random(0.005,0.01); x = random(width); y = random(height); col = color(random(230,255),random(230,255),random(230,255),64); } void draw() { stroke(col); line(x,y,x,y); color c = color(255.0, 255.0, 255.0, 64.0 + (128.0 * sin(TWO_PI*phase)) ); stroke(c); line(x,y,x,y); phase += phaseStep; phase %= TWO_PI; } } abstract class WorldObject { float x,y,vx,vy,radius; WorldObject(float x, float y, float vx, float vy, float radius) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.radius = radius; } void move() { x += vx; y += vy; x = wrap(x,0,width,radius); y = wrap(y,0,height,radius); } abstract void draw(); } class Particle extends WorldObject { int maxage = 10; int age = 0; Particle(float x, float y, float vx, float vy, float radius, int maxage) { super(x,y,vx,vy,10); this.maxage = maxage; } void move() { super.move(); age++; if (age == maxage) { particles.remove(this); } } void draw() { rectMode(CENTER_DIAMETER); fill(255); noStroke(); rect(x,y,3,3); } } class Bullet extends Particle { Bullet(float x, float y, float vx, float vy) { super(x,y,vx,vy,10.0,30); } } class Exhaust extends Particle { Exhaust(float x, float y, float vx, float vy) { super(x,y,vx,vy,10.0,8); } void draw() { blend(exPart,0,0,exPart.width-1,exPart.height-1,(int)x-exPart.width/2,(int)y-exPart.height/2,(int)x+exPart.width/2,(int)y+exPart.height/2,ADD); } } class Ship extends WorldObject { float angle; float drag; boolean shields = false; Ship() { super(width/2,height/2,0,0,10.0); angle = 0; drag = 0.95; } void turn(float off) { angle += off; } void accel(float accel) { float cx = cos(angle); float cy = sin(angle); vx += cx * accel; vy += cy * accel; particles.add(new Exhaust(x-10*cx,y-10*cy,random(vx/2,vx),random(vy/2,vy))); } void shields() { shields = true; } void move() { shields = false; if (keysPressed[UP]) ship.accel(0.5); else if (keysPressed[DOWN]) ship.shields(); if (keysPressed[LEFT]) ship.turn(-0.1); else if (keysPressed[RIGHT]) ship.turn(0.1); if (keysPressed[' ']) ship.fire(); super.move(); vx *= drag; vy *= drag; } void draw() { push(); translate(x,y); rotate(angle); noStroke(); beginShape(POLYGON); fill(120,0,30); vertex(-10,-10); fill(220,30,80); vertex(12.5,0); fill(255); vertex(-10,10); vertex(-5,0); endShape(); pop(); if (shields) { ellipseMode(CENTER_DIAMETER); stroke(255,128,0); fill(255,255,0,32); ellipse(x,y,3*radius,3*radius); } } void fire() { particles.add(new Bullet(x,y,20*cos(angle),20*sin(angle))); } } class Asteroid extends WorldObject { int n = 15; float xs[]; float ys[]; int c[]; float angle, angleStep; Asteroid(float rad) { super(random(width),random(height),random(-1,1),random(-1,1), rad); xs = new float[n]; ys = new float[n]; c = new int[n]; for (int i = 0; i < n; i++) { float p = (float)i/n; xs[i] = rad*cos(TWO_PI*p) + random(-rad/4,rad/4); ys[i] = rad*sin(TWO_PI*p) + random(-rad/4,rad/4); c[i] = (int)random(60,150); } angle = random(TWO_PI); angleStep = random(-0.03,0.05); } void move() { super.move(); angle+=angleStep; } void draw() { stroke(0); push(); translate(x,y); rotate(angle); beginShape(POLYGON); for (int i = 0; i < n; i++) { fill(c[i]); vertex(xs[i], ys[i]); } endShape(); pop(); } } Ship ship; Star[] stars; ArrayList asteroids = new ArrayList(); ArrayList particles = new ArrayList(); BImage exPart; boolean keysPressed[]; void setup() { size(400,400); smooth(); ship = new Ship(); stars = new Star[256]; for (int i = 0; i < stars.length; i++) { stars[i] = new Star(); } for (int i = 0; i < 8; i++) { asteroids.add(new Asteroid(25)); } exPart = createParticleImage(10); background(0); keysPressed = new boolean[128]; for (int i = 0; i < keysPressed.length; i++) { keysPressed[i] = false; } } void loop() { background(0); for (int i = 0; i < stars.length; i++) { stars[i].draw(); } for (int i = 0; i < asteroids.size(); i++) { Asteroid asteroid = (Asteroid)asteroids.get(i); asteroid.move(); asteroid.draw(); } for (int i = 0; i < particles.size(); i++) { Particle particle = (Particle)particles.get(i); particle.move(); particle.draw(); } ship.move(); ship.draw(); } void keyPressed() { keysPressed[key] = true; } void keyReleased() { keysPressed[key] = false; } float wrap(float val, float min, float max, float radius) { if (val > max+(2*radius)) { val -= (max-min)+4*radius; } else if (val < min-2*radius) { val += (max-min)+4*radius; } return val; } BImage createParticleImage(int dim) { BImage img = new BImage(dim,dim); float maxd = max(img.width/2,img.height/2); for (int i = 0; i < img.width; i++) { for (int j = 0; j < img.height; j++) { float d = sqrt(sq(i-(img.width/2))+sq(j-(img.height/2))); img.set(i,j,color(255,128,10,255-(255*d/maxd))); } } return img; }