From 77504c8c9bd8a91a483103540011cd4d85d61b9d Mon Sep 17 00:00:00 2001 From: Miguel Manjarres <54128874+DevTony101@users.noreply.github.com> Date: Sun, 21 Nov 2021 18:06:04 -0500 Subject: [PATCH] Added difficulty mechanics --- sketch.js | 177 +++++++++++++++++++++++++++++++++++++++------------- src/ship.js | 40 +++++++----- 2 files changed, 157 insertions(+), 60 deletions(-) diff --git a/sketch.js b/sketch.js index 380aca1..8767411 100644 --- a/sketch.js +++ b/sketch.js @@ -1,24 +1,38 @@ -// begin parameters +// begin fixed parameters const numberOfStars = 200; -const numberOfInitialAsteroids = 2; -const asteroidsToAdd = 1; const starsMovement = 8; const bulletMovement = 8; -const initialLives = 5; const scoreIncrement = 100; const assetsFolder = "./assets"; const soundsFolder = `${assetsFolder}/sounds`; const imagesFolder = `${assetsFolder}/images`; const fontsFolder = `${assetsFolder}/fonts`; -// end parameters +// end fixed parameters -let ship, stars, asteroids; +// begin changeable parameters +let globalDifficulty = "EASY"; +let asteroidsToAdd = 1; +let numberOfInitialAsteroids = 2; +let initialLives = 5; +let scoreMultiplier = 1; +let gameOver = false; +let gameOverSfxPlayed = false; +let bulletsLimit = 5; +// end changeable parameters + +// begin assets variables let heartImage, gameOverImage; let shootEffect, explodeEffect, gameOverEffect; let psFont; +// end assets variables + +// GUI +let gui, easyButton, mediumButton, hardButton, buttons; + +// game variables +let ship, stars, asteroids; function preload() { - // begin assets // -- Images heartImage = loadImage(`${imagesFolder}/heart.png`); gameOverImage = loadImage(`${imagesFolder}/game_over.png`); @@ -28,47 +42,105 @@ function preload() { gameOverEffect = loadSound(`${soundsFolder}/game_over_sound.mp3`); // -- Fonts psFont = loadFont(`${fontsFolder}/PressStart2P-Regular.ttf`); - // end assets } function setup() { createCanvas(windowWidth, windowHeight); - ship = new Ship(parseInt(width / 2), height - 20, bulletMovement, initialLives); - ship.setShootSoundEffect(shootEffect); - ship.setHeartImage(heartImage); - ship.setScoreFont(psFont); - stars = new MovableObjects(0, starsMovement, numberOfStars); - asteroids = Array(numberOfInitialAsteroids) - .fill(0) - .map(_ => { - return new Asteroid(random(50, width - 50), random(10, 20)); + gui = createGui(); + easyButton = createButton("Restart Game [Easy]", (width / 2) - 375, (height / 2) + 100, 230, 40); + mediumButton = createButton("Restart Game [Medium]", (width / 2) - 125, (height / 2) + 100, 250, 40); + hardButton = createButton("Restart Game [Hard]", (width / 2) + 145, (height / 2) + 100, 230, 40); + buttons = [easyButton, mediumButton, hardButton]; + for (button of buttons) { + button.visible = false; + button.setStyle({ + strokeBg: color(255), + fillBg: color(0), + fillLabel: color(255), + fillBgActive: color(255), + fillLabelActive: color(0), + fillBgHover: color(255), + fillLabelHover: color(0) }); + } + restartGame("EASY"); } function mousePressed() { - if (ship.hasAnyHeartsLeft()) ship.shoot(); + if (!gameOver) ship.shoot(); } function keyPressed() { - if (ship.hasAnyHeartsLeft()) { - if (keyCode === 32) ship.shoot(); + if (!gameOver) { + if (keyCode === 32) ship.shoot(); // SPACE_BAR + else if (keyCode === 27) gameOver = true; // ESC_KEY } return false; } function draw() { background(0); + drawGui(); drawStars(); drawAsteroids(); + drawDifficulty(); ship.draw(mouseX); - if (!ship.hasAnyHeartsLeft()) { - image(gameOverImage, (width / 2) - 155, (height / 2) - 85, 310, 170, 0, 0); - gameOverEffect.setVolume(0.05); - gameOverEffect.play(); - noLoop(); + if (!ship.hasAnyHeartsLeft() || gameOver) { + asteroids = []; + if (!gameOver) gameOver = true; + image(gameOverImage, (width / 2) - 155, (height / 2) - 150, 310, 170, 0, 0); + if (!gameOverSfxPlayed) { + gameOverSfxPlayed = true; + gameOverEffect.setVolume(0.05); + gameOverEffect.play(); + } + buttons.forEach(button => button.visible = true); + if (easyButton.isPressed) restartGame("EASY"); + else if (mediumButton.isPressed) restartGame("MEDIUM"); + else if (hardButton.isPressed) restartGame("HARD"); + } +} + +function adjustParameters(difficulty) { + globalDifficulty = difficulty; + if (difficulty === "EASY") { + asteroidsToAdd = 1; + numberOfInitialAsteroids = 2; + initialLives = 5; + scoreMultiplier = 1; + bulletsLimit = 5; + } else if (difficulty === "MEDIUM") { + asteroidsToAdd = 2; + numberOfInitialAsteroids = 3; + initialLives = 5; + scoreMultiplier = 1.2; + bulletsLimit = 7; + } else if (difficulty === "HARD") { + asteroidsToAdd = 3; + numberOfInitialAsteroids = 5; + initialLives = 8; + scoreMultiplier = 1.5; + bulletsLimit = 9; } } +function restartGame(difficulty) { + adjustParameters(difficulty); + gameOver = false; + gameOverSfxPlayed = false; + ship = new Ship(parseInt(width / 2), height - 20, bulletMovement, initialLives, bulletsLimit); + ship.setShootSoundEffect(shootEffect); + ship.setHeartImage(heartImage); + ship.setScoreFont(psFont); + stars = new MovableObjects(0, starsMovement, numberOfStars); + buttons.forEach(button => button.visible = false); + asteroids = Array(numberOfInitialAsteroids) + .fill(0) + .map(_ => { + return new Asteroid(random(50, width - 50), random(10, 20)); + }); +} + function drawStars() { stars.move((x, y) => y > height, true); stars.draw((x, y) => { @@ -80,28 +152,43 @@ function drawStars() { } function drawAsteroids() { - if (frameCount % 50 === 0) { - for (let i = 0; i < asteroidsToAdd; i++) { - asteroids.push(new Asteroid(random(50, width - 50), random(10, 20))); - } - } - - for (let i = 0; i < asteroids.length; i++) { - const asteroid = asteroids[i]; - const idxBullet = asteroid.isHitBy(ship.getBullets()); - if (!asteroid.hasExploded() && asteroid.isOffsetY()) ship.decrementHearts(); - if (asteroid.isOffset()) { - asteroids.splice(i, 1); - continue; + if (!gameOver) { + if (frameCount % 50 === 0) { + for (let i = 0; i < asteroidsToAdd; i++) { + asteroids.push(new Asteroid(random(50, width - 50), random(10, 20))); + } } - - if (!asteroid.hasExploded() && idxBullet >= 0) { - ship.incrementScore(scoreIncrement); - asteroid.explode(explodeEffect); - ship.deleteBullet(idxBullet); + + for (let i = 0; i < asteroids.length; i++) { + const asteroid = asteroids[i]; + const idxBullet = asteroid.isHitBy(ship.getBullets()); + if (!asteroid.hasExploded() && asteroid.isOffsetY()) ship.decrementHearts(); + if (asteroid.isOffset()) { + asteroids.splice(i, 1); + continue; + } + + if (!asteroid.hasExploded() && idxBullet >= 0) { + ship.incrementScore(scoreIncrement * scoreMultiplier); + asteroid.explode(explodeEffect); + ship.deleteBullet(idxBullet); + } + + asteroid.move(); + asteroid.draw(); } + } +} - asteroid.move(); - asteroid.draw(); +function drawDifficulty() { + if (!gameOver) { + push(); + textFont(psFont); + textSize(12); + if (globalDifficulty === "EASY") fill(68, 161, 160); + else if(globalDifficulty === "MEDIUM") fill(238, 184, 104); + else if (globalDifficulty === "HARD") fill(250, 0, 63); + text(`Difficulty [${globalDifficulty}]`, 20, 130); + pop(); } } diff --git a/src/ship.js b/src/ship.js index b8d1603..08e2402 100644 --- a/src/ship.js +++ b/src/ship.js @@ -1,10 +1,11 @@ class Ship { - constructor(x, y, bulletMovement, initialHearts) { + constructor(x, y, bulletMovement, initialHearts, bulletsLimit) { this.x = x; this.y = y; - this.bullets = new MovableObjects(0, -bulletMovement); this.hearts = initialHearts; this.score = 0; + this.bullets = new MovableObjects(0, -bulletMovement); + this.bulletsLimit = bulletsLimit; } getBullets() { @@ -33,7 +34,7 @@ class Ship { } shoot() { - if (this.bullets.size() < 5) { + if (this.bullets.size() < this.bulletsLimit) { this.shootSoundEffect.play(); this.bullets.add({ x: mapXLimits(mouseX), @@ -55,18 +56,20 @@ class Ship { } draw(x) { - this.drawHearts(); - this.drawBullets(); this.drawScore(); - let translateX = mapXLimits(x); - push(); - translate(translateX, this.y); - rectMode(CENTER); - noStroke(); - fill(255); - rect(0, 0, 60, 20); - rect(0, -20, 20, 20); - pop(); + if (!gameOver) { + this.drawHearts(); + this.drawBullets(); + let translateX = mapXLimits(x); + push(); + translate(translateX, this.y); + rectMode(CENTER); + noStroke(); + fill(255); + rect(0, 0, 60, 20); + rect(0, -20, 20, 20); + pop(); + } } drawBullets() { @@ -92,7 +95,14 @@ class Ship { fill(255); textFont(this.scoreFont); textSize(15); - text(`Score: ${this.score}`, 20, 100); + if (!gameOver) { + text(`Score: ${this.score}`, 20, 100); + } else { + text("Final Score", (width / 2) - 80, 75); + if (this.score === 0) text(this.score, (width / 2) - 10, 110); + else if (this.score < 1000) text(this.score, (width / 2) - 20, 110); + else text(this.score, (width / 2) - 30, 110); + } pop(); } }