Flappy Bird 是一款經典的休閑游戲,由越南開發者 Dong Nguyen 開發并于2013年發布。游戲玩法簡單但極具挑戰性,玩家需要控制一只小鳥通過不斷點擊屏幕使其飛行,并避開上下移動的管道。盡管游戲規則簡單,但其高難度和上癮性使其迅速風靡全球。
本文將詳細介紹如何使用 JavaScript 實現一個簡化版的 Flappy Bird 游戲。我們將從游戲的基本結構開始,逐步實現游戲的各個部分,包括小鳥的飛行、管道的生成與移動、碰撞檢測以及得分計算等。
首先,我們需要創建一個基本的 HTML 文件來承載我們的游戲。我們將使用 HTML5 的 <canvas>
元素來繪制游戲畫面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flappy Bird</title>
<style>
body {
margin: 0;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #70c5ce;
}
canvas {
border: 2px solid #000;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="288" height="512"></canvas>
<script src="game.js"></script>
</body>
</html>
在這個 HTML 文件中,我們創建了一個 <canvas>
元素,并為其設置了寬度和高度。我們還引入了一個名為 game.js
的 JavaScript 文件,該文件將包含我們游戲的所有邏輯。
接下來,我們將在 game.js
文件中初始化游戲。首先,我們需要獲取 <canvas>
元素并設置其上下文。
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const bird = {
x: 50,
y: 150,
width: 40,
height: 30,
gravity: 0.6,
lift: -10,
velocity: 0
};
const pipes = [];
const pipeWidth = 50;
const pipeGap = 100;
const pipeFrequency = 90;
let frameCount = 0;
let score = 0;
let gameOver = false;
在這里,我們定義了小鳥的初始位置、大小、重力、升力和速度。我們還定義了一個數組 pipes
來存儲所有的管道,以及一些與管道相關的常量。
接下來,我們需要繪制小鳥。我們將使用一個簡單的矩形來表示小鳥。
function drawBird() {
ctx.fillStyle = 'yellow';
ctx.fillRect(bird.x, bird.y, bird.width, bird.height);
}
小鳥的飛行是通過不斷更新其位置來實現的。每次游戲循環時,我們都會更新小鳥的速度和位置。
function updateBird() {
bird.velocity += bird.gravity;
bird.y += bird.velocity;
if (bird.y + bird.height > canvas.height || bird.y < 0) {
gameOver = true;
}
}
function flap() {
bird.velocity = bird.lift;
}
document.addEventListener('keydown', function(event) {
if (event.code === 'Space') {
flap();
}
});
在這里,我們定義了一個 updateBird
函數來更新小鳥的位置,并檢查小鳥是否碰到了畫布的頂部或底部。我們還定義了一個 flap
函數,當玩家按下空格鍵時,小鳥會獲得一個向上的速度。
管道的生成是通過在特定的時間間隔內創建新的管道對象來實現的。
function generatePipe() {
const gapStart = Math.random() * (canvas.height - pipeGap);
const topPipe = {
x: canvas.width,
y: 0,
width: pipeWidth,
height: gapStart
};
const bottomPipe = {
x: canvas.width,
y: gapStart + pipeGap,
width: pipeWidth,
height: canvas.height - gapStart - pipeGap
};
pipes.push(topPipe, bottomPipe);
}
在這里,我們定義了一個 generatePipe
函數來生成新的管道。每個管道由一個上管道和一個下管道組成,它們之間有一個固定的間隙。
接下來,我們需要繪制所有的管道。
function drawPipes() {
ctx.fillStyle = 'green';
pipes.forEach(pipe => {
ctx.fillRect(pipe.x, pipe.y, pipe.width, pipe.height);
});
}
每次游戲循環時,我們都需要更新管道的位置,并檢查它們是否已經移出畫布。
function updatePipes() {
if (frameCount % pipeFrequency === 0) {
generatePipe();
}
pipes.forEach(pipe => {
pipe.x -= 2;
if (pipe.x + pipe.width < 0) {
pipes.shift();
score++;
}
});
}
在這里,我們定義了一個 updatePipes
函數來更新管道的位置。如果管道移出了畫布,我們將其從數組中移除,并增加得分。
我們需要檢測小鳥是否與管道發生了碰撞。
function checkCollision() {
for (let i = 0; i < pipes.length; i += 2) {
const topPipe = pipes[i];
const bottomPipe = pipes[i + 1];
if (bird.x < topPipe.x + topPipe.width &&
bird.x + bird.width > topPipe.x &&
(bird.y < topPipe.height || bird.y + bird.height > bottomPipe.y)) {
gameOver = true;
}
}
}
在這里,我們定義了一個 checkCollision
函數來檢測小鳥是否與管道發生了碰撞。如果發生了碰撞,我們將 gameOver
設置為 true
。
我們需要在畫布上顯示當前的得分。
function drawScore() {
ctx.fillStyle = 'black';
ctx.font = '24px Arial';
ctx.fillText(`Score: ${score}`, 10, 30);
}
最后,我們需要創建一個游戲循環來不斷更新和繪制游戲。
function gameLoop() {
if (gameOver) {
ctx.fillStyle = 'black';
ctx.font = '48px Arial';
ctx.fillText('Game Over', canvas.width / 2 - 100, canvas.height / 2);
return;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
updateBird();
updatePipes();
checkCollision();
drawBird();
drawPipes();
drawScore();
frameCount++;
requestAnimationFrame(gameLoop);
}
gameLoop();
在這里,我們定義了一個 gameLoop
函數來不斷更新和繪制游戲。如果游戲結束,我們將在畫布上顯示“Game Over”并停止游戲循環。
通過以上步驟,我們成功地使用 JavaScript 實現了一個簡化版的 Flappy Bird 游戲。雖然這個版本的游戲相對簡單,但它涵蓋了游戲開發中的許多基本概念,如游戲循環、碰撞檢測、得分計算等。
你可以在此基礎上進一步擴展游戲的功能,例如添加背景音樂、增加難度、優化圖形等。希望這篇文章能幫助你理解如何使用 JavaScript 開發簡單的游戲,并激發你進一步探索游戲開發的興趣。
以下是完整的 game.js
文件代碼:
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const bird = {
x: 50,
y: 150,
width: 40,
height: 30,
gravity: 0.6,
lift: -10,
velocity: 0
};
const pipes = [];
const pipeWidth = 50;
const pipeGap = 100;
const pipeFrequency = 90;
let frameCount = 0;
let score = 0;
let gameOver = false;
function drawBird() {
ctx.fillStyle = 'yellow';
ctx.fillRect(bird.x, bird.y, bird.width, bird.height);
}
function updateBird() {
bird.velocity += bird.gravity;
bird.y += bird.velocity;
if (bird.y + bird.height > canvas.height || bird.y < 0) {
gameOver = true;
}
}
function flap() {
bird.velocity = bird.lift;
}
document.addEventListener('keydown', function(event) {
if (event.code === 'Space') {
flap();
}
});
function generatePipe() {
const gapStart = Math.random() * (canvas.height - pipeGap);
const topPipe = {
x: canvas.width,
y: 0,
width: pipeWidth,
height: gapStart
};
const bottomPipe = {
x: canvas.width,
y: gapStart + pipeGap,
width: pipeWidth,
height: canvas.height - gapStart - pipeGap
};
pipes.push(topPipe, bottomPipe);
}
function drawPipes() {
ctx.fillStyle = 'green';
pipes.forEach(pipe => {
ctx.fillRect(pipe.x, pipe.y, pipe.width, pipe.height);
});
}
function updatePipes() {
if (frameCount % pipeFrequency === 0) {
generatePipe();
}
pipes.forEach(pipe => {
pipe.x -= 2;
if (pipe.x + pipe.width < 0) {
pipes.shift();
score++;
}
});
}
function checkCollision() {
for (let i = 0; i < pipes.length; i += 2) {
const topPipe = pipes[i];
const bottomPipe = pipes[i + 1];
if (bird.x < topPipe.x + topPipe.width &&
bird.x + bird.width > topPipe.x &&
(bird.y < topPipe.height || bird.y + bird.height > bottomPipe.y)) {
gameOver = true;
}
}
}
function drawScore() {
ctx.fillStyle = 'black';
ctx.font = '24px Arial';
ctx.fillText(`Score: ${score}`, 10, 30);
}
function gameLoop() {
if (gameOver) {
ctx.fillStyle = 'black';
ctx.font = '48px Arial';
ctx.fillText('Game Over', canvas.width / 2 - 100, canvas.height / 2);
return;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
updateBird();
updatePipes();
checkCollision();
drawBird();
drawPipes();
drawScore();
frameCount++;
requestAnimationFrame(gameLoop);
}
gameLoop();
通過本文的學習,你應該已經掌握了如何使用 JavaScript 實現一個簡單的 Flappy Bird 游戲。雖然這個游戲相對簡單,但它涵蓋了游戲開發中的許多基本概念。你可以在此基礎上進一步擴展游戲的功能,例如添加背景音樂、增加難度、優化圖形等。
希望這篇文章能幫助你理解如何使用 JavaScript 開發簡單的游戲,并激發你進一步探索游戲開發的興趣。祝你編程愉快!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。