xxxxxxxxxx
461
let gif_loadImg;
let backgroundImageStart;
let backgroundImageInstructions;
let backgroundImageWaiting;
let backgroundImagePlaying;
let backgroundImageResult;
let startButton;
let playerImages = []; // Declare an array to store the player images
let me;
let guests;
let sharedBombId;
let moveSpeed = 5; // Speed at which players move
const names = [
"MICKEY",
"MINNIE",
"JERRY",
"REMY",
"PINKY",
"ALVIN",
"SIMON",
"THEODORE",
];
let stars = []; // Array to hold star objects
let score = 0; // Player's score
const numStars = 5; // Number of stars to generate
const WAITING_DURATION = 10 * 1000;
const PLAYING_DURATION = 30 * 1000;
const requiredNumberOfPlayers = 3;
const playerImageSize = { width: 80, height: 80 };
let sharedTimer;
let gameAlreadyReset = false;
function preload() {
partyConnect("wss://demoserver.p5party.org", "steferrnieWeek2");
let startX = random(0, 400);
let startY = random(0, 400);
let nameIndex = floor(random(names.length)); // Random index for name
let assignedName = names.splice(nameIndex, 1); // Assign and remove the name from the array
me = partyLoadMyShared({
x: startX,
y: startY,
id: random(1000000),
score: 0,
name: assignedName[0],
isReady: false,
});
guests = partyLoadGuestShareds();
sharedBombId = partyLoadShared("bombId", null);
sharedTimer = partyLoadShared("globals", {
gameState: "start",
startTime: Date.now(),
displayTime: null,
});
backgroundImageStart = loadImage("backgrounds/start.png");
backgroundImageInstructions = loadImage("backgrounds/instructions.png");
backgroundImageWaiting = loadImage("backgrounds/waiting.png");
backgroundImagePlaying = loadImage("backgrounds/playing.png");
backgroundImageResult = loadImage("backgrounds/result.png");
playerImages[0] = loadImage("players/player1.png");
playerImages[1] = loadImage("players/player2.png");
playerImages[2] = loadImage("players/player3.png");
gif_loadImg = loadImage("explosion.gif");
}
function setup() {
createCanvas(563, 750);
noStroke();
if (partyIsHost()) {
sharedBombId.value = me.id; // Host has the // Generate stars
}
for (let i = 0; i < numStars; i++) {
stars.push(createVector(random(width), random(height)));
}
}
function resetGame() {
me.score = 0; // Reset the score
stars = []; // Clear and repopulate the stars array
for (let i = 0; i < numStars; i++) {
stars.push(createVector(random(width), random(height)));
}
sharedTimer.gameState = "waiting"; // Set game state to waiting
gameAlreadyReset = true; // Mark game as reset
}
function draw() {
background("#F5F1EA");
manageTimer(); // Ensure the timer is managed correctly based on game state
// Check if the game has just transitioned to the waiting state
if (sharedTimer.gameState === "waiting" && !gameAlreadyReset) {
resetGame(); // Reset the game
gameAlreadyReset = true; // Mark the game as reset
} else if (sharedTimer.gameState !== "waiting") {
gameAlreadyReset = false; // Reset the flag when not in waiting state
}
switch (sharedTimer.gameState) {
case "start":
background(backgroundImageStart);
drawStartPage();
break;
case "instructions":
background(backgroundImageInstructions);
drawInstructionsPage();
break;
case "waiting":
background(backgroundImageWaiting);
drawWaitingPage();
break;
case "playing":
background(backgroundImagePlaying);
drawPlayingPage(); // Now handles both playing and waiting logic
break;
case "result":
background(backgroundImageResult);
drawResultPage(); // Handle the result display
break;
// Optionally, you could handle other states here if needed
}
}
function drawStartPage() {
background(backgroundImageStart);
}
function startGame() {
// Handle any setup or initialization logic before transitioning to the next game state
sharedTimer.gameState = "instructions"; // or any other initial state you want
startButton.hide(); // Remove the button once clicked
}
function drawInstructionsPage() {
fill(0);
}
function drawWaitingPage() {
// Handle player movement and interaction
handleMovementAndInteraction();
// Check if the game is in the playing state and waiting for more players
if (sharedTimer.gameState === "waiting") {
let requiredPlayers = 3;
let currentPlayers = guests.length; // Including 'me' in the count
if (currentPlayers < requiredPlayers) {
// Display waiting message
fill("#552B1C"); // Set the text color to #552B1C
textSize(22);
textAlign(CENTER, CENTER);
textFont("Avenir"); // Set the font to Avenir
textStyle(BOLD);
text(
"WAITING FOR " +
(requiredPlayers - currentPlayers) +
" MORE PLAYERS...",
width / 2,
height / 3 + 120
);
let gifWidth = 200; // Adjust the width as needed
let gifHeight = 200; // Adjust the height as needed
image(gif_loadImg, 190, 400, gifWidth, gifHeight);
} else if (currentPlayers >= requiredPlayers) {
// Corrected the comparison operator here
// Display ready message
fill("#552B1C"); // Set the text color to #552B1C
textSize(21);
textAlign(CENTER, CENTER);
textFont("Avenir"); // Set the font to Avenir
textStyle(BOLD);
text("YOUR PARTY IS READY CLICK TO START", width / 2, height / 3 + 120);
}
}
// Draw players and the bomb
drawPlayersAndBomb();
// explosion.draw(282, 450);
}
function drawPlayingPage() {
handleMovementAndInteraction(); // Handle player movement
// Draw and manage stars
for (let i = stars.length - 1; i >= 0; i--) {
fill(255, 255, 0); // Yellow color for stars
ellipse(stars[i].x, stars[i].y, 20, 20); // Draw star
// Check if player collects the star
if (dist(me.x, me.y, stars[i].x, stars[i].y) < 20) {
me.score++; // Increase score
stars.splice(i, 1); // Remove the collected star
stars.push(createVector(random(width), random(height))); // Add a new star
}
}
// Check if the game is in the playing state and waiting for more players
if (sharedTimer.gameState === "playing") {
let requiredPlayers = 3;
let currentPlayers = guests.length; // Including 'me' in the count
if (currentPlayers < requiredPlayers) {
// Transition back to waiting state
sharedTimer.gameState = "waiting";
sharedTimer.startTime = Date.now();
}
}
// Now, call the newly defined function to draw players and the bomb
drawPlayersAndBomb();
// Draw the countdown timer during gameplay
if (sharedTimer.displayTime !== null) {
fill("#FED087");
textSize(20);
textFont("Avenir"); // Set the font to Avenir
textStyle(BOLD);
textAlign(CENTER, CENTER);
text("TIME: " + sharedTimer.displayTime, width / 2, height - 20);
}
}
function handleMovementAndInteraction() {
// Arrow key controls for movement
if (keyIsDown(LEFT_ARROW)) {
me.x -= moveSpeed;
}
if (keyIsDown(RIGHT_ARROW)) {
me.x += moveSpeed;
}
if (keyIsDown(UP_ARROW)) {
me.y -= moveSpeed;
}
if (keyIsDown(DOWN_ARROW)) {
me.y += moveSpeed;
}
// Constrain player movement within the canvas boundaries
me.x = constrain(me.x, 0, width);
me.y = constrain(me.y, 0, height);
}
const BOMB_PASS_DISTANCE = 30; // The distance used for passing the bomb
function drawPlayersAndBomb() {
guests = partyLoadGuestShareds(); // Refresh the guest list
const textOffsetY = -55; // Distance above the player image for text
const bombOffsetY = -30; // Distance above the player image for the bomb
// Draw Bomb
function drawAdjustedBomb(x, y) {
drawBomb(x, y + bombOffsetY);
}
// Draw 'me' with adjusted positions for name, score, and bomb
let myImg = playerImages[0];
image(myImg, me.x - playerImageSize.width / 2, me.y - playerImageSize.height / 2, playerImageSize.width, playerImageSize.height);
fill("#000000");
textSize(11);
textAlign(CENTER, CENTER);
text(me.name + " " + me.score, me.x, me.y + textOffsetY);
if (me.id === sharedBombId.value) {
drawAdjustedBomb(me.x, me.y);
}
// Draw each guest with adjusted positions for name, score, and bomb
for (const guest of guests) {
let guestImgIndex = (guests.indexOf(guest) + 1) % playerImages.length;
let guestImg = playerImages[guestImgIndex];
image(guestImg, guest.x - playerImageSize.width / 2, guest.y - playerImageSize.height / 2, playerImageSize.width, playerImageSize.height);
fill("#000000");
textSize(11);
textAlign(CENTER, CENTER);
text(guest.name + " " + guest.score, guest.x, guest.y + textOffsetY);
if (guest.id === sharedBombId.value) {
drawAdjustedBomb(guest.x, guest.y);
}
}
// Check bomb passing if the player is 'me' and the current guest is not 'me'
if (me.id === sharedBombId.value) {
for (const guest of guests) {
if (guest.id !== me.id && dist(me.x, me.y, guest.x, guest.y) < BOMB_PASS_DISTANCE) {
console.log(`Passing bomb from ${me.id} to ${guest.id}`);
// Before changing the bomb owner, reduce the score of the receiver
guest.score -= 1; // Deduct score for receiving the bomb
sharedBombId.value = guest.id; // Pass the bomb to another player
break; // Exit the loop after passing the bomb
}
}
}
}
function checkAndStartGame() {
if (partyIsHost() && guests.length >= requiredNumberOfPlayers - 1) {
let playerIds = [me.id].concat(guests.map((guest) => guest.id));
let randomIndex = floor(random(playerIds.length));
sharedBombId.value = playerIds[randomIndex]; // Assign bomb to a random player
// Reduce the score of the initial bomb receiver
guests.forEach((guest) => {
if (guest.id === sharedBombId.value) guest.score -= 1;
});
if (me.id === sharedBombId.value) me.score -= 1; // Check if 'me' is the initial bomb receiver
guests.forEach((guest) => (guest.score = 0)); // Initialize scores to 0 for all guests
me.score = 0; // Initialize 'me' score to 0
sharedTimer.gameState = "playing";
sharedTimer.startTime = Date.now();
}
}
function drawBomb(x, y) {
fill("#000000");
ellipse(x, y, 25, 25); // Bomb representation
stroke("#000000");
strokeWeight(3);
let fuseEndX = x + 18;
let fuseEndY = y - 16;
line(x, y, fuseEndX, fuseEndY); // Fuse
// Spark flicker at the tip of the fuse
noStroke(); // No outline for the spark
fill("#F283E1");
let sparkSize = random(5, 7); // Random size for flicker effect
let sparkX = fuseEndX + random(-2, 2); // Slightly randomize the spark position for flicker effect
let sparkY = fuseEndY + random(-2, 2);
ellipse(sparkX, sparkY, sparkSize, sparkSize); // Draw the spark
noStroke(); // Ensure no stroke is set after drawing the bomb
}
function drawWaiting() {
fill(0);
textSize(20);
textAlign(CENTER, CENTER);
text("Waiting for players...", width / 2, height / 2);
image(gif_loadImg, 50, 50);
gif_createImg.position(50, 350);
resetGame();
}
function manageTimer() {
if (sharedTimer.gameState === "playing") {
const currentTime = Date.now();
const elapsed = currentTime - sharedTimer.startTime;
sharedTimer.displayTime = floor((PLAYING_DURATION - elapsed) / 1000);
if (elapsed >= PLAYING_DURATION) {
sharedTimer.gameState = "result";
sharedTimer.displayTime = null;
}
}
}
function drawResultPage() {
fill("#362418"); // Set the text color to #552B1C
textSize(24);
textAlign(CENTER, CENTER);
textFont("Avenir"); // Set the font to Avenir
textStyle(BOLD);
text("GAME OVER!", width / 2, 50); // Adjusted for better layout
// Calculate start Y position for listing scores
let startY = 90;
let spacingY = 20;
// Display score and name for 'me'
textSize(18);
let myFinalScore = me.id === sharedBombId.value ? 0 : me.score;
fill(me.id === sharedBombId.value ? "#F9C7B6" : "white");
text(`My Score: ${myFinalScore}`, width / 2, startY);
// Display scores and names for guests
guests.forEach((guest, index) => {
let guestFinalScore = guest.id === sharedBombId.value ? 0 : guest.score;
fill(guest.id === sharedBombId.value ? "#F9C7B6" : "#white");
text(
`${guest.name}: ${guestFinalScore}`,
width / 2,
startY + 15 + (index + 1) * spacingY
);
});
// Prompt to restart game
fill(0);
text("Click to play again!", width / 2, height - 30);
}
function mousePressed() {
switch (sharedTimer.gameState) {
case "start":
// Transition from the start state to the instructions state
sharedTimer.gameState = "instructions";
break;
case "instructions":
// Transition from the instructions state to the waiting state
sharedTimer.gameState = "waiting";
break;
case "waiting":
// Check if conditions are met to start the game (e.g., enough players)
// Directly transition to the playing state
sharedTimer.gameState = "playing";
sharedTimer.startTime = Date.now(); // Reset timer for game duration tracking
sharedTimer.displayTime = floor(PLAYING_DURATION / 1000) + 1; // Initialize display time if needed
break;
case "result":
// Transition from the result state back to the start or waiting state
sharedTimer.gameState = "start"; // Or "waiting" if you have a waiting state before the game officially starts
sharedTimer.startTime = Date.now();
sharedTimer.displayTime = null;
// Reset player positions and potentially reshuffle/reassign images here if needed
resetGame(); // Ensure this function resets positions, scores, etc., as needed
if (partyIsHost()) {
assignBombRandomly(); // Ensure bomb is reassigned for the new game
}
break;
// No default case needed
}
function resetPlayerPositionsAndImages() {
// Reset 'me'
let startX = random(0, 400);
let startY = random(0, 400);
me.x = startX;
me.y = startY;
me.score = 0;
// Optionally reshuffle or reassign 'me's image if that's part of your game logic
// Reset guests
guests.forEach(guest => {
guest.x = random(0, 400);
guest.y = random(0, 400);
guest.score = 0;
});
}
function assignBombRandomly() {
let playerIds = [me.id].concat(guests.map((guest) => guest.id));
let randomIndex = floor(random(playerIds.length));
sharedBombId.value = playerIds[randomIndex];
}
}