Skip to content

Commit 8076d2e

Browse files
structure change
1 parent f9cce9c commit 8076d2e

8 files changed

Lines changed: 1449 additions & 1527 deletions

File tree

flappy-bird/index.html

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Flappy Bird</title>
7+
<link rel="stylesheet" href="styles.css">
8+
</head>
9+
<body>
10+
<div class="game-container">
11+
<div class="score-display">0</div>
12+
13+
<canvas id="gameCanvas" width="360" height="640"></canvas>
14+
15+
<div class="start-screen">
16+
<h1>FLAPPY BIRD</h1>
17+
<p>Click, tap, or press SPACE to fly</p>
18+
<p>Avoid the pipes and don't hit the ground!</p>
19+
<button id="startButton">START GAME</button>
20+
<div class="instructions">Press SPACE or click to flap</div>
21+
</div>
22+
23+
<div class="game-over">
24+
<h1>GAME OVER</h1>
25+
<p>Your score: <span id="finalScore">0</span></p>
26+
<button id="restartButton">PLAY AGAIN</button>
27+
<div class="instructions">Press SPACE or click to restart</div>
28+
</div>
29+
</div>
30+
31+
<script src="script.js"></script>
32+
</body>
33+
</html>

flappy-bird/script.js

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
const canvas = document.getElementById('gameCanvas');
2+
const ctx = canvas.getContext('2d');
3+
const scoreDisplay = document.querySelector('.score-display');
4+
const startScreen = document.querySelector('.start-screen');
5+
const gameOverScreen = document.querySelector('.game-over');
6+
const finalScoreDisplay = document.getElementById('finalScore');
7+
const startButton = document.getElementById('startButton');
8+
const restartButton = document.getElementById('restartButton');
9+
10+
let gameRunning = false;
11+
let score = 0;
12+
let frames = 0;
13+
14+
const bird = {
15+
x: 50,
16+
y: canvas.height / 2,
17+
width: 34,
18+
height: 24,
19+
gravity: 0.5,
20+
velocity: 0,
21+
jump: -10,
22+
23+
draw: function() {
24+
ctx.fillStyle = '#FFD700';
25+
ctx.beginPath();
26+
ctx.arc(this.x, this.y, 15, 0, Math.PI * 2);
27+
ctx.fill();
28+
29+
ctx.fillStyle = 'black';
30+
ctx.beginPath();
31+
ctx.arc(this.x + 8, this.y - 3, 4, 0, Math.PI * 2);
32+
ctx.fill();
33+
34+
ctx.fillStyle = '#FF6B35';
35+
ctx.beginPath();
36+
ctx.moveTo(this.x + 15, this.y);
37+
ctx.lineTo(this.x + 30, this.y);
38+
ctx.lineTo(this.x + 15, this.y + 8);
39+
ctx.fill();
40+
41+
ctx.fillStyle = '#FFA500';
42+
ctx.beginPath();
43+
ctx.ellipse(this.x - 5, this.y + 5, 10, 6, Math.PI/4, 0, Math.PI * 2);
44+
ctx.fill();
45+
},
46+
47+
update: function() {
48+
if (gameRunning) {
49+
this.velocity += this.gravity;
50+
this.y += this.velocity;
51+
52+
if (this.y + this.height/2 >= canvas.height - ground.height) {
53+
this.y = canvas.height - ground.height - this.height/2;
54+
if (gameRunning) gameOver();
55+
}
56+
57+
if (this.y - this.height/2 <= 0) {
58+
this.y = this.height/2;
59+
this.velocity = 0;
60+
}
61+
}
62+
},
63+
64+
flap: function() {
65+
this.velocity = this.jump;
66+
},
67+
68+
reset: function() {
69+
this.y = canvas.height / 2;
70+
this.velocity = 0;
71+
}
72+
};
73+
74+
const ground = {
75+
height: 80,
76+
77+
draw: function() {
78+
ctx.fillStyle = '#D2691E';
79+
ctx.fillRect(0, canvas.height - this.height, canvas.width, this.height);
80+
81+
ctx.fillStyle = '#2E8B57';
82+
ctx.fillRect(0, canvas.height - this.height, canvas.width, 15);
83+
84+
ctx.fillStyle = '#8B4513';
85+
for (let i = 0; i < canvas.width; i += 30) {
86+
ctx.fillRect(i, canvas.height - 20, 15, 5);
87+
}
88+
}
89+
};
90+
91+
const pipes = {
92+
position: [],
93+
gap: 180,
94+
maxYPos: -150,
95+
dx: 2,
96+
97+
draw: function() {
98+
for (let i = 0; i < this.position.length; i++) {
99+
let p = this.position[i];
100+
101+
ctx.fillStyle = '#2E8B57';
102+
ctx.fillRect(p.x, p.y, p.width, p.height);
103+
104+
ctx.fillStyle = '#228B22';
105+
ctx.fillRect(p.x - 5, p.y + p.height - 20, p.width + 10, 20);
106+
107+
ctx.fillStyle = '#2E8B57';
108+
ctx.fillRect(p.x, p.y + p.height + this.gap, p.width, canvas.height);
109+
110+
ctx.fillStyle = '#228B22';
111+
ctx.fillRect(p.x - 5, p.y + p.height + this.gap, p.width + 10, 20);
112+
}
113+
},
114+
115+
update: function() {
116+
if (gameRunning) {
117+
if (frames % 100 === 0) {
118+
this.position.push({
119+
x: canvas.width,
120+
y: this.maxYPos * (Math.random() + 1),
121+
width: 60,
122+
height: 300
123+
});
124+
}
125+
126+
for (let i = 0; i < this.position.length; i++) {
127+
let p = this.position[i];
128+
129+
p.x -= this.dx;
130+
131+
if (p.x + p.width <= 0) {
132+
this.position.shift();
133+
score++;
134+
scoreDisplay.textContent = score;
135+
}
136+
137+
if (
138+
bird.x + bird.width/2 > p.x &&
139+
bird.x - bird.width/2 < p.x + p.width &&
140+
bird.y - bird.height/2 < p.y + p.height
141+
) {
142+
gameOver();
143+
}
144+
145+
if (
146+
bird.x + bird.width/2 > p.x &&
147+
bird.x - bird.width/2 < p.x + p.width &&
148+
bird.y + bird.height/2 > p.y + p.height + this.gap
149+
) {
150+
gameOver();
151+
}
152+
}
153+
}
154+
},
155+
156+
reset: function() {
157+
this.position = [];
158+
}
159+
};
160+
161+
const background = {
162+
draw: function() {
163+
ctx.fillStyle = '#70c5ce';
164+
ctx.fillRect(0, 0, canvas.width, canvas.height);
165+
166+
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
167+
ctx.beginPath();
168+
ctx.arc(100, 80, 30, 0, Math.PI * 2);
169+
ctx.arc(130, 70, 35, 0, Math.PI * 2);
170+
ctx.arc(160, 80, 25, 0, Math.PI * 2);
171+
ctx.fill();
172+
173+
ctx.beginPath();
174+
ctx.arc(300, 120, 30, 0, Math.PI * 2);
175+
ctx.arc(330, 110, 35, 0, Math.PI * 2);
176+
ctx.arc(360, 120, 25, 0, Math.PI * 2);
177+
ctx.fill();
178+
}
179+
};
180+
181+
function draw() {
182+
background.draw();
183+
pipes.draw();
184+
ground.draw();
185+
bird.draw();
186+
}
187+
188+
function update() {
189+
bird.update();
190+
pipes.update();
191+
}
192+
193+
function gameLoop() {
194+
update();
195+
draw();
196+
frames++;
197+
198+
requestAnimationFrame(gameLoop);
199+
}
200+
201+
function startGame() {
202+
gameRunning = true;
203+
score = 0;
204+
frames = 0;
205+
scoreDisplay.textContent = score;
206+
bird.reset();
207+
pipes.reset();
208+
startScreen.style.display = 'none';
209+
gameOverScreen.style.display = 'none';
210+
}
211+
212+
function gameOver() {
213+
gameRunning = false;
214+
finalScoreDisplay.textContent = score;
215+
gameOverScreen.style.display = 'block';
216+
}
217+
218+
document.addEventListener('keydown', function(e) {
219+
if (e.code === 'Space') {
220+
if (!gameRunning && gameOverScreen.style.display === 'block') {
221+
startGame();
222+
} else if (gameRunning) {
223+
bird.flap();
224+
}
225+
}
226+
});
227+
228+
canvas.addEventListener('click', function() {
229+
if (!gameRunning && gameOverScreen.style.display === 'block') {
230+
startGame();
231+
} else if (gameRunning) {
232+
bird.flap();
233+
}
234+
});
235+
236+
canvas.addEventListener('touchstart', function(e) {
237+
if (!gameRunning && gameOverScreen.style.display === 'block') {
238+
startGame();
239+
} else if (gameRunning) {
240+
bird.flap();
241+
}
242+
e.preventDefault();
243+
});
244+
245+
startButton.addEventListener('click', startGame);
246+
restartButton.addEventListener('click', startGame);
247+
248+
draw();
249+
gameLoop();

