xxxxxxxxxx
325
// Defining variables
let x1; // X-Position of first background image
let x2; // X-Position of second (of the same) background image
let scrollSpeed = 2; // Background scroll speed
// Character
let character; // Influencer Madison
let charX, charY; // Madison's X & Y position
let charSpeed = 3; // Madison's speed
let lives = 3; // Number of lives each player has
// Obstacles
let obstacles = []; // Array to store obstacles
let obstacleImages = []; // Array to store images of different NYC obstacle
// Background Images
let menuBG; // Background image of main menu
let tutorialBG; // Background image of tutorial
let gameBG; // Background image of actual game (cityview)
let gameOverBG; // Background image if player loses
let youWinBG; // Background image if player wins
// Game status
let gameState = "menu"; //'menu,''game,''tutorial,' or 'end'
let wonGame = false; // If player has won
// Music
let song; // Game background music
let songDuration = 94; // Duration of the song in seconds
let timeLeft = songDuration; // Time left in the song
let songStarted = false; // If song has started
let mainMusic; // Main Menu & Tutorial music
let wonMusic; // Music for wins
let lostMusic; // Music for losses
function preload() {
// Preloading background images
menuBG = loadImage("menubg.jpg"); // Background image for main menu
tutorialBG = loadImage('tutorial.png'); // Background image for tutorial page
gameBG = loadImage("citybg.jpeg"); // Background image of game
gameOverBG = loadImage('lost.jpg'); // Background image of Game Over
youWinBG = loadImage ('won.jpg'); // Background image of You Won!
character = loadImage('Madison.PNG'); // Influencer Madison herself
//preloading obstacle images
obstacleImages.push(loadImage('crackhead.png'));
obstacleImages.push(loadImage('garbage.png'));
obstacleImages.push(loadImage('rat.png'));
// Preloading music/sounds
song = loadSound("Ratatouille Chase Soundtrack.mp3");
mainMusic = loadSound('mainmenu.mp3');
wonMusic = loadSound('youwon.mp3');
lostMusic = loadSound('youlost.mp3');
// Preloading fonts
titleFont = loadFont("Bomber Dreams.ttf"); // Font of title on main menu
menuFont = loadFont("Street Hipster.ttf"); // Font of main menu buttons (start & tutorial)
tutorialFont = loadFont("Melody Break Demo.ttf"); // Font of actual tutorial heading
tutorialTextFont = loadFont("Sen.ttf"); // Font of instructions under tutorial
gameFont = loadFont('Happy Chicken.ttf'); // Font of lives & time in game
}
function setup() {
createCanvas(600, 400); // Canvas size
x1 = 0;
x2 = width;
charX = 40; // Madison x-position
charY = width / 2; // Madison y-position
restartGame();
// Spawn a new obstacle every 1 second
setInterval(() => {
obstacles.push(new Obstacle());
}, 1000);
}
function restartGame(){
obstacles = []; // Clear obstacles
wonGame = false;
gameState = 'menu'; // Restart by bringing back to main menu
stopAllMusic(); // Stop all music on restart
}
// Stopping music if called
function stopAllMusic() {
mainMusic.stop();
song.stop();
wonMusic.stop();
lostMusic.stop();
}
function draw() {
background(255); // Default background color if no background image is uploaded
print(mouseX, mouseY);
// State of the game
if (gameState === 'menu') {
displayMenu();
playMainMusic(); // Play main menu music
} else if (gameState === 'tutorial') {
displayTutorial();
playMainMusic(); // Play main menu music
} else if (gameState === 'game') {
displayGame();
manageGameMusic(); // Manage game music
} else if (gameState === 'end') {
displayEnd();
manageEndMusic(); // Manage end game music
lives = 3;
}
}
function playMainMusic() {
if (!mainMusic.isPlaying()) {
mainMusic.loop(); // Loop main menu music if it's not playing
}
}
function manageGameMusic() {
if (!song.isPlaying()) {
song.loop();
stopAllMusicExcept(song); // Loop game music, stop any other songs
}
}
function manageEndMusic() {
if (wonGame) {
if (!wonMusic.isPlaying()) {
wonMusic.play();
stopAllMusicExcept(wonMusic); // Play winner music, stop any other songs
}
} else {
if (!lostMusic.isPlaying()) {
lostMusic.play();
stopAllMusicExcept(lostMusic);// Play loser music, stop any other songs
}
}
}
// Stopping music besides current song in use for screen
function stopAllMusicExcept(current) {
if (current !== mainMusic) mainMusic.stop();
if (current !== song) song.stop();
if (current !== wonMusic) wonMusic.stop();
if (current !== lostMusic) lostMusic.stop();
}
// Visuals and text of main menu
function displayMenu() {
image(menuBG, 0, 0, width, height); // Background image
textFont(titleFont);
textSize(50);
fill(221, 220, 217);
stroke(0);
strokeWeight(7);
textAlign(CENTER, CENTER);
text('Escape From New York', width / 2, height / 4 + 63);
textFont(menuFont);
fill(221, 220, 217);
textStyle(BOLD);
textSize(30);
strokeWeight(5);
text('Click to Start', width / 2, height / 2 + 77);
text('Click for Tutorial', width / 2, height / 2 + 123);
}
// Visuals and text if user clicks on the tutorial
function displayTutorial() {
image(tutorialBG, 0, 0, width, height); // Display tutorial background
textFont(tutorialFont);
textSize(40);
fill(242, 70, 194);
textAlign(CENTER,CENTER);
strokeWeight(7);
text('Tutorial', width / 2, height / 4 - 47);
fill(242, 70, 194); // color for the point
strokeWeight(10);
// Two points as shapes for the project; shapes make up the colon
point( width / 2 + 73, height / 4 - 51); // Position of the point
point(width / 2 + 73, height / 4 -37); // Position of the second point
strokeWeight(4);
textFont(tutorialTextFont);
textSize(20);
textAlign(CENTER,CENTER);
text('Social media influencer Madison just moved from suburban', width / 2, height / 4 + 20);
text('Mississipi to the romanticized New York City, where she', width / 2, height / 4 + 50);
text('is met with NYC obstacles', width / 2, height / 4 + 80);
text('Help her drive around the city and avoid', width / 2, height / 4 + 130);
text(' the obstacles to get her back out of here!!!', width / 2, height / 4 + 160);
textSize(17);
text('Click anywhere to return to the menu', width / 2, height / 4 + 240);
}
// Function for the actual game
function displayGame() {
// If the time is up and there are over 0 lives, go to winner game ending
if (timeLeft <= 0) {
wonGame = (lives > 0);
gameState = 'end'; // Move to end state
}
// Moving background of game
image(gameBG, x1, 0, width, height);
image(gameBG, x2, 0, width, height);
let charProportion = character.width / character.height; // Character aspect ratio
// print (charProportion);
let charHeight = 85; // Character height
let charWidth = charHeight * charProportion; // Character width based on aspect ratio
x1 -= scrollSpeed;
x2 -= scrollSpeed;
// Loop background image
if (x1 < -width) {
x1 = x2 + width; // Reset x1 position
}
if (x2 < -width) {
x2 = x1 + width; // Reset x2 position
}
// Display the character and update position
image(character, charX, charY, charWidth, charHeight); // Draws Madison
// Constrain character's Y position to the range [200, height]
charY = constrain(charY, 175, height - charHeight);
// Constrain character's X position to the range [0, width]
charX = constrain(charX, 0, width - charWidth);
// Check for key presses and move the character accordingly
if (keyIsDown(UP_ARROW)) {
charY -= charSpeed;
}
if (keyIsDown(DOWN_ARROW)) {
charY += charSpeed;
}
if (keyIsDown(LEFT_ARROW)) {
charX -= charSpeed;
}
if (keyIsDown(RIGHT_ARROW)) {
charX += charSpeed;
}
// Creating obstacles
for (let i = obstacles.length - 1; i >= 0; i--) { // Loops through obstacle array
obstacles[i].move(); // Updates position of obstacle
obstacles[i].display(); // Draws obstacle
// Check for collision between the character and the roadblock
if (obstacles[i].collidesWith(charX, charY, charWidth, charHeight)) { // If the dimensions of the obstacle collides with the dimesions of Madison...
lives--; // Reduce lives if collision occurs
obstacles.splice(i, 1); // Remove the obstacle after collision
if (lives <= 0) {
gameState = 'end'; // End the game if no lives left
}
}
}
// Text in game screen counting number of lives left
textAlign(LEFT, TOP);
textFont(gameFont);
textSize(20);
text('Lives: ' + lives, 18, height / 4 - 90);
// Amount of time left (how much time is left in the game song, reverse of how many seconds of the song has passed)
timeLeft = songDuration - song.currentTime();
let minutes = Math.floor(timeLeft / 60); // Minutes rounded down to the nearest whole number
let seconds = Math.floor(timeLeft % 60); // Seconds rounded down
let timeString = nf(minutes, 2) + ":" + nf(seconds, 2);
textAlign(RIGHT, TOP); // Minutes and seconds will be displayed as two digits
text('Time: ' + timeString, width - 20, height / 4 - 90); // Display time in MM:SS
}
// Game ending screens
function displayEnd(){
// If user won
if (wonGame) {
image(youWinBG, 0, 0, width, height);
textAlign(CENTER, CENTER);
fill(255);
textSize(20);
text('Click Anywhere to Restart', width / 2, height / 4 + 238);
} else {
// If user lost
image(gameOverBG, 0, 0, width, height);
textAlign(CENTER, CENTER);
fill(255);
textSize(20);
text('Click Anywhere to Restart', width / 2, height / 4 + 238);
}
}
// Mouse click functions
function mousePressed() {
if (gameState === 'menu') {
// Click to start
if (mouseY > height / 2 + 60 && mouseY < height / 2 + 90) {
gameState = 'game';
}
// Click for tutorial
else if (mouseY > height / 2 + 100 && mouseY < height / 2 + 140) {
gameState = 'tutorial';
}
} else if (gameState === 'tutorial') {
gameState = 'menu'; // Return to menu
}
else if (gameState === 'end'){
restartGame(); // End and restart the game if clicked on
}
}