comparison birthday_page/pages/index.html @ 34:6c322f9c2cb9

[Birthday] I didn't have nay time to buy birhtday present so w/e/
author MrJuneJune <me@mrjunejune.com>
date Sat, 11 Oct 2025 15:07:07 -0700
parents
children 6639f5389f47
comparison
equal deleted inserted replaced
33:c0f6c8c7829f 34:6c322f9c2cb9
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 <link rel="preload" href="/punpun.png" as="image">
7 <link rel="preload" href="/random_1.jpeg" as="image">
8 <link rel="preload" href="/random_2.png" as="image">
9 <link rel="preload" href="/random_3.jpeg" as="image">
10 <title>Dino Birthday Game</title>
11 <style>
12 * {
13 margin: 0;
14 padding: 0;
15 box-sizing: border-box;
16 }
17
18 body {
19 font-family: Arial, sans-serif;
20 display: flex;
21 justify-content: center;
22 align-items: center;
23 min-height: 100vh;
24 background: linear-gradient(to bottom, #87CEEB 0%, #E0F6FF 100%);
25 touch-action: manipulation;
26 }
27
28 #gameContainer {
29 position: relative;
30 width: 100%;
31 max-width: 800px;
32 height: 400px;
33 background-image: url('/background.avif'); /* Replace with your actual image path */
34 background-size: cover; /* Ensures the image covers the entire element */
35 background-repeat: no-repeat; /* Prevents tiling */
36 overflow: hidden;
37 border: 3px solid #333;
38 box-shadow: 0 10px 30px rgba(0,0,0,0.3);
39 }
40
41 #ground {
42 position: absolute;
43 bottom: 0;
44 width: 100%;
45 height: 50px;
46 background: #c2b280;
47 border-top: 3px solid #8b7355;
48 }
49
50 #dino {
51 position: absolute;
52 bottom: 50px;
53 left: 50px;
54 width: 40px;
55 height: 50px;
56 background-image: url('/punpun.png'); /* Replace with your actual image path */
57 background-size: cover; /* Ensures the image covers the entire element */
58 background-repeat: no-repeat; /* Prevents tiling */
59 border-radius: 5px;
60 transition: none;
61 }
62
63 .obstacle {
64 position: absolute;
65 bottom: 50px;
66 width: 100px;
67 height: 50px;
68 background: #8b4513;
69 border-radius: 3px;
70 }
71
72 .random_1 {
73 background-image: url('/random_1.jpeg'); /* Replace with your actual image path */
74 background-size: cover; /* Ensures the image covers the entire element */
75 }
76
77 .random_2 {
78 background-image: url('/random_2.png'); /* Replace with your actual image path */
79 background-size: cover; /* Ensures the image covers the entire element */
80 }
81
82 .random_3 {
83 background-image: url('/random_3.jpeg'); /* Replace with your actual image path */
84 background-size: cover; /* Ensures the image covers the entire element */
85 }
86
87
88
89 #goal {
90 position: absolute;
91 bottom: 50px;
92 width: 50px;
93 height: 60px;
94 background: linear-gradient(45deg, #ff69b4, #ff1493);
95 border-radius: 10px;
96 display: none;
97 }
98
99 #score {
100 position: absolute;
101 top: 20px;
102 right: 20px;
103 font-size: 24px;
104 font-weight: bold;
105 color: #333;
106 }
107
108 #message {
109 position: absolute;
110 top: 50%;
111 left: 50%;
112 transform: translate(-50%, -50%);
113 font-size: 32px;
114 font-weight: bold;
115 color: #ff1493;
116 text-align: center;
117 display: none;
118 background: rgba(255, 255, 255, 0.9);
119 padding: 30px;
120 border-radius: 15px;
121 box-shadow: 0 5px 20px rgba(0,0,0,0.3);
122 }
123
124 #startBtn {
125 position: absolute;
126 top: 50%;
127 left: 50%;
128 transform: translate(-50%, -50%);
129 padding: 15px 40px;
130 font-size: 24px;
131 background: #4CAF50;
132 color: white;
133 border: none;
134 border-radius: 10px;
135 cursor: pointer;
136 font-weight: bold;
137 box-shadow: 0 5px 15px rgba(0,0,0,0.3);
138 }
139
140 #startBtn:hover {
141 background: #45a049;
142 }
143
144 .confetti {
145 position: absolute;
146 width: 10px;
147 height: 10px;
148 background: #ff0;
149 animation: fall 3s linear;
150 }
151
152 @keyframes fall {
153 to {
154 transform: translateY(400px) rotate(360deg);
155 opacity: 0;
156 }
157 }
158
159 @media (max-width: 600px) {
160 #gameContainer {
161 height: 300px;
162 }
163
164 #score {
165 font-size: 18px;
166 }
167
168 #message {
169 font-size: 24px;
170 padding: 20px;
171 }
172 }
173 </style>
174 </head>
175 <body>
176 <div id="gameContainer">
177 <div id="ground"></div>
178 <div id="dino"></div>
179 <div id="goal"></div>
180 <div id="score">Distance: 0m</div>
181 <div id="message"></div>
182 <button id="startBtn">START GAME</button>
183 </div>
184
185 <script>
186 const dino = document.getElementById('dino');
187 const gameContainer = document.getElementById('gameContainer');
188 const scoreEl = document.getElementById('score');
189 const messageEl = document.getElementById('message');
190 const startBtn = document.getElementById('startBtn');
191 const goal = document.getElementById('goal');
192
193 let isJumping = false;
194 let gameRunning = false;
195 let obstacles = [];
196 let distance = 0;
197 let gameSpeed = 5;
198 const goalDistance = 500;
199
200 function jump() {
201 if (isJumping || !gameRunning) return;
202
203 isJumping = true;
204 let jumpHeight = 0;
205 let jumpUp = setInterval(() => {
206 if (jumpHeight >= 120) {
207 clearInterval(jumpUp);
208 let jumpDown = setInterval(() => {
209 if (jumpHeight <= 0) {
210 clearInterval(jumpDown);
211 isJumping = false;
212 jumpHeight = 0;
213 }
214 jumpHeight -= 5;
215 dino.style.bottom = (50 + jumpHeight) + 'px';
216 }, 20);
217 }
218 jumpHeight += 5;
219 dino.style.bottom = (50 + jumpHeight) + 'px';
220 }, 20);
221 }
222
223 document.addEventListener('keydown', (e) => {
224 if (e.code === 'Space' || e.code === 'ArrowUp') {
225 e.preventDefault();
226 jump();
227 }
228 });
229
230 gameContainer.addEventListener('click', jump);
231 gameContainer.addEventListener('touchstart', (e) => {
232 e.preventDefault();
233 jump();
234 });
235
236 function createObstacle() {
237 const randomVal = Math.floor(Math.random() * 3) + 1;
238 const obstacle = document.createElement('div');
239 obstacle.classList.add(`obstacle`);
240 obstacle.classList.add(`random_${randomVal}`);
241 obstacle.style.right = '-80px';
242 gameContainer.appendChild(obstacle);
243 obstacles.push(obstacle);
244 }
245
246 function createConfetti() {
247 for (let i = 0; i < 50; i++) {
248 setTimeout(() => {
249 const confetti = document.createElement('div');
250 confetti.classList.add('confetti');
251 confetti.style.left = Math.random() * 100 + '%';
252 confetti.style.background = `hsl(${Math.random() * 360}, 100%, 50%)`;
253 gameContainer.appendChild(confetti);
254 setTimeout(() => confetti.remove(), 3000);
255 }, i * 50);
256 }
257 }
258
259 function checkCollision(obstacle) {
260 const dinoRect = dino.getBoundingClientRect();
261 const obstacleRect = obstacle.getBoundingClientRect();
262
263 return !(dinoRect.right < obstacleRect.left ||
264 dinoRect.left > obstacleRect.right ||
265 dinoRect.bottom < obstacleRect.top ||
266 dinoRect.top > obstacleRect.bottom);
267 }
268
269 function checkGoalReached() {
270 const dinoRect = dino.getBoundingClientRect();
271 const goalRect = goal.getBoundingClientRect();
272
273 return !(dinoRect.right < goalRect.left ||
274 dinoRect.left > goalRect.right);
275 }
276
277 function gameOver() {
278 gameRunning = false;
279 messageEl.textContent = 'Game Over! Click START to try again';
280 messageEl.style.display = 'block';
281 startBtn.style.display = 'block';
282 obstacles.forEach(obs => obs.remove());
283 obstacles = [];
284 goal.style.display = 'none';
285 }
286
287 function winGame() {
288 gameRunning = false;
289 messageEl.innerHTML = '🎉 HAPPY BIRTHDAY! 🎉<br>You made it to the end!<br> Also I didnt buy any present ^_^';
290 messageEl.style.display = 'block';
291 createConfetti();
292 obstacles.forEach(obs => obs.remove());
293 obstacles = [];
294 }
295
296 function gameLoop() {
297 if (!gameRunning) return;
298
299 distance += 0.1;
300 scoreEl.textContent = `Distance: ${Math.floor(distance)}m`;
301
302 if (distance >= goalDistance && goal.style.display === 'none') {
303 goal.style.display = 'block';
304 goal.style.right = '-50px';
305 goal.style.color = 'dodgerblue';
306 }
307
308 obstacles.forEach((obstacle, index) => {
309 let right = parseInt(window.getComputedStyle(obstacle).right);
310 obstacle.style.right = (right + gameSpeed) + 'px';
311
312 if (right > gameContainer.offsetWidth) {
313 obstacle.remove();
314 obstacles.splice(index, 1);
315 }
316
317 if (checkCollision(obstacle)) {
318 gameOver();
319 }
320 });
321
322 if (goal.style.display === 'block') {
323 let goalRight = parseInt(window.getComputedStyle(goal).right);
324 goal.style.right = (goalRight + gameSpeed) + 'px';
325
326 if (checkGoalReached()) {
327 winGame();
328 return;
329 }
330 }
331
332 requestAnimationFrame(gameLoop);
333 }
334
335 function startGame() {
336 gameRunning = true;
337 distance = 0;
338 gameSpeed = 5;
339 gracePeriod = 15;
340 startBtn.style.display = 'none';
341 messageEl.style.display = 'none';
342 goal.style.display = 'none';
343
344 let obstacleInterval = setInterval(() => {
345 if (!gameRunning || distance < gracePeriod) {
346 clearInterval(obstacleInterval);
347 return;
348 }
349
350 if (Math.random() > 0.3) {
351 createObstacle();
352 }
353 }, 1500);
354
355 gameLoop();
356 }
357
358 startBtn.addEventListener('click', startGame);
359 </script>
360 </body>
361 </html>