class GameList extends ArrayList { void tick() { Iterator i = iterator(); while(i.hasNext()) { GameObject p = (GameObject) i.next(); p.tick(); if(p.removal_flag) i.remove(); } } void draw() { Iterator i = iterator(); while(i.hasNext()) { GameObject p = (GameObject) i.next(); p.draw(); } } } abstract class GameObject { abstract void tick(); abstract void draw(); PVector pos; float radius; boolean removal_flag = false; } abstract class Projectile extends GameObject { float phase; PVector vel; void tick() { pos.add(vel); if(pos.x < 0 - radius) removal_flag = true; if(pos.x > width + radius) removal_flag = true; if(pos.y < 0 - radius) removal_flag = true; if(pos.y > height + radius) removal_flag = true; phase += random(1); } } class Pickup extends Projectile { Pickup(PVector p) { this(new PVector(p.x, p.y), new PVector(0,0)); } Pickup(PVector p, PVector v) { radius = 8; pos = new PVector(p.x, p.y); vel = new PVector(v.x, v.y); } void draw() { fill(128+64*sin(phase*0.2), 255, 0); noStroke(); ellipse(pos.x, pos.y, radius, radius); } void tick() { super.tick(); if(inRadius(player_pos, pos, PLAYER_RADIUS+radius)) { if(!muted) getSound.trigger(); if(level_goal == COLLECT) goal_progress++; removal_flag = true; } } } class BadShot extends Projectile { BadShot(PVector p) { this(new PVector(p.x, p.y), new PVector(0,0)); } BadShot(PVector p, PVector v) { radius = 5; pos = new PVector(p.x, p.y); vel = new PVector(v.x, v.y); } void draw() { fill(255, 128+64*sin(phase*0.2), 0); noStroke(); ellipse(pos.x, pos.y, radius, radius); } void tick() { super.tick(); if(inRadius(player_pos, pos, PLAYER_RADIUS+radius)) { killPlayer(); } } } class PShot extends Projectile { PShot(PVector p) { this(new PVector(p.x, p.y), new PVector(0,0)); } PShot(PVector p, PVector v) { radius = 3; pos = new PVector(p.x, p.y); vel = new PVector(v.x, v.y); } void draw() { fill(0, 128+64*sin(phase*0.2), 255); noStroke(); ellipse(pos.x, pos.y, radius, radius); } void tick() { super.tick(); } } class Enemy extends GameObject { float phase = 0; void tick() { phase += random(1); Iterator psi = player_shots.iterator(); while(psi.hasNext()) { GameObject g = (GameObject) psi.next(); if(inRadius(pos, g.pos, radius+g.radius) && !removal_flag) { hit(); psi.remove(); } } if(inRadius(player_pos, pos, PLAYER_RADIUS+radius)) { killPlayer(); } if(pos.x < 0 - radius) removal_flag = true; } Enemy(PVector p) { radius = 8; pos = p; } void draw() { fill(255, 128+64*sin(phase*0.1), 0); noStroke(); rect(pos.x, pos.y, radius, radius); } void hit() { removal_flag = true; if(!muted) killSound.trigger(); misc_counter++; if(misc_counter % ENEMIES_PER_DROP == 0) enemy_shots.add(new Pickup(pos)); } } class Turret extends Enemy { int lifetime; Turret(PVector p) { super(p); } void tick() { super.tick(); lifetime++; if(lifetime%TURRET_SHOOT_RATE == 0) { PVector at_player = PVector.sub(player_pos, pos); at_player.normalize(); at_player.mult(ENEMY_SHOT_SPEED); enemy_shots.add(new BadShot(pos, at_player)); } } } class Asteroid extends Enemy { PVector vel; Asteroid(PVector p) { super(p); PVector dest = new PVector(random(width), random(height)); vel = PVector.sub(dest, pos); vel.normalize(); vel.mult(0.5); radius = 12; } void tick() { super.tick(); pos.add(vel); if(pos.x < 0 - radius) removal_flag = true; if(pos.x > width + radius) removal_flag = true; if(pos.y < 0 - radius) removal_flag = true; if(pos.y > height + radius) removal_flag = true; } void hit() { for(int i = 0; i < 5; i++) enemy_shots.add(new BadShot(pos, randomVector(ENEMY_SHOT_SPEED))); super.hit(); } } class MobileEnemy extends Enemy { float phase = 0; int swerve = 0; int lifetime; void tick() { super.tick(); lifetime++; if(lifetime%ENEMY_SHOOT_RATE == 0) { PVector at_player = PVector.sub(player_pos, pos); at_player.normalize(); at_player.mult(ENEMY_SHOT_SPEED); at_player.x += SCROLL_RATE; enemy_shots.add(new BadShot(pos, at_player)); } phase += random(1); if(swerve == 2) { pos.x -= ENEMY_SPEED; } else if(swerve == 0) { pos.x -= ENEMY_SPEED; if(lifetime > ENEMY_SWERVE_TIME) { if(player_pos.y < pos.y) swerve = -1; else swerve = 1; } } else { pos.y += ENEMY_SPEED*swerve; if((player_pos.y - pos.y)* swerve < 0) swerve = 2; } if(inRadius(player_pos, pos, PLAYER_RADIUS+radius)) { killPlayer(); } if(pos.x < 0 - radius) removal_flag = true; } MobileEnemy(PVector p) { super(p); } }