/*////////////////////////////////////////////////////////////////
** Fire The Cannons by Paul Williams
** Interactive Toy Assignement
** Shoot your Ships cannon to destroy boats and those pesky birds
** Aim the cannon with UP and Down arrow keys and click to fire
/*////////////////////////////////////////////////////////////////
//Counting variable used to move the waves.
float moveWaves = 0;
//Variables for the boats movement.
float boatPositionX = 0;
float boatPositionY = 0;
float boatBob= 0.3;
//Variables for the ducks movement.
float birdPositionX = 100;
float birdPositionY = 0;
float birdBob = 0.5;
//Variables for Effects
boolean boatExplode = false;
boolean birdExplode = false;
boolean waterSplash1 = false;
boolean waterSplash2 = false;
float effectLength = 0;
//Variables for the cannon's fuse
boolean fuseLit = false;
float fuseHeight = 290;
float fuseBurned = 0;
//Variables for Cannon
float cannonBack = 360;
float cannonAngle = 70;
float cannonAngleValue = 1;
float cannonEnd = 50;
//Variables for Cannonballs.
boolean cannonballFired = false;
float defaultCannonballSize = 50;
float cannonballSize;
float defaultCannonballPosition = 350;
float cannonballPosition;
float shotSpeed=10;
float shotGravity=0;
//Setup the Scene
void setup() {
frameRate(60);
size(400, 400);
smooth();
rectMode(CORNERS);
}
//Repeat these actions.
void draw() {
////////////////////////////////////
// DRAW
////////////////////////////////////
// clear background
background(175, 226, 239);
drawWave(moveWaves, 1);
drawBoat();
drawWave(moveWaves, 2);
drawWave(moveWaves, 3);
drawBird();
//Draw an effect if it's triggered
if (boatExplode) {
drawBoatExplode();
}
if (birdExplode) {
drawBirdExplode();
}
if (waterSplash1) {
drawWaterSplash1();
}
if (waterSplash2) {
drawWaterSplash2();
}
drawPirateShip();
drawCannonBalls();
drawCannon();
// update wave position
updateWavePosition();
}
////////////////////////////////////
// WAVE FUNCTIONS
////////////////////////////////////
// Creates a moving wave using colours, speeds, and lengths decided by the layer you input
void drawWave(float moveWaves, float layer) {
float waveDrawingPositionX = -100 * layer;
// selecting colour based on layer input
if (layer == 1) {
stroke(10, 20, 150);
}
if (layer == 2) {
stroke(0, 25, 200);
}
if (layer == 3) {
stroke(63, 75, 239);
}
// Creating the waves using many rectangles and the sin fuction. Moves with the moveWaves variable multiplied by the layer to increase its speed
while (waveDrawingPositionX < width) {
rect(waveDrawingPositionX + moveWaves * layer, height/1.4, waveDrawingPositionX + 5 + moveWaves * layer, height/1.5-sin(waveDrawingPositionX/(10*layer))*(6 + 3*layer)-(100 - (20 * layer)));
waveDrawingPositionX += 1;
}
}
// Updates the waves current positions.
void updateWavePosition() {
moveWaves += 1;
if (moveWaves > 62) {
moveWaves = 0;
}
}
////////////////////////////////////
// TARGET FUNCTIONS
////////////////////////////////////
// Drawing the boat
void drawBoat() {
stroke(0);
fill(150, 20, 20);
rect(boatPositionX + 10, height/2.1 + boatPositionY, boatPositionX + 60, height/2.4 + boatPositionY);
fill (150);
rect(boatPositionX + 20, height/2.4 + boatPositionY, boatPositionX + 35, height/2.8 + boatPositionY);
quad(boatPositionX - 10, height/1.8 + boatPositionY, boatPositionX- 10, height/2.1 + boatPositionY, boatPositionX + 100, height/2.1 + boatPositionY, boatPositionX + 80, height/1.8 + boatPositionY);
// Updating the boats X position
boatPositionX += 1.2;
if (boatPositionX > width + 200) {
boatPositionX = -100;
}
// Updating the boats Y position
boatPositionY += boatBob;
if (boatPositionY > 5 || boatPositionY< -5) {
boatBob *= -1;
}
}
// Drawing the bird
void drawBird() {
noStroke();
fill(200, 200, 0);
triangle(birdPositionX - 26, height/8 + birdPositionY+ 4, birdPositionX - 16, height/8 + birdPositionY + 4, birdPositionX - 16, height/8 + birdPositionY - 3);
fill(255, 128, 0);
rect(birdPositionX + 6, height/8 + birdPositionY - 1, birdPositionX + 16, height/8 + birdPositionY + 4);
fill (255);
ellipse(birdPositionX, height/8 + birdPositionY, 22, 15);
fill(50, 200, 20);
ellipse(birdPositionX - 14, height/8 + birdPositionY, 10, 10);
fill(100, 50, 0);
quad(birdPositionX-5, height/8 + birdPositionY, birdPositionX + 5, height/8 + birdPositionY, birdPositionX + 5, height/8 - birdPositionY *2, birdPositionX -5, height/8 - birdPositionY *2);
// Updating the birds X position
birdPositionX -= 2;
if (birdPositionX < -100) {
birdPositionX = width + 100;
}
// Updating the birds Y position
birdPositionY += birdBob;
if (birdPositionY > 5 || birdPositionY< -5) {
birdBob *= -1;
}
}
////////////////////////////////////
// EFFECT FUNCTIONS
////////////////////////////////////
// Draws the effect that plays when the Boat gets hit.
void drawBoatExplode() {
fill(255, 0, 0);
rect(width/2 - effectLength*2 + 5, height/2 - effectLength*2 + 5, width/2 + effectLength*2 - 5, height/2 + effectLength*2 - 5);
fill(255, 255, 0);
quad(width/2 - effectLength*2, height/2, width/2, height/2 - effectLength*2, width/2 + effectLength*2, height/2, width/2, height/2 + effectLength*2);
updateEffect();
}
// Draws the effect that plays when the bird gets hit.
void drawBirdExplode() {
fill(255, 0, 0);
rect(width/2 - effectLength + 5, height/8 - effectLength + 5, width/2 + effectLength - 5, height/8 + effectLength - 5);
fill(255, 255, 0);
quad(width/2 - effectLength, height/8, width/2, height/8 - effectLength, width/2 + effectLength, height/8, width/2, height/8 + effectLength);
updateEffect();
}
// Draws the effect that plays when you shoot the cannon with the cannon aimed at position 1.
void drawWaterSplash1() {
fill(70, 85, 255);
ellipse(width/2, height/1.8, effectLength + 10, effectLength + 10);
fill(180, 180, 255);
ellipse(width/2, height/1.8, random(15), random(15));
updateEffect();
}
// Draws the effect that plays when you shoot the cannon with the cannon aimed at position 2 and miss the boat.
void drawWaterSplash2() {
fill(70, 75, 255);
ellipse(width/2, height/2, effectLength + 5, effectLength + 5);
fill(180, 180, 255);
ellipse(width/2, height/2, random(10), random(10));
updateEffect();
}
// Updates the effects and stops them after 20 frames.
void updateEffect() {
effectLength++;
if (effectLength >= 20) {
effectLength = 0;
boatExplode = false;
birdExplode = false;
waterSplash1 = false;
waterSplash2 = false;
}
}
////////////////////////////////////
// PLAYER'S SHIP FUNCTIONS
////////////////////////////////////
// draws the ship which the cannon is placed on
void drawPirateShip() {
stroke(0);
fill(100, 50, 0);
rect(0, height/1.6, width/2 -40, height/1.2);
rect(width, height/1.6, width/2 +40, height/1.2);
rect(width/2-40, height/1.4, width/2+40, height);
rect(0, height/1.2, width, height/1.1);
rect(0, height/1.1, width, height);
fill(63, 75, 239);
rect(-15, height/1.5, 5, height/1.2);
rect(30, height/1.5, 50, height/1.2);
rect(75, height/1.5, 95, height/1.2);
rect(120, height/1.5, 140, height/1.2);
rect(395, height/1.5, 410, height/1.2);
rect(350, height/1.5, 370, height/1.2);
rect(305, height/1.5, 325, height/1.2);
rect(260, height/1.5, 280, height/1.2);
noStroke();
}
// Draws every part of the cannon
void drawCannon() {
// the barrel
noStroke();
fill(40);
ellipse(width/2, height/1.2-cannonAngle, 60, cannonEnd);
quad(width/2+50, height/1.2, width/2 + 30, height/1.2 - cannonAngle, width/2 - 30, height/1.2 - cannonAngle, width/2 - 50, height/1.2);
ellipse(width/2, height/1.2, 100, 100);
// The end piece
stroke(0);
ellipse(width/2, cannonBack, 40, 40);
// The hole for the fuse
fill(0);
ellipse(width/2, fuseHeight+30, 15, 15);
// The wheels on the side
fill(150, 80, 20);
rect(width/2-50, height/1.03, width/2-70, height/1.45);
rect(width/2+50, height/1.03, width/2+70, height/1.45);
// The fuse
noStroke();
rect(width/2 + 5, fuseHeight + 30, width/2 - 5, fuseHeight + fuseBurned);
// Checks to see if the fuse is burning and if it is sets up the fire and shortens the length of the fuse
if (fuseLit) {
fuseBurned ++;
if (fuseBurned < 30) {
fill(255, 255, 0, 150);
triangle(width/2 - 5, fuseHeight+fuseBurned, width/2 + 5, fuseHeight+fuseBurned, width/2 + random(-10, 10), fuseHeight + fuseBurned - 15);
fill(255, 0, 0, 150);
triangle(width/2 - 5, fuseHeight+fuseBurned, width/2 + 5, fuseHeight+fuseBurned, width/2 + random(-10, 10), fuseHeight + fuseBurned - 25);
fill(255, 140, 0, 150);
triangle(width/2 - 5, fuseHeight+fuseBurned, width/2 + 5, fuseHeight+fuseBurned, width/2 + random(-10, 10), fuseHeight + fuseBurned - 25);
}
// Constrains the fuse from going into negatives
if (fuseBurned >=30) {
fuseBurned = 30;
}
}
}
// draws the cannon balls beside the cannon and the cannon ball that fires
void drawCannonBalls() {
stroke(0);
fill(20);
ellipse(325, 335, 42, 42);
ellipse(300, 350, 45, 45);
ellipse(340, 360, 46, 46);
// if the fuse is fully burned the cannonball is now fired
if (fuseBurned == 30) {
cannonballFired = true;
}
// what happens when the cannonball is fired
if (cannonballFired) {
ellipse(width/2, cannonballPosition, cannonballSize, cannonballSize);
// adjusting the height of and size of the cannonball as it flies
cannonballPosition -= shotSpeed - shotGravity;
shotGravity += 0.25;
cannonballSize -= 0.7;
// if the cannonball reaches 0 size the shot is complete. Check for collision and reset the fuse
if (cannonballSize <= 0) {
cannonballFired = false;
fuseLit = false;
fuseBurned = 0;
collisionCheck();
}
}
}
////////////////////////////////////
// EVENT FUNCTIONS
////////////////////////////////////
// Checks if a cannonball has been fired. If not you may change the cannons angle with the assigned keys
void keyPressed() {
if (!cannonballFired) {
updateCannonAngle();
}
}
// If you havn't already lit the fuse then clicking will light it and reset the defaults of the cannonball
void mouseClicked() {
if (!fuseLit) {
fuseLit = true;
cannonballPosition = defaultCannonballPosition;
shotGravity= 0;
cannonballSize = defaultCannonballSize;
}
}
// Updates all of the variables for the cannon to change its angle
void updateCannonAngle() {
// Constraining cannons angle when trying to increase it
if (cannonAngle < 120) {
if (keyCode == UP) {
cannonAngle += 20;
cannonEnd -= 10;
cannonAngleValue++;
cannonBack +=10;
shotSpeed += 1;
fuseHeight +=10;
}
}
// Constraining the cannons angle when trying to decrease it
if (cannonAngle > 70) {
if (keyCode == DOWN) {
cannonAngle -= 20;
cannonEnd += 10;
cannonAngleValue--;
cannonBack -= 10;
shotSpeed -=1;
fuseHeight -= 10;
}
}
}
// Checks if the cannonball hit anything by looking at locations of the boat and bird, and the angle values it's firing at
void collisionCheck() {
// Checking if bird was hit if the cannon was at angle value 4
if (cannonAngleValue == 4 && birdPositionX > width/2 - 20 && birdPositionX < width/2 + 20) {
birdPositionX = 900;
birdExplode = true;
}
// Checking if boat was hit if the cannon was at angle value 2
if (cannonAngleValue == 2) {
if (boatPositionX > width/2 - 90 && boatPositionX < width/2 + 10) {
boatPositionX = -600;
boatExplode = true;
}
// The boat was missed, playing the splash effect instead
else {
waterSplash2 = true;
}
}
// Player the splash effect for aiming too low
if (cannonAngleValue == 1) {
waterSplash1 = true;
}
}