Update fbird.html
added party popper confetti and only top 5 get to enter their name
This commit is contained in:
1 parent
37bccfc53d
commit
94396fa005
1 file changed
+97
-17
+97
-17
@@ -11,7 +11,8 @@
|
|||||||
viewport-fit=cover">
|
viewport-fit=cover">
|
||||||
|
|
||||||
<link rel="shortcut icon"
|
<link rel="shortcut icon"
|
||||||
href="https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/UZ_road_sign_1.25.2.svg/960px-UZ_road_sign_1.25.2.svg.png"
|
href="
|
||||||
|
https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/UZ_road_sign_1.25.2.svg/960px-UZ_road_sign_1.25.2.svg.png"
|
||||||
type="image/svg+xml">
|
type="image/svg+xml">
|
||||||
|
|
||||||
<title>famous bird</title>
|
<title>famous bird</title>
|
||||||
@@ -227,39 +228,57 @@
|
|||||||
"flap your wings"
|
"flap your wings"
|
||||||
</div>
|
</div>
|
||||||
<button id="startButton">START GAME</button>
|
<button id="startButton">START GAME</button>
|
||||||
|
<div class="instructions">
|
||||||
|
Avoid the pipes and<br>
|
||||||
|
don't hit the ground!
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="gameOverScreen" class="hidden">
|
<div id="gameOverScreen" class="hidden">
|
||||||
<div class="message"
|
<div class="message" style="font-size: 8cqw;
|
||||||
style="font-size: 8cqw; font-weight:bold; color: #ff4757; margin-bottom: 2cqw;">
|
font-weight:bold;
|
||||||
GAME OVER
|
color: #ff4757;
|
||||||
|
margin-bottom: 2cqw;">
|
||||||
|
GAME OVER
|
||||||
</div>
|
</div>
|
||||||
<div class="score-display"
|
<div class="score-display" style="margin-top: 0;
|
||||||
style="margin-top: 0; margin-bottom: 2cqw;">
|
margin-bottom: 2cqw;">
|
||||||
Score: <span id="finalScore">0</span>
|
Score: <span id="finalScore">0</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="highscoreEntry" class="hidden"
|
<div id="highscoreEntry" class="hidden" style="display: flex;
|
||||||
style="display: flex; flex-direction: column; align-items: center; width: 100%;">
|
flex-direction: column;
|
||||||
<div style="font-size: 5cqw; margin-bottom: 2cqw; color: #f1c40f; font-weight: bold; text-shadow: 0 2px 4px rgba(0,0,0,0.5);">
|
align-items: center;
|
||||||
NEW HIGH SCORE!
|
width: 100%;">
|
||||||
|
<div style="font-size: 5cqw;
|
||||||
|
margin-bottom: 2cqw;
|
||||||
|
color: #f1c40f;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 0 2px 4px rgba(0,0,0,0.5);">
|
||||||
|
🎉 NEW HIGH SCORE 🏆
|
||||||
</div>
|
</div>
|
||||||
<input type="text" id="playerName" placeholder="YOUR NAME" maxlength="13">
|
<input type="text" id="playerName" placeholder="YOUR NAME" maxlength="13">
|
||||||
<button id="saveScoreButton" style="font-size: 5cqw; padding: 2.5cqw 8cqw;">
|
<button id="saveScoreButton" style="font-size: 5cqw;
|
||||||
|
padding: 2.5cqw 8cqw;">
|
||||||
SAVE SCORE
|
SAVE SCORE
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="leaderboard" class="instructions"
|
<div id="leaderboard" class="instructions" style="margin-top: 2cqw;
|
||||||
style="margin-top: 2cqw; font-size: 4.5cqw;">
|
font-size: 4.5cqw;">
|
||||||
<div style="font-weight: 900; margin-bottom: 3cqw; text-align: center; color: #f1c40f;">
|
<div style="font-weight: 900;
|
||||||
|
margin-bottom: 3cqw;
|
||||||
|
text-align: center;
|
||||||
|
color: #f1c40f;">
|
||||||
TOP 5 SCORES
|
TOP 5 SCORES
|
||||||
</div>
|
</div>
|
||||||
<div id="leaderboardList" style="text-align: left;">
|
<div id="leaderboardList" style="text-align: left;">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="restartButton" style="margin-top: 3cqw;">TRY AGAIN</button>
|
<button id="restartButton" style="margin-top: 3cqw;">
|
||||||
|
TRY AGAIN
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="gameUI" class="hidden">
|
<div id="gameUI" class="hidden">
|
||||||
@@ -289,23 +308,32 @@
|
|||||||
// ==========================================
|
// ==========================================
|
||||||
// Tracks the current menu/game phase.
|
// Tracks the current menu/game phase.
|
||||||
let gameState = 'start';
|
let gameState = 'start';
|
||||||
|
|
||||||
// Current session score.
|
// Current session score.
|
||||||
let score = 0;
|
let score = 0;
|
||||||
|
|
||||||
// Array to hold {name, score} objects for the leaderboard.
|
// Array to hold {name, score} objects for the leaderboard.
|
||||||
let highscores = [];
|
let highscores = [];
|
||||||
|
|
||||||
|
|
||||||
// Time and Speed setup for smooth animations.
|
// Time and Speed setup for smooth animations.
|
||||||
let lastTime = 0;
|
let lastTime = 0;
|
||||||
let pipeSpawnTimer = 0;
|
let pipeSpawnTimer = 0;
|
||||||
|
|
||||||
|
// NEW: Party popper 🎉
|
||||||
|
let confettiParticles = [];
|
||||||
|
|
||||||
// Target pixel distance between pipes. Ensures that when
|
// Target pixel distance between pipes. Ensures that when
|
||||||
// the game speeds up, the horizontal gap stays identical.
|
// the game speeds up, the horizontal gap stays identical.
|
||||||
const PIPE_DISTANCE = 220;
|
const PIPE_DISTANCE = 220;
|
||||||
|
|
||||||
// Starting speed in pixels per second.
|
// Starting speed in pixels per second.
|
||||||
const BASE_SPEED = 120;
|
const BASE_SPEED = 120;
|
||||||
|
|
||||||
// How much faster to go every 10 points.
|
// How much faster to go every 10 points.
|
||||||
const SPEED_INCREMENT = 15;
|
const SPEED_INCREMENT = 15;
|
||||||
|
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 3. GAME ENTITIES (BIRD & PIPES)
|
// 3. GAME ENTITIES (BIRD & PIPES)
|
||||||
// ==========================================
|
// ==========================================
|
||||||
@@ -356,6 +384,7 @@
|
|||||||
if (gameState === 'playing') {
|
if (gameState === 'playing') {
|
||||||
// Apply gravity over time
|
// Apply gravity over time
|
||||||
this.velocity += this.gravity * dt * 60;
|
this.velocity += this.gravity * dt * 60;
|
||||||
|
|
||||||
// Move the bird by the current velocity
|
// Move the bird by the current velocity
|
||||||
this.y += this.velocity * dt;
|
this.y += this.velocity * dt;
|
||||||
|
|
||||||
@@ -608,6 +637,7 @@
|
|||||||
(highscores.length < 5 || score > highscores[highscores.length - 1].score);
|
(highscores.length < 5 || score > highscores[highscores.length - 1].score);
|
||||||
|
|
||||||
if (isHighScore) {
|
if (isHighScore) {
|
||||||
|
spawnConfetti();
|
||||||
// Show input block, force user to save before restarting
|
// Show input block, force user to save before restarting
|
||||||
document.getElementById('highscoreEntry').classList.remove('hidden');
|
document.getElementById('highscoreEntry').classList.remove('hidden');
|
||||||
document.getElementById('restartButton').classList.add('hidden');
|
document.getElementById('restartButton').classList.add('hidden');
|
||||||
@@ -645,6 +675,54 @@
|
|||||||
resetGame();
|
resetGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to create the confetti particles
|
||||||
|
function spawnConfetti() {
|
||||||
|
for (let i = 0; i < 150; i++) {
|
||||||
|
confettiParticles.push({
|
||||||
|
x: Math.random() * canvas.width,
|
||||||
|
y: -10, // Start just above the screen
|
||||||
|
vx: (Math.random() - 0.5) * 4, // Horizontal drift
|
||||||
|
vy: Math.random() * 3 + 2, // Speed falling
|
||||||
|
rotation: Math.random() * Math.PI * 2, // Starting angle
|
||||||
|
rotationSpeed: (Math.random() - 0.5) * 0.2, // How fast it spins
|
||||||
|
color: `hsl(${Math.random() * 360}, 100%, 50%)`,
|
||||||
|
life: 200 // Lasts a bit longer
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update and draw confetti particles
|
||||||
|
function updateAndDrawConfetti() {
|
||||||
|
confettiParticles.forEach((p, i) => {
|
||||||
|
p.x += p.vx;
|
||||||
|
p.y += p.vy;
|
||||||
|
p.rotation += p.rotationSpeed; // Update the angle
|
||||||
|
p.life--;
|
||||||
|
|
||||||
|
ctx.save(); // Save the current canvas state
|
||||||
|
|
||||||
|
// Move to the particle's position and rotate
|
||||||
|
ctx.translate(p.x, p.y);
|
||||||
|
ctx.rotate(p.rotation);
|
||||||
|
|
||||||
|
// Draw the Rhomboid centered at 0,0
|
||||||
|
ctx.fillStyle = p.color;
|
||||||
|
ctx.beginPath();
|
||||||
|
const w = 6; // Width
|
||||||
|
const h = 10; // Height
|
||||||
|
ctx.moveTo(0, -h / 2); // Top
|
||||||
|
ctx.lineTo(w / 2, 0); // Right
|
||||||
|
ctx.lineTo(0, h / 2); // Bottom
|
||||||
|
ctx.lineTo(-w / 2, 0); // Left
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
ctx.restore(); // Restore state so the rest of the game draws normally
|
||||||
|
|
||||||
|
if (p.life <= 0) confettiParticles.splice(i, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// 7. CORE RENDER & UPDATE LOOP
|
// 7. CORE RENDER & UPDATE LOOP
|
||||||
// ==========================================
|
// ==========================================
|
||||||
@@ -655,6 +733,8 @@
|
|||||||
pipes.draw();
|
pipes.draw();
|
||||||
drawGround();
|
drawGround();
|
||||||
bird.draw();
|
bird.draw();
|
||||||
|
// Draw confetti on top of everything
|
||||||
|
updateAndDrawConfetti();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Master update function that processes physics
|
// Master update function that processes physics
|
||||||
|
|||||||
Reference in new issue
Block a user