xxxxxxxxxx
469
// sketch.js
// Game State Variables
let gameStarted = false;
let backgroundImage;
let howToPlayButton, mythologyButton, connectButton;
let page = "start";
let startMusic, gameMusic, tigerRoar;
let timer = 30; // Timer set for 30 seconds
let countdown = timer;
let timerStart = false;
let gameOver = false;
let gameResult = "";
// Typewriter effect variables
let typewriterText = "Press the button to start your adventure!";
let currentText = ""; // Current text being displayed for typewriter effect
let textIndex = 0; // Index to keep track of the character being typed
let typewriterSpeed = 50; // Speed of the typewriter effect (in milliseconds)
// Variables for game elements
let player;
let tiger;
let playerImage, tigerImage; // Images for player and tiger
// Variables for running simulation
let playerSpeedValue = 0; // Player's current speed
let basePlayerSpeed = 2; // Base speed when not moving legs
let maxPlayerSpeed = 10; // Maximum player speed
let playerAcceleration = 0.5; // Speed increase per step
let playerDecay = 0.1; // Speed decrease when not stepping
let tigerSpeed = 0; // Tiger's current speed
let baseTigerSpeed = 2; // Base tiger speed
let maxTigerSpeed = 10; // Maximum tiger speed
let tigerAcceleration = 0.05; // Tiger's speed increase rate over time
// Steps detection
let leftStep = false;
let rightStep = false;
// Variables for serial communication
// 'latestData' is managed by p5.web-serial.js and updated via readSerial()
let latestData = "waiting for data"; // Variable to hold the latest serial data
function preload() {
backgroundImage = loadImage('start.png'); // Load the start page background
startMusic = loadSound('start_music.mp3'); // Load the start screen music
gameMusic = loadSound('bonbibi.mp3'); // Load the game music
tigerRoar = loadSound('tiger_roar.mp3'); // Load the tiger roar sound
playerImage = loadImage('player.png'); // Load the player image
tigerImage = loadImage('tiger.png'); // Load the tiger image
}
function setup() {
createCanvas(windowWidth, windowHeight);
textAlign(CENTER, CENTER);
textSize(32);
// Create Connect to Serial button
connectButton = createButton('Connect to Serial');
connectButton.position(width / 2 - connectButton.width / 10, height / 2 - 220);
connectButton.mousePressed(() => {
setUpSerial(); // Trigger serial setup on user click (from p5.web-serial.js)
connectButton.hide(); // Hide the connect button after connection
});
// Create How to Play button
howToPlayButton = createButton('How to Play');
howToPlayButton.position(width / 2 - howToPlayButton.width / 2, height / 2 + 225);
howToPlayButton.mousePressed(() => setPage("howToPlay"));
// Create Mythology button
mythologyButton = createButton('Read the Mythology');
mythologyButton.position(width / 2 - mythologyButton.width / 2, height / 2 + 250);
mythologyButton.mousePressed(() => setPage("mythology"));
// Start typewriter effect interval
setInterval(() => {
if (textIndex < typewriterText.length) {
currentText += typewriterText[textIndex];
textIndex++;
}
}, typewriterSpeed);
// Play start screen music initially
if (!startMusic.isPlaying()) {
startMusic.loop();
startMusic.setVolume(0.5);
}
// Initialize game elements
setupGameElements();
}
function draw() {
if (page === "start") {
handleStartPage();
} else if (page === "gameStart") {
handleGameStartPage();
} else if (page === "game") {
handleGamePage();
} else if (page === "howToPlay") {
handleHowToPlay();
} else if (page === "mythology") {
drawMythologyPage();
} else if (page === "won" || page === "lost") {
handleEndPage();
}
}
function handleStartPage() {
clear();
background(backgroundImage);
fill(255);
textSize(48);
text("Welcome to Quest for Sundarban", width / 2, height / 10);
// Draw the instruction text in a box with a typewriter effect
drawInstructionBox(currentText);
}
function handleGameStartPage() {
drawVectorBackground(); // Use vector background
fill(255);
textSize(36);
text("Game Starting!", width / 2, height / 2 - 50);
// Start the timer
if (!timerStart) {
timerStart = true;
startTimer();
}
// Display the timer
fill(255);
textSize(24);
text("Time Left: " + countdown + "s", width / 2, height / 2);
// Proceed to the game page after a delay
setTimeout(() => {
page = "game";
}, 2000); // Wait for 2 seconds
}
function handleGamePage() {
drawVectorBackground(); // Use vector background
// Display the timer at the top
displayTimer();
// Update game elements
updateGameElements();
}
function handleEndPage() {
clear();
drawVectorBackground(); // Use vector background
fill(gameResult.includes("Win") ? color(0, 200, 0) : color(200, 0, 0));
textSize(48);
text(gameResult, width / 2, height / 2);
// Instructions to restart
textSize(24);
fill(0);
text("Press 'R' to Restart", width / 2, height / 2 + 50);
}
function drawVectorBackground() {
// Draw sky
background(135, 206, 235); // Sky blue
// Draw ground
fill(34, 139, 34); // Forest green
rect(0, height * 0.75, width, height * 0.25);
// Draw sun
fill(255, 223, 0); // Sun color
ellipse(width * 0.1, height * 0.2, 80, 80);
// Draw clouds
fill(255);
ellipse(width * 0.3, height * 0.15, 100, 60);
ellipse(width * 0.5, height * 0.25, 120, 70);
ellipse(width * 0.7, height * 0.1, 90, 50);
// Add any other vector elements you like
}
function drawInstructionBox(textContent) {
textSize(24);
textAlign(CENTER, CENTER);
// Dimensions of the text box
let boxWidth = width * 0.6;
let boxHeight = 100;
let boxX = width / 2 - boxWidth / 2;
let boxY = height / 2 - boxHeight / 2;
// Draw golden background rectangle with dark brown border
stroke(101, 67, 33); // Dark brown color for border
strokeWeight(5); // Border thickness
fill(255, 215, 0); // Golden fill color
rect(boxX, boxY, boxWidth, boxHeight, 10); // Rounded corners
// Draw the text inside the box
fill(0); // Black text color
noStroke();
text(textContent, width / 2, boxY + boxHeight / 2);
}
function displayTimer() {
fill(255);
textSize(24);
text("Time Left: " + countdown + "s", width / 2, 50);
}
// Game logic functions
function setupGameElements() {
// Initialize player and tiger positions
player = {
x: width / 2,
y: height - 150,
size: 80,
};
tiger = {
x: width / 2,
y: height - 300,
size: 100,
};
// Reset variables
playerSpeedValue = basePlayerSpeed;
tigerSpeed = baseTigerSpeed;
countdown = timer;
gameOver = false;
gameResult = "";
}
function updateGameElements() {
if (gameOver) return;
// Update player position
updatePlayer();
// Update tiger position
updateTiger();
// Draw player and tiger
drawPlayer();
drawTiger();
// Check for win or loss conditions
checkWinOrLoss();
}
function updatePlayer() {
// Update player's speed based on leg movements
if (leftStep || rightStep) {
// Increase speed when stepping
playerSpeedValue += playerAcceleration;
playerSpeedValue = constrain(playerSpeedValue, basePlayerSpeed, maxPlayerSpeed);
} else {
// Decrease speed when not stepping
playerSpeedValue -= playerDecay;
playerSpeedValue = constrain(playerSpeedValue, basePlayerSpeed, maxPlayerSpeed);
}
// Update player's position based on speed
player.y -= playerSpeedValue;
// Constrain player within canvas
player.x = constrain(player.x, player.size / 2, width - player.size / 2);
player.y = constrain(player.y, 0, height - player.size / 2);
// Reset steps
leftStep = false;
rightStep = false;
}
function updateTiger() {
// Increase tiger's speed over time
tigerSpeed += tigerAcceleration;
tigerSpeed = constrain(tigerSpeed, baseTigerSpeed, maxTigerSpeed);
// Tiger moves towards the player
tiger.y -= tigerSpeed;
}
function drawPlayer() {
imageMode(CENTER);
image(playerImage, player.x, player.y, player.size, player.size);
}
function drawTiger() {
imageMode(CENTER);
image(tigerImage, tiger.x, tiger.y, tiger.size, tiger.size);
}
function checkWinOrLoss() {
if (gameOver) return;
// Check win condition: Player reaches the top
if (player.y <= 0) {
gameOver = true;
gameResult = "You Escaped the Tiger! You Win!";
endGame();
}
// Check loss condition: Tiger catches the player
let dTiger = dist(player.x, player.y, tiger.x, tiger.y);
if (dTiger < (player.size / 2 + tiger.size / 2) * 0.8) {
gameOver = true;
gameResult = "The Tiger Caught You!";
endGame();
}
}
function endGame() {
gameMusic.stop();
tigerRoar.stop();
timerStart = false;
clearInterval(timerInterval);
page = gameResult.includes("Win") ? "won" : "lost";
}
function startTimer() {
timerStart = true;
countdown = timer;
timerInterval = setInterval(() => {
if (countdown > 0) {
countdown--;
} else {
if (!gameOver) {
gameOver = true;
gameResult = "Time's Up! You Lose!";
endGame();
clearInterval(timerInterval);
}
}
}, 1000);
}
// Page handling functions
function setPage(newPage) {
page = newPage;
}
function handleHowToPlay() {
clear();
background(255, 215, 0);
fill(101, 67, 33);
textSize(32);
textAlign(CENTER, CENTER);
text("How to Play:", width / 2, height / 5);
textSize(24);
text(
"Use the ultrasonic sensors to move your legs up and down.\nIncrease your speed to escape the tiger!",
width / 2,
height / 2
);
// Back button
let backButton = createButton('Back');
backButton.position(width / 2 - backButton.width / 2, height - 100);
backButton.mousePressed(() => {
backButton.remove();
setPage("start");
});
}
function drawMythologyPage() {
background(255, 215, 0); // Golden background for mythology page
fill(101, 67, 33); // Dark brown text color
textSize(28);
textAlign(LEFT, TOP);
let mythologyText = "In the Sundarbans, Bonbibi is the beloved guardian of the forest...";
// Full mythology text here
let margin = 50;
text(mythologyText, margin, margin, width - 2 * margin, height - 2 * margin);
// Back button
let backButton = createButton('Back');
backButton.position(width / 2 - backButton.width / 2, height - 100);
backButton.mousePressed(() => {
backButton.remove();
setPage("start");
});
}
// Define readSerial and handleSerialEvent to interface with p5.web-serial.js
function readSerial(data) {
// This function is called by p5.web-serial.js when data is received
// Process the data and call handleSerialEvent
if (data.trim().length > 0) {
latestData = data.trim();
handleSerialEvent(latestData);
}
}
function handleSerialEvent(event) {
// Handle serial events
console.log("Received event:", event);
// If the event is "ButtonPressed", start the game
if (event === "ButtonPressed" && page === "start") {
gameStarted = true;
page = "gameStart";
console.log("Game is starting...");
// Stop the start screen music
if (startMusic.isPlaying()) {
startMusic.stop();
}
// Play the tiger roar sound
tigerRoar.play();
tigerRoar.onended(() => {
if (!gameMusic.isPlaying()) {
gameMusic.loop();
gameMusic.setVolume(0.5);
}
});
}
// Handle movement events
if (page === "game" && !gameOver) {
if (event === "LeftLegUp") {
leftStep = true;
console.log("Left leg up");
}
if (event === "RightLegUp") {
rightStep = true;
console.log("Right leg up");
}
}
}
// Handle key presses for restarting the game
function keyPressed() {
if (key === 'r' || key === 'R') {
// Restart the game
setupGameElements();
startTimer();
gameStarted = true;
page = "game";
gameOver = false;
// Stop any end screen music
if (startMusic.isPlaying()) {
startMusic.stop();
}
// Play the game music
if (!gameMusic.isPlaying()) {
gameMusic.loop();
gameMusic.setVolume(0.5);
}
}
}