xxxxxxxxxx
336
let pinguImg, bgImg, platformImg, disappearImg;
let jumpSound;
let pingu;
let platforms = [];
let gameStarted = false;
let score = 0;
let noot;
let gameOver = false;
let serial;
let timer = 60;
let win = false;
function setup() {
createCanvas(600, 800);
textSize(20);
fill(255);
textAlign(CENTER);
if (backgroundMusic) {
backgroundMusic.loop();
}
// hardcoded platforms
for (let i = 0; i < 2; i++) {
platforms.push(new Platform(10 + (i * 200) % width, 600 - i * 150, 200, 40, platformImg, "normal"));
}
// Add RANDOM platforms
platforms = platforms.concat(generateRandomPlatforms(3)); // more platforms
// Pingu on the lowest platform
pingu = new Pingu(platforms[0].x + platforms[0].w / 2, platforms[0].y - 120, 300, 241); // Adjusted size
}
function readSerial(data) {
if (data != null) {
let fromArduino = trim(data);
if (fromArduino === "JUMP") {
if (gameStarted && !gameOver) {
pingu.jump();
}
} else if (fromArduino === "LEFT") {
if (gameStarted && !gameOver) {
pingu.move(-5);
}
} else if (fromArduino === "RIGHT") {
if (gameStarted && !gameOver) {
pingu.move(5);
}
} else if (fromArduino === "IDLE") {
if (gameStarted && !gameOver) {
pingu.stop();
}
} else if (fromArduino === "RESTART") {
if (gameOver || win) {
resetGame(); // Restart the game
} else if (!gameStarted) {
gameStarted = true;
}
}
}
}
function draw() {
background(bgImg);
if (!serialActive) {
text("Press Space for Serial Port", 300, 50);
textAlign(CENTER, CENTER);
return;
} else {
text("Connected", width / 2, 30);
}
if (!gameStarted) {
textSize(40);
fill(255);
text("Press Start!", width / 2, height / 2);
return;
}
let minHeight = height / 2;
if (pingu.y < minHeight) {
let offset = minHeight - pingu.y;
pingu.y = minHeight;
for (let platform of platforms) {
platform.y += offset;
}
}
for (let platform of platforms) {
platform.display();
}
//Remove paltforms
platforms = platforms.filter(platform => platform.y < height);
if (platforms.length < 9) {
platforms.push(generateRandomPlatforms(9 - platforms.length));
}
pingu.update(platforms);
pingu.display();
textSize(20);
fill(255);
text("Score: " + score, width - 50, 30);
text("Time Left: " + timer + "s", 100, 30);
// Decrement timer and check win
if (!gameOver && !win && gameStarted) {
if (frameCount % 60 === 0 && timer > 0) {
timer--;
}
if (timer <= 0) {
win = true;
noLoop();
}
}
if (gameOver) {
backgroundMusic.stop();
fill(0, 0, 0, 150);
rect(0, 0, width, height);
textSize(60);
fill(255, 0, 0);
textStyle(BOLD);
text("YOU LOST.", width / 2, height / 2 - 40);
textSize(30);
fill(255);
text("Press Restart to Try Again!", width / 2, height / 2 + 20);
noLoop();
noot.play();
}
else if (win) {
backgroundMusic.stop();
fill(0, 0, 0, 150);
rect(0, 0, width, height);
textSize(60);
fill(0, 255, 0);
textStyle(BOLD);
text("YOU WIN!", width / 2, height / 2 - 40);
textSize(30);
fill(255);
text("Press Restart to Play Again!", width / 2, height / 2 + 20);
noLoop();
noot.play();
}
}
function preload() {
// Preload assets
pinguImg = loadImage("images/pingu.png");
bgImg = loadImage("images/thesnow.jpg");
platformImg = loadImage("images/platform.png");
disappearImg = loadImage("images/disappearing_platform.png");
jumpSound = loadSound("jump.m4a");
noot = loadSound('noot.mp3');
backgroundMusic = loadSound("background_music.mp3");
}
function keyPressed() {
if (keyCode === LEFT_ARROW) pingu.move(-5);
if (keyCode === RIGHT_ARROW) pingu.move(5);
if (keyCode === UP_ARROW && pingu.onGround) pingu.jump();
if (key === 'R' || key === 'r') resetGame();
if (key == " ") {
setUpSerial();
}
}
function keyReleased() {
if (keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW) pingu.stop();
}
class Pingu {
constructor(x, y, w, h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.vx = 0;
this.vy = 0;
this.onGround = false;
this.landedOnPlatform = false;
}
update(platforms) {
this.vy += 0.5; // Gravity
this.y += this.vy;
this.onGround = false;
let landedOnNewPlatform = false;
for (let platform of platforms) {
if (
this.vy >= 0 && //Ensure Pingu is falling or stationary
this.y + this.h / 2 >= platform.y &&
this.y + this.h / 2 <= platform.y + platform.h &&
this.x > platform.x &&
this.x < platform.x + platform.w
) {
if (platform.type === "disappearImg") {
let index = platforms.indexOf(platform);
if (index !== -1) {
platforms.splice(index, 1); // Remove the platform
}
break;
} else {
this.y = platform.y - this.h / 2;
this.vy = 0;
this.onGround = true;
if (!this.landedOnPlatform) {
landedOnNewPlatform = true;
}
}
}
}
if (landedOnNewPlatform) {
score++;
this.landedOnPlatform = true;
}
if (!this.onGround) {
this.landedOnPlatform = false;
}
if (this.y >= height - this.h / 2) {
this.resetPosition();
gameOver = true;
}
this.x += this.vx;
if (this.x > width) this.x = 0;
if (this.x < 0) this.x = width;
}
resetPosition() {
this.x = width / 2;
this.y = height - 100;
this.vy = 0;
}
display() {
image(pinguImg, this.x - this.w / 2, this.y - this.h / 2, this.w, this.h);
}
move(vx) {
this.vx = vx;
}
stop() {
this.vx = 0;
}
jump() {
if (this.onGround) {
this.vy = -20;
jumpSound.play();
}
}
}
class Platform {
constructor(x, y, w, h, img, type) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.img = img;
this.type = type;
}
display() {
image(this.img, this.x, this.y, this.w, this.h);
}
}
function generateRandomPlatforms(num) {
let platTypesDict = {
normal: platformImg,
disappearImg: disappearImg
};
let newPlatforms = [];
for (let i = 0; i < num; i++) {
let x, y;
let overlap = true;
// doesn't overla p with existing ones
while (overlap) {
x = random(0, width - 200);
y = random(height - 200);
overlap = false;
for (let platform of platforms) {
if (
x + 200 > platform.x &&
x < platform.x + platform.w &&
y + 40 > platform.y &&
y < platform.y + platform.h
) {
overlap = true;
break;
}
}
}
let platType;
let randomNum = random();
if (randomNum < 0.7) platType = "normal";
else platType = "disappearImg";
newPlatforms.push(new Platform(x, y, 200, 40, platTypesDict[platType], platType));
}
return newPlatforms;
}
function resetGame() {
score = 0;
gameOver = false;
gameStarted = false;
win = false;
timer = 60; // Reset the timer
platforms = [];
setup();
loop();
}