xxxxxxxxxx
512
// p5.js Code: Boat Game with Potentiometer Input
// Variables for the game state
let gameStarted = false;
let backgroundImage, boatImage;
let playerX, playerY;
let flowers = [];
let obstacles = [];
let collectedFlowers = 0;
let gameTimer = 60;
let isGameOver = false;
let boatSpeed = 5;
let flowerSpeed = 2;
let lastGenerationTime = 0;
let flowerGenerationInterval = 2000;
let rippleOffset = 0;
let boatSize;
let music;
// Variables for the start screen and integration
let startBackgroundImage, gameBackground;
let connectButton, howToPlayButton, mythologyButton;
let page = "start";
let touchState = "NoTouch";
let startMusic, gameMusic, tigerRoar;
let typewriterText = "Hold the leaves together to start your adventure!";
let currentText = "";
let textIndex = 0;
let typewriterSpeed = 50;
// Variables for serial communication
let serial;
let latestData = "waiting for data"; // Variable to hold the latest serial data
// Preload assets
function preload() {
startBackgroundImage = loadImage('start.png'); // Start screen background
gameBackground = loadImage('sunadrban.png'); // Game background
boatImage = loadImage('boat.png'); // Boat image
startMusic = loadSound('birds.mp3'); // Start screen music
gameMusic = loadSound('bonbibi.mp3'); // Game music
tigerRoar = loadSound('tiger_roar.mp3'); // Tiger roar sound
}
function setup() {
createCanvas(windowWidth, windowHeight);
boatSize = windowWidth / 5;
textAlign(CENTER, CENTER);
textSize(32);
// Start screen buttons
connectButton = createButton('Connect to Serial');
connectButton.position(width / 12 - connectButton.width / 14, height / 13);
connectButton.mousePressed(async () => {
await setUpSerial();
connectButton.hide();
});
howToPlayButton = createButton('How to Play');
howToPlayButton.position(width / 2 - howToPlayButton.width / 2, height / 2 + 225);
howToPlayButton.mousePressed(() => setPage("howToPlay"));
mythologyButton = createButton('Read the Mythology');
mythologyButton.position(width / 2 - mythologyButton.width / 2, height / 2 + 270);
mythologyButton.mousePressed(() => setPage("mythology"));
// Typewriter effect
setInterval(() => {
if (textIndex < typewriterText.length) {
currentText += typewriterText[textIndex];
textIndex++;
}
}, typewriterSpeed);
// Play start screen music
if (!startMusic.isPlaying()) {
startMusic.loop();
startMusic.setVolume(0.5);
}
// Initialize game elements
resetGame();
}
function draw() {
if (!gameStarted) {
handleGameStart();
} else if (isGameOver) {
drawGameOverScreen();
} else {
drawBoatGame();
}
}
// Handle the game start sequence
function handleGameStart() {
clear();
if (page === "start") {
background(startBackgroundImage);
fill(255);
text("Welcome to Quest for Sundarban", width / 2, height / 5);
drawInstructionBox(currentText);
} else if (page === "howToPlay") {
background(0);
fill(255);
text("How to Play: Use the potentiometer to move the boat left and right.", width / 2, height / 2);
} else if (page === "mythology") {
drawMythologyPage();
}
// Start the game when the leaves are touched
if (touchState === "LeafTouched") {
gameStarted = true;
page = "game";
howToPlayButton.hide();
mythologyButton.hide();
if (startMusic.isPlaying()) {
startMusic.stop();
}
tigerRoar.play();
tigerRoar.onended(() => {
if (!gameMusic.isPlaying()) {
gameMusic.loop();
gameMusic.setVolume(0.5);
}
});
}
}
// Draw the boat game
function drawBoatGame() {
drawRiverBackground();
drawBoat();
updateAndDrawFlowers();
updateAndDrawObstacles();
drawCollectedFlowers();
drawTimer();
movePlayer();
checkCollisions();
if (gameTimer <= 0) {
isGameOver = true;
}
}
// Draw the game over screen
function drawGameOverScreen() {
background(0);
fill(255, 0, 0);
text("Time's Up!", width / 2, height / 2 - 50);
textSize(20);
fill(255, 223, 0);
stroke(255);
strokeWeight(3);
rectMode(CENTER);
rect(width / 2, height / 2 + 50, 250, 70, 10);
noStroke();
fill(0);
text("Next Stage", width / 2, height / 2 + 50);
}
// Draw the river background with enhanced visuals
function drawRiverBackground() {
background('#87CEFA');
// Enhanced water visuals
noFill();
stroke(255, 255, 255, 80);
strokeWeight(2);
for (let y = 0; y < height; y += 10) {
beginShape();
for (let x = 0; x < width; x += 5) {
let noiseVal = noise(x * 0.02, y * 0.02 + rippleOffset);
let rippleY = y + (noiseVal * 20 - 10);
vertex(x, rippleY);
}
endShape();
}
rippleOffset += 0.02;
}
// Draw the player's boat
function drawBoat() {
image(boatImage, playerX, playerY, boatSize, boatSize);
}
// Update and draw flowers
function updateAndDrawFlowers() {
let currentTime = millis();
if (currentTime - lastGenerationTime > flowerGenerationInterval) {
generateFlower();
lastGenerationTime = currentTime;
}
for (let i = flowers.length - 1; i >= 0; i--) {
let flower = flowers[i];
updateFlower(flower);
drawFlower(flower.x, flower.y, flower.size, flower.rotation, flower.type);
flower.rotation += 0.01;
// Remove flowers that have moved off-screen
if (flower.y > height + 50) {
flowers.splice(i, 1);
}
}
}
// Update flower position
function updateFlower(flower) {
flower.y += flowerSpeed;
}
// Draw the glowing flowers
function drawFlower(x, y, size, rotation, type) {
push();
translate(x, y);
rotate(rotation);
scale(1.2);
switch (type) {
case 0:
drawDaisy(0, 0, size);
break;
case 1:
drawTulip(0, 0, size);
break;
case 2:
drawRose(0, 0, size);
break;
case 3:
drawSunflower(0, 0, size);
break;
case 4:
drawLily(0, 0, size);
break;
case 5:
drawMarigold(0, 0, size);
break;
}
// Add glowing effect
blendMode(ADD);
noStroke();
fill(255, 200, 0, 80);
ellipse(0, 0, size * 1.5);
pop();
}
// Update and draw obstacles using soft physics
function updateAndDrawObstacles() {
if (frameCount % 120 === 0) {
generateObstacle();
}
for (let i = obstacles.length - 1; i >= 0; i--) {
let obs = obstacles[i];
obs.y += obs.speedY;
obs.x += obs.speedX * sin(frameCount * 0.02);
// Draw obstacle (e.g., driftwood)
push();
translate(obs.x, obs.y);
rotate(obs.rotation);
fill(139, 69, 19);
noStroke();
beginShape();
for (let v of obs.vertices) {
vertex(v.x, v.y);
}
endShape(CLOSE);
pop();
// Remove obstacles that have moved off-screen
if (obs.y > height + 50) {
obstacles.splice(i, 1);
}
}
}
// Generate a new obstacle
function generateObstacle() {
let size = random(30, 80);
let obstacle = {
x: random(50, width - 50),
y: -50,
speedY: random(2, 4),
speedX: random(-1, 1),
rotation: random(TWO_PI),
vertices: []
};
// Create random shape for obstacle
let points = floor(random(5, 8));
for (let i = 0; i < points; i++) {
let angle = map(i, 0, points, 0, TWO_PI);
let radius = size / 2 + random(-10, 10);
obstacle.vertices.push({
x: cos(angle) * radius,
y: sin(angle) * radius
});
}
obstacles.push(obstacle);
}
// Draw collected flowers count
function drawCollectedFlowers() {
fill(0);
textSize(24);
textAlign(LEFT, TOP);
text(`Flowers Collected: ${collectedFlowers}`, 20, 20);
}
// Draw the game timer
function drawTimer() {
fill(0);
textSize(24);
textAlign(RIGHT, TOP);
let timerText = `Time Remaining: ${gameTimer} s`;
text(timerText, width - 20, 20);
if (frameCount % 60 == 0 && gameTimer > 0) {
gameTimer--;
}
}
// Move the player boat using potentiometer input
function movePlayer() {
if (latestData !== "waiting for data") {
let sensorValue = parseInt(latestData);
// Map the potentiometer value (0-1023) to the boat position
playerX = map(sensorValue, 0, 1023, 0, width - boatSize);
}
playerY = height - boatSize - 20;
}
// Check for collisions
function checkCollisions() {
// Check collision with flowers
for (let i = flowers.length - 1; i >= 0; i--) {
let flower = flowers[i];
let distance = dist(playerX + boatSize / 2, playerY + boatSize / 2, flower.x, flower.y);
if (distance < 50) {
flowers.splice(i, 1);
collectedFlowers++;
}
}
// Check collision with obstacles
for (let obs of obstacles) {
let distance = dist(playerX + boatSize / 2, playerY + boatSize / 2, obs.x, obs.y);
if (distance < 60) {
isGameOver = true;
}
}
}
// Reset the game state
function resetGame() {
playerX = width / 2;
playerY = height - boatSize - 20;
collectedFlowers = 0;
gameTimer = 60;
isGameOver = false;
flowers = [];
obstacles = [];
}
// Generate a new flower
function generateFlower() {
let size = random(30, 60);
let flowerType = floor(random(6));
flowers.push({
x: random(50, width - 50),
y: -30,
size: size,
rotation: random(TWO_PI),
type: flowerType
});
}
// Draw the instruction box with typewriter effect
function drawInstructionBox(textContent) {
textSize(24);
textAlign(CENTER, CENTER);
let textWidthValue = textWidth(textContent);
let padding = 30;
let boxX = (width / 2) - (textWidthValue / 2) - padding;
let boxY = (height / 2) + 20;
let boxWidth = textWidthValue + padding * 2;
let boxHeight = 80;
stroke(101, 67, 33);
strokeWeight(5);
fill(255, 215, 0);
rect(boxX, boxY, boxWidth, boxHeight, 10);
fill(0);
noStroke();
text(textContent, width / 2, boxY + boxHeight / 2);
}
// Draw the mythology page
function drawMythologyPage() {
background(255, 215, 0);
fill(101, 67, 33);
textSize(28);
textAlign(CENTER, CENTER);
let mythologyText = "In the Sundarbans, Bonbibi is the beloved guardian of the forest...";
let textY = height / 5;
let lineHeight = 40;
let words = mythologyText.split(" ");
let currentLine = "";
let lines = [];
for (let word of words) {
if (textWidth(currentLine + word) < width - 100) {
currentLine += word + " ";
} else {
lines.push(currentLine);
currentLine = word + " ";
}
}
lines.push(currentLine);
for (let i = 0; i < lines.length; i++) {
text(lines[i], width / 2, textY + (i * lineHeight));
}
}
// Flower drawing functions (same as before)
// ... [Include all flower drawing functions here, as provided in the previous code]
// Serial setup function
async function setUpSerial() {
// Initialize the serial port
serial = new p5.SerialPort();
// Get a list of available serial ports
let ports = await serial.list();
console.log("Available ports:", ports);
// Open the serial port (adjust the port name as needed)
// If you know the port name, you can specify it directly
// Example: serial.open('/dev/tty.usbmodem14101');
// Otherwise, use serial.requestPort() to prompt the user to select a port
try {
await serial.requestPort();
await serial.open({ baudRate: 9600 });
console.log("Serial port opened successfully.");
// Set up callbacks
serial.on('data', serialEvent);
serial.on('error', serialError);
} catch (err) {
console.error("Error opening serial port:", err);
}
}
// Callback for new serial data
function serialEvent() {
let inString = serial.readLine();
if (inString.length > 0) {
latestData = inString;
}
}
// Callback for serial errors
function serialError(err) {
console.error("Something went wrong with the serial port. " + err);
}
// Handle touch events or potentiometer input
function touchStarted() {
touchState = "LeafTouched";
}
// Handle mouse pressed event for the "Next Stage" button
function mousePressed() {
if (isGameOver) {
let buttonX = width / 2 - 125;
let buttonY = height / 2 + 15;
let buttonW = 250;
let buttonH = 70;
if (
mouseX > buttonX &&
mouseX < buttonX + buttonW &&
mouseY > buttonY &&
mouseY < buttonY + buttonH
) {
// Proceed to the next stage or tiger game
isGameOver = false;
gameStarted = false;
page = "tigerGame";
resetGame();
// Implement the tiger game or proceed to the next stage
}
}
}
function setPage(newPage) {
page = newPage;
}
// Include your flower drawing functions here...
// drawDaisy, drawTulip, drawRose, drawSunflower, drawLily, drawMarigold