flappy-bird/styles.css

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
body {
2+
margin: 0;
3+
padding: 0;
4+
display: flex;
5+
justify-content: center;
6+
align-items: center;
7+
height: 100vh;
8+
background: linear-gradient(to bottom, #1a2a6c, #b21f1f, #1a2a6c);
9+
font-family: 'Arial Rounded MT Bold', 'Arial', sans-serif;
10+
overflow: hidden;
11+
}
12+
13+
.game-container {
14+
position: relative;
15+
width: 360px;
16+
text-align: center;
17+
}
18+
19+
#gameCanvas {
20+
background: #70c5ce;
21+
border-radius: 10px;
22+
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
23+
display: block;
24+
}
25+
26+
.score-display {
27+
position: absolute;
28+
top: 20px;
29+
left: 0;
30+
right: 0;
31+
text-align: center;
32+
font-size: 40px;
33+
font-weight: bold;
34+
color: white;
35+
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
36+
z-index: 10;
37+
}
38+
39+
.start-screen, .game-over {
40+
position: absolute;
41+
top: 50%;
42+
left: 50%;
43+
transform: translate(-50%, -50%);
44+
background: rgba(0, 0, 0, 0.8);
45+
color: white;
46+
padding: 30px;
47+
border-radius: 15px;
48+
text-align: center;
49+
z-index: 20;
50+
width: 80%;
51+
}
52+
53+
.game-over {
54+
display: none;
55+
}
56+
57+
h1 {
58+
color: #ffcc00;
59+
margin-bottom: 20px;
60+
font-size: 32px;
61+
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
62+
}
63+
64+
p {
65+
margin: 15px 0;
66+
line-height: 1.5;
67+
}
68+
69+
button {
70+
background: #ff6b6b;
71+
color: white;
72+
border: none;
73+
padding: 12px 25px;
74+
font-size: 18px;
75+
border-radius: 50px;
76+
cursor: pointer;
77+
margin-top: 20px;
78+
font-weight: bold;
79+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
80+
transition: all 0.3s;
81+
}
82+
83+
button:hover {
84+
background: #ff5252;
85+
transform: translateY(-2px);
86+
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4);
87+
}
88+
89+
.instructions {
90+
margin-top: 20px;
91+
font-size: 14px;
92+
color: #ccc;
93+
}

0 commit comments

Comments
 (0)