|
1 | | ---- |
2 | | -layout: bootstrap |
3 | | -title: Flappy |
4 | | -description: Flappy Game |
5 | | -permalink: /flappy |
6 | | -Author: Aarush |
7 | | ---- |
8 | | - |
9 | | -<style> |
10 | | - body { |
11 | | - background-color: #222; |
12 | | - color: #eee; |
13 | | - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
14 | | - } |
15 | | - #flappyCanvas { |
16 | | - display: block; |
17 | | - margin: 80px auto 0 auto; /* Increased top margin for more downward shift */ |
18 | | - background: linear-gradient(to bottom, #87ceeb 80%, #e0e0e0 100%); |
19 | | - border: 2px solid #333; |
20 | | - width: 90vw; |
21 | | - height: 80vh; |
22 | | - max-width: 900px; |
23 | | - max-height: 900px; |
24 | | - } |
25 | | - .flappy-center { |
26 | | - text-align: center; |
27 | | - margin-top: 10px; |
28 | | - } |
29 | | - .flappy-btn { |
30 | | - font-size: 1.1em; |
31 | | - margin: 8px; |
32 | | - padding: 6px 18px; |
33 | | - border-radius: 6px; |
34 | | - border: none; |
35 | | - background: #ffd700; |
36 | | - color: #222; |
37 | | - font-weight: bold; |
38 | | - cursor: pointer; |
39 | | - } |
40 | | - .flappy-settings { |
41 | | - position: absolute; |
42 | | - top: 200px; /* Move settings panel down to match canvas shift */ |
43 | | - right: 5vw; |
44 | | - background: #222; |
45 | | - color: #ffd700; |
46 | | - border: 2px solid #ffd700; |
47 | | - border-radius: 10px; |
48 | | - padding: 18px 18px 10px 18px; |
49 | | - min-width: 180px; |
50 | | - z-index: 10; |
51 | | - font-size: 1em; |
52 | | - } |
53 | | - .flappy-settings label { |
54 | | - display: block; |
55 | | - margin-bottom: 6px; |
56 | | - margin-top: 10px; |
57 | | - font-weight: bold; |
58 | | - } |
59 | | - .flappy-settings input[type="range"] { |
60 | | - width: 100%; |
61 | | - } |
62 | | - .flappy-settings span { |
63 | | - font-size: 1em; |
64 | | - color: #fff; |
65 | | - margin-left: 8px; |
66 | | - } |
67 | | -</style> |
68 | | - |
69 | | -<h1 class="flappy-center">Flappy Bird</h1> |
70 | | -<p class="flappy-center">Press <b>Space</b> or click/tap to jump. Avoid the pipes!</p> |
71 | | -<div class="flappy-center"> |
72 | | - <button id="flappyRestart" class="flappy-btn" style="display:none;">Restart</button> |
73 | | -</div> |
74 | | - |
75 | | -<!-- Settings Panel --> |
76 | | -<div class="flappy-settings" id="flappySettings"> |
77 | | - <label for="speedRange">Pipe Speed: <span id="speedValue"></span></label> |
78 | | - <input type="range" id="speedRange" min="1" max="8" step="0.1" value="2.5"> |
79 | | - <label for="jumpRange">Jump Height: <span id="jumpValue"></span></label> |
80 | | - <input type="range" id="jumpRange" min="-16" max="-4" step="0.1" value="-8"> |
81 | | -</div> |
82 | | - |
83 | | -<canvas id="flappyCanvas" width="900" height="800"></canvas> |
84 | | -<div class="flappy-center" id="flappyScore"></div> |
85 | | - |
86 | | -<script> |
87 | | - const canvas = document.getElementById('flappyCanvas'); |
88 | | - const ctx = canvas.getContext('2d'); |
89 | | - const width = canvas.width; |
90 | | - const height = canvas.height; |
91 | | - |
92 | | - // Settings elements |
93 | | - const speedRange = document.getElementById('speedRange'); |
94 | | - const jumpRange = document.getElementById('jumpRange'); |
95 | | - const speedValue = document.getElementById('speedValue'); |
96 | | - const jumpValue = document.getElementById('jumpValue'); |
97 | | - |
98 | | - // Bird |
99 | | - const bird = { |
100 | | - x: 80, |
101 | | - y: height / 2, |
102 | | - radius: 18, |
103 | | - velocity: 0, |
104 | | - gravity: 0.5, |
105 | | - jump: Number(jumpRange.value) |
106 | | - }; |
107 | | - |
108 | | - // Pipes |
109 | | - let pipes = []; |
110 | | - const pipeWidth = 60; |
111 | | - const pipeGap = 150; |
112 | | - let pipeSpeed = Number(speedRange.value); |
113 | | - let frame = 0; |
114 | | - let score = 0; |
115 | | - let bestScore = 0; |
116 | | - let gameOver = false; |
117 | | - let started = false; |
118 | | - |
119 | | - // Update settings display |
120 | | - function updateSettingsDisplay() { |
121 | | - speedValue.textContent = pipeSpeed.toFixed(1); |
122 | | - jumpValue.textContent = Math.abs(bird.jump).toFixed(1); |
123 | | - } |
124 | | - |
125 | | - // Listen for settings changes |
126 | | - speedRange.addEventListener('input', function () { |
127 | | - pipeSpeed = Number(speedRange.value); |
128 | | - updateSettingsDisplay(); |
129 | | - }); |
130 | | - jumpRange.addEventListener('input', function () { |
131 | | - bird.jump = Number(jumpRange.value); |
132 | | - updateSettingsDisplay(); |
133 | | - }); |
134 | | - |
135 | | - updateSettingsDisplay(); |
136 | | - |
137 | | - function showRestartButton(show) { |
138 | | - document.getElementById('flappyRestart').style.display = show ? '' : 'none'; |
139 | | - } |
140 | | - |
141 | | - function resetGame() { |
142 | | - bird.y = height / 2; |
143 | | - bird.velocity = 0; |
144 | | - pipes = []; |
145 | | - frame = 0; |
146 | | - score = 0; |
147 | | - gameOver = false; |
148 | | - started = false; |
149 | | - document.getElementById('flappyScore').textContent = ''; |
150 | | - showRestartButton(false); |
151 | | - } |
152 | | - |
153 | | - function drawBird() { |
154 | | - ctx.save(); |
155 | | - // Body (ellipse) |
156 | | - ctx.beginPath(); |
157 | | - ctx.ellipse(bird.x, bird.y, bird.radius + 6, bird.radius, 0, 0, Math.PI * 2); |
158 | | - ctx.fillStyle = "#ffe066"; |
159 | | - ctx.shadowColor = "#e1a800"; |
160 | | - ctx.shadowBlur = 10; |
161 | | - ctx.fill(); |
162 | | - ctx.shadowBlur = 0; |
163 | | - ctx.strokeStyle = "#e1a800"; |
164 | | - ctx.lineWidth = 2; |
165 | | - ctx.stroke(); |
166 | | - |
167 | | - // Wing |
168 | | - ctx.save(); |
169 | | - ctx.translate(bird.x - 8, bird.y + 2); |
170 | | - ctx.rotate(-0.2); |
171 | | - ctx.beginPath(); |
172 | | - ctx.ellipse(0, 0, bird.radius / 1.7, bird.radius / 2.2, 0, 0, Math.PI * 2); |
173 | | - ctx.fillStyle = "#fffbe0"; |
174 | | - ctx.globalAlpha = 0.85; |
175 | | - ctx.fill(); |
176 | | - ctx.globalAlpha = 1; |
177 | | - ctx.restore(); |
178 | | - |
179 | | - // Beak (triangle) |
180 | | - ctx.beginPath(); |
181 | | - ctx.moveTo(bird.x + bird.radius + 10, bird.y - 2); |
182 | | - ctx.lineTo(bird.x + bird.radius + 22, bird.y - 6); |
183 | | - ctx.lineTo(bird.x + bird.radius + 10, bird.y + 6); |
184 | | - ctx.closePath(); |
185 | | - ctx.fillStyle = "#ff9900"; |
186 | | - ctx.fill(); |
187 | | - ctx.strokeStyle = "#d17a00"; |
188 | | - ctx.stroke(); |
189 | | - |
190 | | - // Eye white |
191 | | - ctx.beginPath(); |
192 | | - ctx.arc(bird.x + 12, bird.y - 7, 7, 0, Math.PI * 2); |
193 | | - ctx.fillStyle = "#fff"; |
194 | | - ctx.fill(); |
195 | | - ctx.strokeStyle = "#bbb"; |
196 | | - ctx.lineWidth = 1.2; |
197 | | - ctx.stroke(); |
198 | | - |
199 | | - // Eye black |
200 | | - ctx.beginPath(); |
201 | | - ctx.arc(bird.x + 14, bird.y - 7, 3, 0, Math.PI * 2); |
202 | | - ctx.fillStyle = "#222"; |
203 | | - ctx.fill(); |
204 | | - |
205 | | - // Eyebrow |
206 | | - ctx.beginPath(); |
207 | | - ctx.moveTo(bird.x + 8, bird.y - 13); |
208 | | - ctx.lineTo(bird.x + 18, bird.y - 15); |
209 | | - ctx.strokeStyle = "#222"; |
210 | | - ctx.lineWidth = 2; |
211 | | - ctx.stroke(); |
212 | | - |
213 | | - ctx.restore(); |
214 | | - } |
215 | | - |
216 | | - function drawPipes() { |
217 | | - ctx.fillStyle = "#228B22"; |
218 | | - pipes.forEach(pipe => { |
219 | | - // Top pipe |
220 | | - ctx.fillRect(pipe.x, 0, pipeWidth, pipe.top); |
221 | | - // Bottom pipe |
222 | | - ctx.fillRect(pipe.x, pipe.bottom, pipeWidth, height - pipe.bottom); |
223 | | - }); |
224 | | - } |
225 | | - |
226 | | - function drawScore() { |
227 | | - ctx.save(); |
228 | | - ctx.font = "bold 32px Arial"; |
229 | | - ctx.fillStyle = "#fff"; |
230 | | - ctx.strokeStyle = "#222"; |
231 | | - ctx.lineWidth = 3; |
232 | | - ctx.textAlign = "center"; |
233 | | - ctx.strokeText(score, width / 2, 60); |
234 | | - ctx.fillText(score, width / 2, 60); |
235 | | - ctx.restore(); |
236 | | - } |
237 | | - |
238 | | - function update() { |
239 | | - if (gameOver) return; |
240 | | - if (!started) return; |
241 | | - bird.velocity += bird.gravity; |
242 | | - bird.y += bird.velocity; |
243 | | - |
244 | | - // Add pipes |
245 | | - if (frame % 90 === 0) { |
246 | | - const top = Math.random() * (height - pipeGap - 120) + 40; |
247 | | - pipes.push({ |
248 | | - x: width, |
249 | | - top: top, |
250 | | - bottom: top + pipeGap, |
251 | | - passed: false |
252 | | - }); |
253 | | - } |
254 | | - |
255 | | - // Move pipes and check for collision |
256 | | - pipes.forEach(pipe => { |
257 | | - pipe.x -= pipeSpeed; |
258 | | - // Collision |
259 | | - if ( |
260 | | - bird.x + bird.radius > pipe.x && |
261 | | - bird.x - bird.radius < pipe.x + pipeWidth && |
262 | | - (bird.y - bird.radius < pipe.top || bird.y + bird.radius > pipe.bottom) |
263 | | - ) { |
264 | | - gameOver = true; |
265 | | - bestScore = Math.max(score, bestScore); |
266 | | - document.getElementById('flappyScore').innerHTML = `<b>Game Over!</b> Score: ${score} | Best: ${bestScore}`; |
267 | | - showRestartButton(true); |
268 | | - } |
269 | | - // Score |
270 | | - if (!pipe.passed && pipe.x + pipeWidth < bird.x) { |
271 | | - score++; |
272 | | - pipe.passed = true; |
273 | | - } |
274 | | - }); |
275 | | - |
276 | | - // Remove off-screen pipes |
277 | | - pipes = pipes.filter(pipe => pipe.x + pipeWidth > 0); |
278 | | - |
279 | | - // Ground or ceiling collision |
280 | | - if (bird.y + bird.radius > height || bird.y - bird.radius < 0) { |
281 | | - gameOver = true; |
282 | | - bestScore = Math.max(score, bestScore); |
283 | | - document.getElementById('flappyScore').innerHTML = `<b>Game Over!</b> Score: ${score} | Best: ${bestScore}`; |
284 | | - showRestartButton(true); |
285 | | - } |
286 | | - |
287 | | - frame++; |
288 | | - } |
289 | | - |
290 | | - function draw() { |
291 | | - ctx.clearRect(0, 0, width, height); |
292 | | - drawPipes(); |
293 | | - drawBird(); |
294 | | - drawScore(); |
295 | | - } |
296 | | - |
297 | | - function loop() { |
298 | | - update(); |
299 | | - draw(); |
300 | | - if (!gameOver) { |
301 | | - requestAnimationFrame(loop); |
302 | | - } |
303 | | - } |
304 | | - |
305 | | - function jump() { |
306 | | - if (!started) { |
307 | | - started = true; |
308 | | - gameOver = false; |
309 | | - pipes = []; |
310 | | - frame = 0; |
311 | | - score = 0; |
312 | | - document.getElementById('flappyScore').textContent = ''; |
313 | | - bird.y = height / 2; |
314 | | - bird.velocity = 0; |
315 | | - showRestartButton(false); |
316 | | - loop(); |
317 | | - } |
318 | | - if (!gameOver) { |
319 | | - bird.velocity = bird.jump; |
320 | | - } |
321 | | - } |
322 | | - |
323 | | - document.addEventListener('keydown', (e) => { |
324 | | - if (e.code === 'Space') { |
325 | | - e.preventDefault(); // Prevent page from scrolling down |
326 | | - jump(); |
327 | | - } |
328 | | - if (e.key && e.key.toLowerCase() === 'r') { |
329 | | - resetGame(); |
330 | | - draw(); |
331 | | - } |
332 | | - }); |
333 | | - |
334 | | - canvas.addEventListener('mousedown', jump); |
335 | | - canvas.addEventListener('touchstart', jump); |
336 | | - |
337 | | - document.getElementById('flappyRestart').onclick = () => { |
338 | | - resetGame(); |
339 | | - draw(); |
340 | | - }; |
341 | | - |
342 | | - // Initial draw |
343 | | - resetGame(); |
344 | | - draw(); |
345 | | -</script> |
346 | | - |
347 | | -<script> |
348 | | -// filepath: /home/kasm-user/nighthawk/GenomeGamersFrontend/navigation/Worlds/world0.md |
349 | | -// ...existing code... |
350 | | - |
351 | | -// --- Background Music --- |
352 | | -const music = new Audio('{{site.baseurl}}/assets/audio/7anxiety.mp3'); // Change path as needed |
353 | | -music.loop = true; |
354 | | -music.volume = 0.5; |
355 | | - |
356 | | -// Play music after first user interaction (required by browsers) |
357 | | -function startMusicOnce() { |
358 | | - music.play().catch(() => {}); |
359 | | - window.removeEventListener('click', startMusicOnce); |
360 | | - window.removeEventListener('keydown', startMusicOnce); |
361 | | -} |
362 | | -window.addEventListener('click', startMusicOnce); |
363 | | -window.addEventListener('keydown', startMusicOnce); |
364 | | -</script> |
0 commit comments