xxxxxxxxxx
462
let gridStartX;
let gridStartY;
let backgroundImage;
let instruction;
let sound;
let noSound;
let fishIcon;
let winningSound;
let playedWinningSound = false;
let losingSound;
let winningSign;
let losingSign;
let cols = 14;
let rows = 8;
let sandboxes = [];
let shells = [];
let fishes = [];
let sandboxWidth;
let sandboxHeight;
let padding = 5;
let stitch;
let stitchX, stitchY;
let pixelFont;
let initialX = 70;
let initialY = 105;
let huntTimerValue = 240; // 4 minutes in seconds
let isHuntTimerActive = false;
let showLosingSign = false;
let losingSignTimer = 0;
let losingSignDuration = 10;
let isMusicPlaying = true;
let myColor;
let timerValue = 10; // Initial 10-second timer
let canMove = false; // Stitch cannot move initially
let numShells = 6;
let shellPositions = [];
let fishPositions = [];
let shellCounter = 0;
let popwindow;
let showHowToPlay = false;
let hasPressedSpace = false;
function preload() {
backgroundImage = loadImage("background.jpg");
shellicon = loadImage("shell.jpeg");
noSound = loadImage("nomusic.png");
fishIcon = loadImage("fish.png");
stitch = loadImage("stitchpixel.png");
instruction = loadImage("instruct.png");
sound = loadImage("sound.png");
popwindow = loadImage("rules.png");
pixelFont = loadFont("PixelifySans.ttf");
music = loadSound("music.mp3");
winningSound = loadSound("win.mp3");
losingSound = loadSound("lost.mp3");
winningSign = loadImage("yoohoobutton.png");
losingSign = loadImage("sorrybutton.png");
}
function setup() {
createCanvas(800, 600);
pixelDensity(1);
music.loop();
imageMode(CENTER);
// SANDBOX GRID
let gridWidth = 630 - (cols - 1) * padding;
let gridHeight = 360 - (rows - 1) * padding;
sandboxWidth = gridWidth / cols;
sandboxHeight = gridHeight / rows;
gridStartX = width / 2 - 630 / 2 + 45;
gridStartY = height / 2 - 360 / 2;
stitchX = gridStartX - (sandboxWidth / 2 + padding + stitch.width);
stitchY = gridStartY - 15;
for (let i = 0; i < cols; i++) {
sandboxes[i] = [];
for (let j = 0; j < rows; j++) {
let x = gridStartX + i * (sandboxWidth + padding);
let y = gridStartY + j * (sandboxHeight + padding);
sandboxes[i][j] = new Sandbox(x, y, sandboxWidth, sandboxHeight);
shellPositions.push({ x, y });
fishPositions.push({ x, y });
}
}
generateShells();
generateFishes();
}
function draw() {
push();
//print(mouseX,mouseY);
imageMode(CORNER);
background(backgroundImage);
pop();
myColor = color(40, 91, 110);
// THE BACKGROUND RECTANGLE
rectMode(CENTER);
fill(246, 225, 169);
noStroke();
rect(width / 2, height / 2 - 25, 720, 420, 25, 25, 25, 25);
// THE BUTTONS
fill(myColor);
rect(width / 2 - 230, height / 2 + 210, 150, 40, 10, 10, 10, 10);
rect(width / 2 + 155, height / 2 + 210, 200, 40, 10, 10, 10, 10);
fill(255);
textFont(pixelFont);
textSize(20);
text("how to play", width / 2 - 290, height / 2 + 215);
text("shells collected: " + shellCounter, width / 2 + 70, height / 2 + 215);
if (isMusicPlaying) {
image(sound, 700, 510);
} else {
image(noSound, 700, 510);
}
// ICONS
sound.resize(35, 35);
noSound.resize(35, 35);
instruction.resize(35, 35);
image(instruction, 70, 510);
// MAIN TIMER (INITIAL TIMER)
if (timerValue > 0) {
fill(myColor);
text("0:" + (timerValue >= 10 ? timerValue : "0" + timerValue), 60, 435);
}
// HUNT TIMER (4 MINUTES) WITH "HUNT!" TEXT DISPLAY
if (timerValue === 0 && !isHuntTimerActive) {
isHuntTimerActive = true;
canMove = true;
}
if (isHuntTimerActive && huntTimerValue > 0) {
let minutes = floor(huntTimerValue / 60);
let seconds = huntTimerValue % 60;
fill(myColor);
text("hunt!", 55, 415);
text(minutes + ":" + (seconds < 10 ? "0" + seconds : seconds), 60, 435);
}
// Check if hunt timer has reached 0:00
if (isHuntTimerActive && huntTimerValue === 0) {
stitchX = initialX;
stitchY = initialY;
showLosingSign = true;
losingSignTimer = losingSignDuration;
isHuntTimerActive = false; // Stop the hunt timer
canMove = false; // Disable Stitch movement when timer hits 0
}
// CASE 1: Timer is still running, show fish above sandboxes
if (timerValue > 0) {
// Display sandboxes first
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
sandboxes[i][j].display();
}
}
// Display fish above sandboxes
for (let i = 0; i < fishes.length; i++) {
fishes[i].display();
checkFishCollision(fishes[i], i); // Ensure we still check fish collision
}
// Display shells
for (let i = 0; i < shells.length; i++) {
shells[i].display();
checkShellCollision(shells[i], i);
}
// CASE 2: Timer is 0, show fish behind sandboxes
} else {
// Display fish first (behind sandboxes)
for (let i = 0; i < fishes.length; i++) {
fishes[i].display(); // Fish drawn behind sandboxes
}
// Display sandboxes after fish (on top of fish)
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
sandboxes[i][j].display();
}
}
// Still check fish collisions even if they are drawn behind sandboxes
for (let i = 0; i < fishes.length; i++) {
checkFishCollision(fishes[i], i); // This keeps the collision detection active
}
// Display shells (above everything)
for (let i = 0; i < shells.length; i++) {
shells[i].display();
checkShellCollision(shells[i], i);
}
}
// STITCH CHARACTER MOVEMENT
if (canMove === true) {
// Stitch is visible and can move
stitch.resize(30, 30);
push();
imageMode(CORNER);
image(stitch, stitchX, stitchY, 30, 30);
pop();
} else {
// Stitch is visible but cannot move
stitch.resize(30, 30);
push();
imageMode(CORNER);
image(stitch, stitchX, stitchY, 30, 30);
pop();
}
let rectLeft = width / 2 - 720 / 2;
let rectRight = width / 2 + 720 / 2;
let rectTop = height / 2 - 420 / 2 - 40;
let rectBottom = height / 2 + 420 / 2 - 40;
stitchX = constrain(stitchX, rectLeft + 30, rectRight - 55);
stitchY = constrain(stitchY, rectTop + 55, rectBottom - 45);
// START & END ICONS //
textSize(15);
fill(myColor);
text("start", width / 2 - 290, height / 2 - 210);
text("end", width / 2 + 310, height / 2 + 175);
//POP-UP INSTRUCTIONS//
if (showHowToPlay) {
push();
imageMode(CORNER);
background(backgroundImage);
pop();
image(popwindow, width/2,height/2,630,420);
instruction.resize(35, 35);
image(instruction, 70, 510);
}
// DISPLAY LOSING SIGN //
if (showLosingSign) {
losingSign.resize(200, 100);
image(losingSign, width / 2, height / 2);
losingSignTimer--;
if (losingSignTimer <= 0) {
showLosingSign = false; // Hide losing sign after 10 seconds
}
}
checkWinCondition();
}
function keyPressed() {
if (key === ' ') {
generateShells(); // Generate new shells
generateFishes(); // Generate new fishes
shellCounter = 0; // Reset the shell counter
timerValue = 10; // Restart the initial 10-second timer
canMove = false; // Disable movement at the start of the 10-second timer
playedWinningSound = false; // Reset the flag so winning sound can play again
}
if (canMove) {
if (keyCode === UP_ARROW) {
stitchY -= sandboxHeight + padding;
} else if (keyCode === DOWN_ARROW) {
stitchY += sandboxHeight + padding;
} else if (keyCode === LEFT_ARROW) {
stitchX -= sandboxWidth + padding;
} else if (keyCode === RIGHT_ARROW) {
stitchX += sandboxWidth + padding;
}
}
}
// TIMERS
setInterval(timeIt, 1000);
function timeIt() {
if (timerValue > 0) {
timerValue--;
canMove = false; // Disable movement while the 10-second timer is running
}
if (timerValue === 0 && !isHuntTimerActive) {
isHuntTimerActive = true;
canMove = true; // Allow movement once the 10-second timer expires
}
if (isHuntTimerActive && huntTimerValue > 0) {
huntTimerValue--; // Decrement hunt timer once active
}
}
// SHELL RANDOM GENERATION //
function generateShells() {
shells = [];
let shuffledPositions = shuffle(shellPositions);
for (let i = 0; i < numShells; i++) {
let pos = shuffledPositions[i];
// Ensure the shell is not placed in the same position as any fish
let isOverlappingWithFish = fishes.some(fish => dist(pos.x, pos.y, fish.x, fish.y) < (sandboxWidth + padding));
if (!isOverlappingWithFish) {
shells.push(new Shell(pos.x, pos.y, sandboxWidth, sandboxHeight, shellicon));
} else {
// Try another position if there is overlap
i--;
}
}
}
// FISH BONE RANDOM GENERATION //
function generateFishes() {
fishes = [];
let shuffledPositions = shuffle(fishPositions);
for (let i = 0; i < 6; i++) {
let pos = shuffledPositions[i];
// Ensure the fish is not placed in the same position as any shell
let isOverlappingWithShell = shells.some(shell => dist(pos.x, pos.y, shell.x, shell.y) < (sandboxWidth + padding));
if (!isOverlappingWithShell) {
fishes.push(new Fish(pos.x, pos.y, sandboxWidth, sandboxHeight, fishIcon));
} else {
// Try another position if there is overlap
i--;
}
}
}
// COLLECTING & COUNTING THE SHELLS //
function checkShellCollision(shell, index) {
let d = dist(stitchX, stitchY, shell.x, shell.y);
if (d < 30 && !shell.isCollected) {
shell.isCollected = true;
shellCounter++;
}
}
function checkFishCollision(fish, index) {
let d = dist(stitchX, stitchY, fish.x, fish.y);
if (d < 30) {
losingSound.play();
stitchX = initialX;
stitchY = initialY;
playedWinningSound = false;
}
shellCounter = 0; // Reset the shell counter
generateShells(); // Generate new shells
generateFishes(); // Generate new fishes
}
function mousePressed() {
if (mouseX > 50 && mouseX < 245 && mouseY > 492 && mouseY < 530) {
showHowToPlay = !showHowToPlay;
}
if (mouseX > 680 && mouseX < 715 && mouseY > 500 && mouseY < 530) {
if (isMusicPlaying) {
music.pause();
} else {
music.loop();
}
isMusicPlaying = !isMusicPlaying;
}
}
function keyPressed() {
if (key === ' ') {
stitchX = initialX;
stitchY = initialY;
// Reset the 10-second timer
timerValue = 10; // Restart the 10-second timer
isHuntTimerActive = false; // Stop the hunt timer (4-minute one)
huntTimerValue = 240; // Reset the 4-minute timer value
shellCounter = 0; // Reset the shell counter
generateShells(); // Generate new shells
generateFishes(); // Generate new fishes
playedWinningSound = false;
}
if (canMove) {
if (keyCode === UP_ARROW) {
stitchY -= sandboxHeight + padding;
} else if (keyCode === DOWN_ARROW) {
stitchY += sandboxHeight + padding;
} else if (keyCode === LEFT_ARROW) {
stitchX -= sandboxWidth + padding;
} else if (keyCode === RIGHT_ARROW) {
stitchX += sandboxWidth + padding;
}
}
}
function checkWinCondition() {
// Check if the shellCounter is equal to 6 (all shells collected)
if (shellCounter === 6) {
// Check if Stitch is within the rectangle (x: 700 to 740, y: 100 to 460)
if (stitchX > 700 && stitchX < 740 && stitchY > 100 && stitchY < 460) {
// Play the winning sound only once
if (!playedWinningSound) {
winningSound.play(); // Play the winning sound
playedWinningSound = true; // Set the flag to prevent further sound playback
}
// Ensure the winning sign is drawn on top of everything else
push();
imageMode(CENTER);
winningSign.resize(200, 100); // Resize the winning sign image
image(winningSign, width / 2, height / 2); // Display the winning sign at the center of the canvas
pop();
}
}
}
class Shell {
constructor(x, y, w, h, shellicon) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.img = shellicon;
this.isCollected = false;
}
display() {
if (!this.isCollected) { // Only display if not collected
image(this.img, this.x, this.y, this.w, this.h);
}
}
}
class Fish {
constructor(x, y, w, h, fishicon) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.img = fishicon;
}
display() {
image(this.img, this.x, this.y, this.w, this.h);
}
}