//AUTHOR: William Ye //TITLE: avoid2 (NOTE: I NEED A REAL TITLE FOR THIS I CAN'T COME UP WITH A GOOD ONE) //NOTES: Sorry for lack of comments; I thought the code is pretty self explanatory //TODO (later of course): Add particles // Add option to disable background squares // Think of a decent title boolean fullScreen = true; int sw, sh; String screen; Button playButton, quitButton, helpButton; Button menuButton, againButton; Button backButton; PFont font; int numberOfLanes = 5; float laneWidth; ArrayList backgroundQuads; ArrayList blocks; ArrayList bBlocks; float bgAnimationTimer; Player player; boolean cannonReady; float distanceApart = 300; MuzzleFlash muzzleFlash; int score; float cannonTimer; int [][][] patterns = { { {1, 0, 0, 0, 1}, {1, 0, 0, 0, 1}, {1, 1, 0, 1, 1}, {1, 1, 0, 1, 1}, {1, 1, 2, 1, 1} }, { {0, 1, 1, 1, 1}, {1, 0, 1, 1, 1}, {1, 1, 2, 1, 1}, {1, 1, 1, 0, 1}, {1, 1, 1, 1, 0} }, { {1, 1, 0, 1, 1}, {0, 0, 1, 0, 0}, {1, 1, 0, 1, 1}, {0, 0, 1, 0, 0}, {0, 1, 1, 1, 0}, {2, 1, 1, 1, 2} }, { {1, 1, 0, 1, 1}, {1, 1, 0, 1, 1}, {1, 1, 2, 1, 1}, {1, 1, 0, 1, 1}, {1, 1, 0, 1, 1} }, { {1, 0, 1, 1, 1}, {1, 1, 0, 1, 1}, {1, 0, 1, 1, 1}, {1, 1, 2, 1, 1}, {1, 1, 1, 0, 1}, {1, 1, 0, 1, 1}, {1, 1, 1, 0, 1} }, { {1, 1, 0, 1, 1}, {1, 1, 0, 1, 1}, {2, 1, 1, 1, 2}, {0, 1, 1, 1, 0}, {1, 0, 1, 0, 1}, {1, 1, 0, 1, 1}, } }; void setup() { sw = displayWidth; sh = displayHeight; size(sw, sh); rectMode(CENTER); textAlign(CENTER, CENTER); noStroke(); noCursor(); font = createFont("Segoe UI Light", 30); textFont(font); startMenu(); playButton = new Button(sw/2 - 200, sh/2, 170, 100, "PLAY"); quitButton = new Button(sw/2 + 200, sh/2, 170, 100, "QUIT"); helpButton = new Button(sw/2, sh/2, 170, 100, "HELP"); menuButton = new Button(sw/2 + 150, sh/2 + 100, 170, 100, "MENU"); againButton = new Button(sw/2 - 150, sh/2 + 100, 170, 100, "AGAIN"); backButton = new Button(sw/2, sh/2 + 120, 170, 100, "BACK"); laneWidth = sw/numberOfLanes; backgroundQuads = new ArrayList(); blocks = new ArrayList(); bBlocks = new ArrayList(); player = new Player(); muzzleFlash = new MuzzleFlash(); } void reset() { blocks = new ArrayList(); bBlocks = new ArrayList(); cannonReady = true; score = 0; cannonTimer = 100; } void draw() { background(255, 255, 255); animateBackground(); if (screen.equals("menu")) { drawMenu(); } else if (screen.equals("play")) { drawPlay(); } else if (screen.equals("gameover")) { drawGameOver(); } else if (screen.equals("help")) { drawHelp(); } drawCursor(); } void startMenu() { screen = "menu"; } void startPlay() { reset(); screen = "play"; } void startHelp() { screen = "help"; } void startGameOver() { screen = "gameover"; } void drawHelp() { titleText("HELP"); textSize(40); text("MOVE YOUR MOUSE TO AVOID THE BLOCKS", sw/2, sh/2 - 20); text("CLICK TO DESTROY GREEN BLOCKS", sw/2, sh/2 + 20); backButton.update(); backButton.draw(); } void drawGameOver() { titleText("GAME OVER"); textSize(80); text("SCORE: " + score, sw/2, sh/2 - 30); menuButton.update(); menuButton.draw(); againButton.update(); againButton.draw(); } void titleText(String text) { fill(30, 30, 30); textSize(200); text(text, sw/2, sh/4); } void drawMenu() { playButton.update(); playButton.draw(); quitButton.update(); quitButton.draw(); helpButton.update(); helpButton.draw(); titleText("avoid2"); fill(50, 50, 50); textSize(30); text("DEVELOPED BY WILLIAM YE", sw/2, sh - 100); } void drawPlay() { player.update(); player.draw(); for (int i = blocks.size() - 1; i >= 0; i--) { Block b = blocks.get(i); b.update(); b.draw(); //removes blocks if (b.y - b.w/2 > sh) { blocks.remove(i); } //checks for collision if (player.x - player.w/2 < b.x + b.w/2 && player.x + player.w/2 > b.x - b.w/2 && player.y + player.h/2 > b.y - b.h/2 && player.y - player.h/2 < b.y + b.h/2) { startGameOver(); } } for (int i = bBlocks.size() - 1; i >= 0; i--) { BreakableBlock b = bBlocks.get(i); b.update(); b.draw(); if (b.y - b.w/2 > sh) { bBlocks.remove(i); } //checks for collision if (player.x - player.w/2 < b.x + b.w/2 && player.x + player.w/2 > b.x - b.w/2 && player.y + player.h/2 > b.y - b.h/2 && player.y - player.h/2 < b.y + b.h/2) { startGameOver(); } } //increase score score++; muzzleFlash.update(); muzzleFlash.draw(); if (!cannonReady) reloadCannon(); drawHud(); spawnBlocks(); } void reloadCannon() { cannonTimer--; if (cannonTimer < 0) { cannonTimer = 100; cannonReady = true; } } void drawHud() { textSize(60); textAlign(LEFT, CENTER); if (cannonReady) { fill(0, 0, 255); text("CANNON READY", 20, sh - 100); } else { fill(255, 0, 0); text("CANNON DEPLETED", 20, sh - 100); } fill(30, 30, 30); text("SCORE: " + score, sw - 400, sh - 100); textAlign(CENTER, CENTER); } void spawnBlocks() { if (blocks.size() == 0) { addPattern(); } else { if (blocks.get(blocks.size() - 1).y > distanceApart) { addPattern(); } } } void shoot() { if (cannonReady) { muzzleFlash.create(player.x, player.y - player.h/2); //checks if block is shot for (int i = bBlocks.size() - 1; i >= 0; i--) { BreakableBlock b = bBlocks.get(i); if (player.x - player.w/2 < b.x + b.w/2 && player.x + player.w/2 > b.x - b.w/2) { bBlocks.remove(i); } } } cannonReady = false; } void addPattern() { int pNumber, pRows; pNumber = (int)random(patterns.length); //which pattern number? pRows = patterns[pNumber].length; //queries current row for (int i = 0; i < pRows; i ++) { for (int j = 0; j < numberOfLanes; j++) { if (patterns[pNumber][i][j] == 1) { addBlock(j, -i * distanceApart - 25); } else if (patterns[pNumber][i][j] == 2) { addBreakableBlock(j, -i * distanceApart - 25); } } } } void animateBackground() { addBackgrounds(); for (int i = backgroundQuads.size() - 1; i >= 0; i--) { BackgroundQuad b = backgroundQuads.get(i); b.update(); b.draw(); if (b.x1 + b.w1 < 0 && b.x2 + b.w2 < 0) { backgroundQuads.remove(i); } } } void addBackgrounds() { bgAnimationTimer--; if (bgAnimationTimer <= 0) { bgAnimationTimer = 50; backgroundQuads.add(new BackgroundQuad()); } } void mousePressed() { if (screen.equals("menu")) { if (playButton.selected()) { startPlay(); } else if (helpButton.selected()) { startHelp(); } else if (quitButton.selected()) { exit(); } } else if (screen.equals("gameover")) { if (againButton.selected()) { startPlay(); } else if (menuButton.selected()) { startMenu(); } } else if (screen.equals("play")) { shoot(); } else if (screen.equals("help")) { if (backButton.selected()) { startMenu(); } } } void drawCursor() { if (!screen.equals("play")) { stroke(0, 0, 100); strokeWeight(2); noFill(); ellipse(mouseX, mouseY, 10, 10); noStroke(); } } class BreakableBlock extends Block { BreakableBlock(float x, float y) { super(x, y); col = new Color(50, 170, 50); } } class Block { float x, y, w, h; Color col; Block(float x, float y) { this.x = x; this.y = y; w = laneWidth; h = 50; col = new Color(50, 50, 50); } void update() { y += 8; } void draw() { shadowColorize(); rect(x, y+5, w, h); col.colorize(); rect(x, y, w, h); } } class Player { float x, y, w, h; Color col; float pulseSpeed; Player() { x = sw/2; y = sh*4/5; w = 100; h = 50; col = new Color(255, 50, 50); pulseSpeed = 1; } void update() { x = mouseX; pulse(); } void pulse() { if (col.g < 50 || col.g > 100) { pulseSpeed*=-1; } col.g += pulseSpeed; col.b += pulseSpeed; } void draw() { shadowColorize(); rect(x, y + 5, w, h); col.colorize(); rect(x, y, w, h); } } class Button { float x, y, w, h; String text; Color col; float textSize; Button(float x, float y, float w, float h, String text) { this.x = x; this.y = y; this.w = w; this.h = h; this.text = text; col = new Color(50, 50, 50); textSize = 25; } boolean selected() { if (mouseX > x - w/2 && mouseX < x + w/2 && mouseY > y - h/2 && mouseY < y + h/2) { return true; } else { return false; } } void update() { if (selected()) { col.b = 100; textSize = 30; } else { col.b = 50; textSize = 25; } } void draw() { //shadow shadowColorize(); rect(x, y + 5, w, h); //object col.colorize(); rect(x, y, w, h); fill(255, 255, 255); textSize(textSize); text(text, x, y); } } class BackgroundQuad { float x1, x2, w1, w2; Color col; BackgroundQuad() { x1 = sw + random(300); x2 = sw + random(300); w1 = 50; w2 = 50; col = new Color(random(150, 255), random(150, 255), random(150, 255), 200); } void update() { x1 -= 4; x2 -= 4; } void draw() { col.colorize(); quad(x1, 0, x2, sh, x2 + w2, sh, x1 + w1, 0); } } void shadowColorize() { fill(0, 0, 0, 100); } void addBlock(int laneNumber, float y) { if (laneNumber > numberOfLanes - 1) { return; } blocks.add(new Block(laneNumber * laneWidth + laneWidth/2, y)); } void addBreakableBlock(int laneNumber, float y) { if (laneNumber > numberOfLanes - 1) { return; } bBlocks.add(new BreakableBlock(laneNumber * laneWidth + laneWidth/2, y)); } class Color { float r, g, b, o; Color(float r, float g, float b) { this.r = r; this.g = g; this.b = b; o = 255; } Color(float r, float g, float b, float o) { this.r = r; this.g = g; this.b = b; this.o = o; } void colorize() { fill(r, g, b, o); } } class MuzzleFlash { float x, y, w; Color col; MuzzleFlash() { col = new Color(0, 0, 255, 0); w = 0; } void draw() { col.colorize(); ellipse(x, y, w, w); rect(x, y - sh/2, w - 30, sh); } void update() { w += 5; col.o -= 10; } void create(float x, float y) { this.x = x; this.y = y; col.o = 255; w = 50; } } boolean sketchFullScreen() { return fullScreen; }