xxxxxxxxxx
452
// Global Variable
let backgroundImage;
let footballImage;
let mannequinImage;
let footballX, footballY;
let targetX, targetY;
let footballSpeed = 25;
let timer = 30;
let timerInterval;
let positions = [];
let mannequins = [];
let openPositionIndex;
let customFont;
let currentPage = "start";
let ballShot = false;
let ledActive = false;
let playerScored = false;
let score = 0; // Player's score
let missedShots = 0; // Missed attempts
let ledPositions = ["left", "middle", "right"];
let ledIndex; // Current target LED
let gameActive = false; // Indicates if the game is running
let buttonPressed = false; // Track if the button is already pressed
let writer = null; // Placeholder for serial writer object
let missSound; // Sound effect for missed shot
let scoreSound; // Sound effect for scored goal
let backgroundSounds = []; // Array to hold background sound tracks
let currentTrackIndex = 0; // Track the currently playing sound
let isMusicPlaying = true; // Track if the music is playing
// Preload Function
function preload() {
backgroundImage = loadImage("stadium.avif");
gameBackground = loadImage("field.jpg");
footballImage = loadImage("ball.png");
mannequinImage = loadImage("post.png");
customFont = loadFont("BowlbyOne-Regular.ttf");
missSound = loadSound("missSound.mp3");
scoreSound = loadSound("scoreSound.mp3");
// Load multiple background sounds
backgroundSounds.push(loadSound("backgroundSound.mp3"));
backgroundSounds.push(loadSound("backgroundSound2.mp3"));
backgroundSounds.push(loadSound("backgroundSound3.mp3"));
backgroundSounds.push(loadSound("backgroundSound4.mp3"));
backgroundSounds.push(loadSound("backgroundSound5.mp3"));
}
// Setup Function
function setup() {
createCanvas(windowWidth, windowHeight);
textFont(customFont);
calculatePositions();
randomizeMannequins();
resetBall();
backgroundSounds[currentTrackIndex].loop();
backgroundSounds[currentTrackIndex].setVolume(0.2); // Adjust volume
}
// Function to Shuffle Music
function shuffleMusic() {
// Stop the current track
backgroundSounds[currentTrackIndex].stop();
// Randomly pick a new track that is not the current one
let newTrackIndex = currentTrackIndex;
while (newTrackIndex === currentTrackIndex) {
newTrackIndex = floor(random(backgroundSounds.length));
}
// Update the track index and play the new track
currentTrackIndex = newTrackIndex;
backgroundSounds[currentTrackIndex].loop();
}
// Function to Toggle Play/Pause
function toggleMusic() {
if (isMusicPlaying) {
backgroundSounds[currentTrackIndex].pause(); // Pause the current track
isMusicPlaying = false;
} else {
backgroundSounds[currentTrackIndex].play(); // Play the current track
isMusicPlaying = true;
}
}
// Draw Function
function draw() {
if (currentPage === "start") {
drawStartPage();
} else if (currentPage === "instructions") {
drawInstructionsPage();
} else if (currentPage === "game") {
if (timer > 0) {
drawGamePage();
} else {
stopGame();
}
} else if (currentPage === "end") {
drawEndScreen();
}
drawMusicButtons();
}
// Function to Draw Music Buttons
function drawMusicButtons() {
fill(255, 255, 0, 200);
rect(10, height - 70, 150, 50, 10);
fill(0);
textAlign(CENTER, CENTER);
textSize(16);
text("Shuffle Music", 85, height - 45);
fill(255, 255, 0, 200);
rect(170, height - 70, 150, 50, 10);
fill(0);
text("Play/Pause", 245, height - 45);
}
function drawStartPage() {
image(backgroundImage, 0, 0, width, height);
fill(255, 0, 0, 200);
rect(width / 2 - 200, height / 4 - 40, 400, 90, 15);
fill(255);
textAlign(CENTER, CENTER);
textSize(64);
text("Goal Rush", width / 2, height / 4);
fill(255, 0, 0, 150);
rect(width / 2 - 150, height / 2 - 60, 300, 70, 15);
rect(width / 2 - 150, height / 2 + 60, 300, 70, 15);
fill(255);
textSize(36);
text("Instructions", width / 2, height / 2 - 25);
text("Start Game", width / 2, height / 2 + 95);
}
function drawInstructionsPage() {
image(gameBackground, 0, 0, width, height); // Use the same background as the main game
fill(0, 150); // Add a dark overlay for better text visibility
rect(0, 0, width, height);
fill(255);
textAlign(CENTER, TOP);
textSize(32);
text("How to Play", width / 2, 50);
textSize(24);
text(
"Press on (f) for the screen.\n\n" +
"Press on (space bar) to connect to the button.\n\n" +
"React quickly to the button's LED lighting up!\n\n" +
"Press the correct button to score.\n\n" +
"Miss or press the wrong button, and you lose the chance to score!",
width / 2,
150
);
// Back button
fill(255, 0, 0, 150);
rect(width / 2 - 100, height - 100, 200, 90, 10);
fill(255);
textSize(54);
text("Back", width / 2, height - 90);
}
// Game Page
function drawGamePage() {
image(gameBackground, 0, 0, width, height);
drawMannequins();
drawFootball();
moveFootball();
checkCollision();
fill(255, 0, 0, 150);
rect(width / 2 - 150, 10, 300, 60, 10);
fill(255);
textSize(28);
textAlign(CENTER, CENTER);
text(`Time Left: ${timer}s`, width / 2, 40);
text(`Score: ${score}`, width / 2, 80);
text(`Misses: ${missedShots}`, width / 2, 120);
}
// End Screen
function drawEndScreen() {
image(gameBackground, 0, 0, width, height);
fill(0, 150);
rect(0, 0, width, height);
fill(255);
textAlign(CENTER, CENTER);
textSize(64);
text("Game Over!", width / 2, height / 4);
textSize(36);
text(`Final Score: ${score}`, width / 2, height / 2 - 40);
text(`Misses: ${missedShots}`, width / 2, height / 2 + 20);
fill(255, 0, 0, 150);
rect(width / 2 - 150, height / 2 + 100, 300, 70, 15);
fill(255);
textSize(36);
text("Restart Game", width / 2, height / 2 + 135);
fill(255, 0, 0, 150);
rect(width / 2 - 150, height / 2 + 200, 300, 70, 15);
fill(255);
textSize(36);
text("Main Menu", width / 2, height / 2 + 235);
}
// Helper Functions
function calculatePositions() {
positions = [
{ x: width * 0.25, y: height * 0.55 },
{ x: width * 0.5, y: height * 0.55 },
{ x: width * 0.75, y: height * 0.55 },
];
}
function randomizeMannequins() {
let indexes = [0, 1, 2];
shuffle(indexes, true);
mannequins = [positions[indexes[0]], positions[indexes[1]]];
openPositionIndex = indexes[2];
targetX = positions[openPositionIndex].x;
targetY = positions[openPositionIndex].y;
}
function drawMannequins() {
for (let i = 0; i < mannequins.length; i++) {
image(
mannequinImage,
mannequins[i].x - 250,
mannequins[i].y - 150,
500,
400
);
}
}
function drawFootball() {
if (footballImage) {
image(footballImage, footballX, footballY, 50, 50);
}
}
function moveFootball() {
if (ballShot) {
let dx = targetX - footballX;
let dy = targetY - footballY;
let distance = dist(footballX, footballY, targetX, targetY);
if (distance > footballSpeed) {
footballX += (dx / distance) * footballSpeed;
footballY += (dy / distance) * footballSpeed;
} else {
ballShot = false;
setTimeout(() => {
randomizeMannequins();
resetBall();
}, 200);
}
}
}
function checkCollision() {
if (ballShot) {
let distance = dist(footballX, footballY, targetX, targetY);
if (distance < 25 && playerScored) {
console.log("Goal!");
} else if (distance < 25 && !playerScored) {
console.log("Missed! Wrong button.");
}
}
}
function resetBall() {
footballX = width / 2;
footballY = height + 100;
ballShot = false;
buttonPressed = false;
ledActive = false;
if (gameActive) sendLEDSignal();
}
function sendLEDSignal() {
if (!ledActive && !ballShot) {
ledActive = true;
ledIndex = openPositionIndex;
if (serialActive && writer) {
writer.write(`LED:${ledIndex}\n`);
console.log(`LED signal sent for position ${ledPositions[ledIndex]}`);
}
setTimeout(() => {
if (!buttonPressed) {
missedShots++;
let randomMannequinIndex = floor(random(mannequins.length));
targetX = mannequins[randomMannequinIndex].x;
targetY = mannequins[randomMannequinIndex].y;
console.log("Missed! Ball going to mannequin.");
ballShot = true; // Move the ball
moveFootball();
setTimeout(() => {
randomizeMannequins();
resetBall();
}, 200);
}
ledActive = false;
}, 700);
}
}
function readSerial(data) {
if (data != null && !buttonPressed) {
buttonPressed = true;
let trimmedData = trim(data);
if (trimmedData === "BUTTON:CORRECT") {
score++;
playerScored = true;
ballShot = true;
scoreSound.play();
targetX = positions[openPositionIndex].x;
targetY = positions[openPositionIndex].y;
moveFootball();
} else if (trimmedData === "BUTTON:WRONG") {
missedShots++;
playerScored = false;
ballShot = true;
// Redirect the ball to a mannequin's position
let randomMannequinIndex = floor(random(mannequins.length));
targetX = mannequins[randomMannequinIndex].x;
targetY = mannequins[randomMannequinIndex].y;
moveFootball();
}
}
}
// Game Control
function startGame() {
score = 0;
missedShots = 0;
timer = 30;
gameActive = true;
startTimer();
resetBall();
}
function startTimer() {
clearInterval(timerInterval);
timerInterval = setInterval(() => {
if (timer > 0) {
timer--;
} else {
clearInterval(timerInterval);
stopGame();
}
}, 1000);
}
function stopGame() {
gameActive = false;
currentPage = "end";
}
function mousePressed() {
if (currentPage === "start") {
if (
mouseX > width / 2 - 150 &&
mouseX < width / 2 + 150 &&
mouseY > height / 2 - 60 &&
mouseY < height / 2
) {
currentPage = "instructions";
} else if (
mouseX > width / 2 - 150 &&
mouseX < width / 2 + 150 &&
mouseY > height / 2 + 60 &&
mouseY < height / 2 + 130
) {
currentPage = "game";
startGame();
} else if (
mouseX > 10 &&
mouseX < 160 &&
mouseY > height - 70 &&
mouseY < height - 20
) {
shuffleMusic();
} else if (
mouseX > 170 &&
mouseX < 320 &&
mouseY > height - 70 &&
mouseY < height - 20
) {
toggleMusic(); // Call play/pause function
}
} else if (currentPage === "instructions") {
if (
mouseX > width / 2 - 100 &&
mouseX < width / 2 + 100 &&
mouseY > height - 100 &&
mouseY < height - 10
) {
currentPage = "start";
}
} else if (currentPage === "end") {
if (
mouseX > width / 2 - 150 &&
mouseX < width / 2 + 150 &&
mouseY > height / 2 + 100 &&
mouseY < height / 2 + 170
) {
currentPage = "game";
startGame(); // Restart the game
} else if (
mouseX > width / 2 - 150 &&
mouseX < width / 2 + 150 &&
mouseY > height / 2 + 200 &&
mouseY < height / 2 + 270
) {
currentPage = "start";
}
}
}
function keyPressed() {
if (key === " ") {
setUpSerial();
} else if (key === "f") {
toggleFullscreen();
}
}
function toggleFullscreen() {
let fs = fullscreen();
fullscreen(!fs);
resizeCanvas(windowWidth, windowHeight);
calculatePositions();
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
calculatePositions();
}