ProPerNounpYK commited on
Commit
4b2b7da
·
verified ·
1 Parent(s): d386683

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +158 -436
index.html CHANGED
@@ -1,204 +1,21 @@
1
  <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <style>
5
- body {
6
- margin: 0;
7
- overflow: hidden;
8
- background: #1a1a1a;
9
- display: flex;
10
- justify-content: center;
11
- align-items: center;
12
- min-height: 100vh;
13
- }
14
-
15
- canvas {
16
- cursor: pointer;
17
- }
18
- </style>
19
- </head>
20
- <body>
21
- <canvas id="canvas"></canvas>
22
-
23
- <script>
24
- const canvas = document.getElementById('canvas');
25
- const ctx = canvas.getContext('2d');
26
-
27
- let particles = [];
28
- const phrases = [
29
- { text: 'Hello everyone.', size: 65, duration: 5000 },
30
- { text: 'You have been selected as the next\nTimewalker for our team of Space Guardians.', size: 50, duration: 7000 },
31
- { text: 'Repair the collapsing timelines\nand return safely.', size: 55, duration: 6000 },
32
- { text: 'Good luck.\n- From the Space Guardians Leader', sizes: [65, 45], spacing: 45, duration: 6000 },
33
- { text: 'TimeWalker', size: 65, duration: 3000 },
34
- { text: 'Chapter 1', size: 65, duration: null }
35
- ];
36
-
37
- let currentPhraseIndex = 0;
38
- let animationFrame;
39
- let mouseX = 0;
40
- let mouseY = 0;
41
-
42
- canvas.width = window.innerWidth;
43
- canvas.height = window.innerHeight;
44
-
45
- class Particle {
46
- constructor(x, y, targetX, targetY) {
47
- this.x = Math.random() * canvas.width;
48
- this.y = Math.random() * canvas.height;
49
- this.targetX = targetX;
50
- this.targetY = targetY;
51
- this.dx = (Math.random() - 0.5) * 8;
52
- this.dy = (Math.random() - 0.5) * 8;
53
- this.radius = 2;
54
- this.alpha = 1;
55
- this.fadeSpeed = 0.02;
56
- }
57
-
58
- draw() {
59
- ctx.beginPath();
60
- ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
61
- ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`;
62
- ctx.fill();
63
- ctx.closePath();
64
- }
65
-
66
- update() {
67
- const distance = Math.hypot(mouseX - this.x, mouseY - this.y);
68
-
69
- if(distance < 100) {
70
- this.x += this.dx;
71
- this.y += this.dy;
72
- } else {
73
- this.x += (this.targetX - this.x) * 0.1;
74
- this.y += (this.targetY - this.y) * 0.1;
75
- }
76
- }
77
- }
78
-
79
- function createParticles(phrase) {
80
- let newParticles = [];
81
- ctx.clearRect(0, 0, canvas.width, canvas.height);
82
-
83
- const lines = phrase.text.split('\n');
84
-
85
- lines.forEach((line, index) => {
86
- const size = phrase.sizes ? phrase.sizes[index] : phrase.size;
87
- ctx.font = `${size}px Arial`;
88
- ctx.fillStyle = 'white';
89
- ctx.textAlign = 'center';
90
- ctx.textBaseline = 'middle';
91
-
92
- const spacing = phrase.spacing || size * 1.2;
93
- const y = (canvas.height/2 - 20) + (index - (lines.length-1)/2) * spacing;
94
- ctx.fillText(line, canvas.width/2, y);
95
- });
96
-
97
- const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
98
-
99
- for(let y = 0; y < canvas.height; y += 4) {
100
- for(let x = 0; x < canvas.width; x += 4) {
101
- const index = (y * canvas.width + x) * 4;
102
- const alpha = imageData[index + 3];
103
-
104
- if(alpha > 128) {
105
- newParticles.push(new Particle(x, y, x, y));
106
- }
107
- }
108
- }
109
-
110
- ctx.clearRect(0, 0, canvas.width, canvas.height);
111
- return newParticles;
112
- }
113
-
114
- function transition() {
115
- if(currentPhraseIndex < phrases.length - 1) {
116
- currentPhraseIndex++;
117
- const currentPhrase = phrases[currentPhraseIndex];
118
-
119
- particles.forEach(particle => {
120
- particle.dx = (Math.random() - 0.5) * 20;
121
- particle.dy = (Math.random() - 0.5) * 20;
122
- const fadeOut = setInterval(() => {
123
- particle.alpha -= particle.fadeSpeed;
124
- if(particle.alpha <= 0) clearInterval(fadeOut);
125
- }, 50);
126
- });
127
-
128
- setTimeout(() => {
129
- particles = createParticles(currentPhrase);
130
- particles.forEach(particle => {
131
- particle.alpha = 0;
132
- const fadeIn = setInterval(() => {
133
- particle.alpha += particle.fadeSpeed;
134
- if(particle.alpha >= 1) clearInterval(fadeIn);
135
- }, 50);
136
- });
137
- }, 800);
138
-
139
- if(currentPhrase.duration) {
140
- setTimeout(transition, currentPhrase.duration);
141
- }
142
- }
143
- }
144
-
145
- function animate() {
146
- ctx.clearRect(0, 0, canvas.width, canvas.height);
147
- particles.forEach(particle => {
148
- particle.update();
149
- particle.draw();
150
- });
151
- animationFrame = requestAnimationFrame(animate);
152
- }
153
-
154
- canvas.addEventListener('mousemove', (e) => {
155
- mouseX = e.clientX;
156
- mouseY = e.clientY;
157
- });
158
-
159
- window.addEventListener('resize', () => {
160
- canvas.width = window.innerWidth;
161
- canvas.height = window.innerHeight;
162
- particles = createParticles(phrases[currentPhraseIndex]);
163
- });
164
-
165
- particles = createParticles(phrases[0]);
166
- particles.forEach(particle => {
167
- particle.alpha = 0;
168
- const fadeIn = setInterval(() => {
169
- particle.alpha += particle.fadeSpeed;
170
- if(particle.alpha >= 1) clearInterval(fadeIn);
171
- }, 50);
172
- });
173
-
174
- animate();
175
- setTimeout(transition, phrases[0].duration);
176
-
177
- function playAudioForDuration(url, duration) {
178
- const audio = new Audio(url);
179
- audio.play();
180
- setTimeout(() => {
181
- audio.pause();
182
- audio.currentTime = 0; // Reset to start
183
- }, duration);
184
- }
185
-
186
- // Play audio for 31 seconds
187
- playAudioForDuration('reflected-light-147979.mp3', 31000);
188
-
189
- </script>
190
- </body>
191
- </html>
192
-
193
- after 1 second run this code:
194
- <!DOCTYPE html>
195
- <html>
196
  <head>
 
 
 
197
  <style>
198
  body {
199
  margin: 0;
200
  overflow: hidden;
201
- background: black;
 
 
 
 
 
 
 
202
  }
203
  #gameCanvas {
204
  background-image: url('stage 1.jpg');
@@ -228,11 +45,11 @@ after 1 second run this code:
228
  right: 20px;
229
  color: white;
230
  font-family: Arial;
231
- font-size: 28px;
232
  }
233
  #healthBar {
234
- width: 300px;
235
- height: 30px;
236
  background: #333;
237
  margin-top: 5px;
238
  }
@@ -243,7 +60,7 @@ after 1 second run this code:
243
  transition: width 0.3s;
244
  }
245
  #bulletCount, #enemyCount {
246
- font-size: 28px;
247
  }
248
  #replayButton {
249
  position: fixed;
@@ -266,10 +83,11 @@ after 1 second run this code:
266
  </style>
267
  </head>
268
  <body>
 
269
  <canvas id="gameCanvas"></canvas>
270
  <div id="message"></div>
271
  <div id="stats">
272
- Health:<div id="healthBar"><div id="healthFill"></div></div>
273
  Bullets: <span id="bulletCount">35</span>
274
  </div>
275
  <div id="villainCount">Villains: <span id="enemyCount">30</span></div>
@@ -281,267 +99,171 @@ after 1 second run this code:
281
  <audio id="enemyHitSound" src="Renovatorsgetshot.mp3"></audio>
282
 
283
  <script>
284
- const canvas = document.getElementById('gameCanvas');
 
 
285
  const ctx = canvas.getContext('2d');
286
- const message = document.getElementById('message');
287
- const healthFill = document.getElementById('healthFill');
288
- const bulletCount = document.getElementById('bulletCount');
289
- const enemyCount = document.getElementById('enemyCount');
290
- const bgMusic = document.getElementById('bgMusic');
291
- const replayButton = document.getElementById('replayButton');
292
- const playerShootSound = document.getElementById('playerShootSound');
293
- const enemyShootSound = document.getElementById('enemyShootSound');
294
- const playerHitSound = document.getElementById('playerHitSound');
295
- const enemyHitSound = document.getElementById('enemyHitSound');
 
 
 
 
296
 
297
  canvas.width = window.innerWidth;
298
  canvas.height = window.innerHeight;
299
 
300
- const player = {
301
- x: canvas.width / 2.3,
302
- y: canvas.height - 260,
303
- width: 250,
304
- height: 250,
305
- speed: 10,
306
- health: 10,
307
- bullets: 35,
308
- direction: 1,
309
- image: new Image(),
310
- imageLeft: 'Maincharacterdefaultleft.png',
311
- imageRight: 'Maincharacterdefaultright.png',
312
- imageShootLeft: 'gunshotleft.png',
313
- imageShootRight: 'gunshotright.png',
314
- imageHitLeft: 'ExplosionLeft.png',
315
- imageHitRight: 'ExplosionRight.png'
316
- };
317
- player.image.src = player.imageRight;
318
-
319
- let enemies = [];
320
- let bullets = [];
321
- let enemyBullets = [];
322
- let enemiesRemaining = 30;
323
- let mouseX = 0;
324
- let gameStarted = false;
325
- let gameOver = false;
326
-
327
- function spawnEnemy() {
328
- if (!gameStarted || gameOver) {
329
- return;
330
- }
331
-
332
- if (enemies.length >= 10) { // 동시에 존재할 수 있는 적의 수 제한
333
- return;
334
- }
335
-
336
- const side = Math.random() < 0.5 ? 0 : canvas.width;
337
- const enemy = {
338
- x: side,
339
- y: Math.random() * (canvas.height - 150),
340
- width: 250,
341
- height: 250,
342
- speed: side === 0 ? 1 : -1,
343
- image: new Image(),
344
- imageLeft: 'Renovators Default Right.png',
345
- imageRight: 'RenovatorsDefaultLeft.png',
346
- imageShootLeft: 'RenovatorsgunLeft.png',
347
- imageShootRight: 'RenovatorsGunRight.png',
348
- imageHitLeft: 'RenovatorsExplodeLeft.png',
349
- imageHitRight: 'RenovatorsExplodeRight.png',
350
- lastShootTime: Date.now()
351
- };
352
- enemy.image.src = side === 0 ? enemy.imageLeft : enemy.imageRight;
353
- enemies.push(enemy);
354
- }
355
- function updateGame() {
356
- ctx.clearRect(0, 0, canvas.width, canvas.height);
357
-
358
- player.direction = mouseX > player.x ? 1 : -1;
359
- player.image.src = player.direction === 1 ? player.imageRight : player.imageLeft;
360
- ctx.drawImage(player.image, player.x, player.y, player.width, player.height);
361
-
362
- // 플레이어가 발사한 총알 처리
363
- bullets.forEach((bullet, index) => {
364
- bullet.x += bullet.speed;
365
- ctx.fillStyle = 'yellow';
366
- ctx.fillRect(bullet.x, bullet.y, 10, 5);
367
- });
368
-
369
- // 적 처리
370
- enemies.forEach((enemy, enemyIndex) => {
371
- enemy.x += enemy.speed;
372
- ctx.drawImage(enemy.image, enemy.x, enemy.y, enemy.width, enemy.height);
373
-
374
- // 플레이어와 적이 충돌했을 경우 처리
375
- if (checkCollision(player, enemy)) {
376
- player.health--;
377
- healthFill.style.width = (player.health / 5 * 100) + '%';
378
- player.image.src = player.direction === 1 ? player.imageHitRight : player.imageHitLeft;
379
- enemies.splice(enemyIndex, 1); // 적 제거
380
- playerHitSound.play();
381
-
382
- if (player.health <= 0) {
383
- endGame("Game Over! Go back to the past and change the current result!");
384
  }
385
- }
386
 
387
- // 플레이어의 총알이 적을 맞췄을 경우 처리
388
- bullets.forEach((bullet, bulletIndex) => {
389
- if (checkCollision(bullet, enemy)) {
390
- // 총알이 적을 맞췄을 처리
391
- enemy.image.src = enemy.speed > 0 ? enemy.imageHitRight : enemy.imageHitLeft;
392
- setTimeout(() => {
393
- enemies.splice(enemyIndex, 1); // 적 제거
394
- bullets.splice(bulletIndex, 1); // 총알 제거
395
- enemiesRemaining--;
396
- enemyCount.textContent = enemiesRemaining;
397
- }, 100);
398
- enemyHitSound.play();
399
 
400
- if (enemiesRemaining <= 0) {
401
- endGame("You have successfully protected New York. Return to the time machine.");
 
 
 
 
 
 
402
  }
403
  }
404
- });
405
-
406
- // 적의 총알 발사
407
- enemyShoot(enemy);
408
- });
409
- if (enemiesRemaining <= 0 && enemies.length === 0) {
410
- endGame("You have successfully protected New York. Return to the time machine.");
411
- return; // 게임 종료 후 더 이상 업데이트하지 않음
412
- }
413
- // 적의 총알 처리
414
- enemyBullets.forEach((bullet, index) => {
415
- bullet.x += bullet.speed;
416
- ctx.fillStyle = 'orange';
417
- ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
418
-
419
- // 총알이 플레이어와 충돌했을 경우 처리
420
- if (
421
- bullet.x < player.x + player.width - 30 &&
422
- bullet.x + bullet.width > player.x + 30 &&
423
- bullet.y < player.y + player.height - 30 &&
424
- bullet.y + bullet.height > player.y + 30
425
- ) {
426
- player.health--;
427
- healthFill.style.width = (player.health / 5 * 100) + '%';
428
- player.image.src = player.direction === 1 ? player.imageHitRight : player.imageHitLeft;
429
- enemyBullets.splice(index, 1); // 총알 제거
430
- playerHitSound.play();
431
 
432
- if (player.health <= 0) {
433
- endGame("Game Over! Go back to the past and change the current result!");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  }
 
 
 
435
  }
436
- });
437
 
438
- // 화면 밖으로 나간 총알 제거
439
- bullets = bullets.filter(bullet =>
440
- bullet.x >= 0 && bullet.x <= canvas.width
441
- );
442
- enemyBullets = enemyBullets.filter(bullet =>
443
- bullet.x >= 0 && bullet.x <= canvas.width
444
- );
 
 
 
 
 
 
445
 
446
- // 게임이 종료되지 않으면 계속 업데이트
447
- if (!gameOver) {
448
- requestAnimationFrame(updateGame);
449
- }
450
- }
451
- setTimeout(() => {
452
- message.textContent = "Click on the character";
453
- setTimeout(() => {
454
- message.textContent = "You can move your character using the arrow keys.";
455
  setTimeout(() => {
456
- message.textContent = "The character's direction follows the mouse cursor.";
457
- setTimeout(() => {
458
- message.textContent = "Press the space bar to shoot a bullet.";
459
- setTimeout(() => {
460
- message.textContent = "Your mission is to defeat the Renovators who have attacked New York. Defeat them all and save New York in 2030!";
461
- setTimeout(() => {
462
- message.textContent = "";
463
- gameStarted = true;
464
- }, 5000);
465
- }, 3000);
466
- }, 4000);
467
- }, 4000);
468
- }, 4000);
469
- }, 0);
470
-
471
- function endGame(messageText) {
472
- gameOver = true;
473
- message.textContent = messageText;
474
- replayButton.style.display = 'block';
475
- }
476
- function checkCollision(rect1, rect2) {
477
- return (
478
- rect1.x + rect1.width * 0.2 < rect2.x + rect2.width * 0.8 &&
479
- rect1.x + rect1.width * 0.8 > rect2.x + rect2.width * 0.2 &&
480
- rect1.y + rect1.height * 0.2 < rect2.y + rect2.height * 0.8 &&
481
- rect1.y + rect1.height * 0.8 > rect2.y + rect2.height * 0.2
482
- );
483
- }
484
- function enemyShoot(enemy) {
485
- const now = Date.now();
486
- if (now - enemy.lastShootTime >= 3000 && !gameOver) {
487
- enemy.image.src = enemy.speed > 0 ? enemy.imageShootRight : enemy.imageShootLeft;
488
- enemyBullets.push({
489
- x: enemy.x + enemy.width / 2,
490
- y: enemy.y + enemy.height / 2.5,
491
- width: 10,
492
- height: 5,
493
- speed: enemy.speed > 0 ? 5 : -5
494
- });
495
- enemy.lastShootTime = now; // Update the last shoot time
496
- enemyShootSound.play();
497
  }
498
  }
499
 
500
- window.addEventListener('keydown', (e) => {
501
- if (!gameOver) {
502
- switch (e.key) {
503
- case 'ArrowUp':
504
- if (player.y > 0) player.y -= player.speed;
505
- break;
506
- case 'ArrowDown':
507
- if (player.y < canvas.height - player.height) player.y += player.speed;
508
- break;
509
- case 'ArrowLeft':
510
- if (player.x > 0) player.x -= player.speed;
511
- break;
512
- case 'ArrowRight':
513
- if (player.x < canvas.width - player.width) player.x += player.speed;
514
- break;
515
- case ' ':
516
- if (player.bullets > 0) {
517
- player.image.src = player.direction === 1 ? player.imageShootRight : player.imageShootLeft;
518
- bullets.push({
519
- x: player.x + player.width / 2,
520
- y: player.y + player.height / 2.5,
521
- width: 10,
522
- height: 5,
523
- speed: player.direction * 10
524
- });
525
- player.bullets--;
526
- bulletCount.textContent = player.bullets;
527
- playerShootSound.play();
528
- }
529
- break;
530
- }
531
- }
532
- });
533
 
534
- window.addEventListener('mousemove', (e) => {
535
  mouseX = e.clientX;
 
 
 
 
 
 
 
536
  });
537
 
538
- replayButton.addEventListener('click', () => {
539
- location.reload();
 
 
 
 
 
540
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
 
542
- setInterval(spawnEnemy, 2000);
543
- bgMusic.play();
544
- updateGame();
545
  </script>
546
  </body>
547
  </html>
 
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>Interactive Animation & Game</title>
7
  <style>
8
  body {
9
  margin: 0;
10
  overflow: hidden;
11
+ background: #1a1a1a;
12
+ display: flex;
13
+ justify-content: center;
14
+ align-items: center;
15
+ min-height: 100vh;
16
+ }
17
+ canvas {
18
+ cursor: pointer;
19
  }
20
  #gameCanvas {
21
  background-image: url('stage 1.jpg');
 
45
  right: 20px;
46
  color: white;
47
  font-family: Arial;
48
+ font-size: 28px;
49
  }
50
  #healthBar {
51
+ width: 300px;
52
+ height: 30px;
53
  background: #333;
54
  margin-top: 5px;
55
  }
 
60
  transition: width 0.3s;
61
  }
62
  #bulletCount, #enemyCount {
63
+ font-size: 28px;
64
  }
65
  #replayButton {
66
  position: fixed;
 
83
  </style>
84
  </head>
85
  <body>
86
+ <canvas id="canvas"></canvas>
87
  <canvas id="gameCanvas"></canvas>
88
  <div id="message"></div>
89
  <div id="stats">
90
+ Health: <div id="healthBar"><div id="healthFill"></div></div>
91
  Bullets: <span id="bulletCount">35</span>
92
  </div>
93
  <div id="villainCount">Villains: <span id="enemyCount">30</span></div>
 
99
  <audio id="enemyHitSound" src="Renovatorsgetshot.mp3"></audio>
100
 
101
  <script>
102
+ // Part 1 - Animation and Particle Effects
103
+
104
+ const canvas = document.getElementById('canvas');
105
  const ctx = canvas.getContext('2d');
106
+ let particles = [];
107
+ const phrases = [
108
+ { text: 'Hello everyone.', size: 65, duration: 5000 },
109
+ { text: 'You have been selected as the next\nTimewalker for our team of Space Guardians.', size: 50, duration: 7000 },
110
+ { text: 'Repair the collapsing timelines\nand return safely.', size: 55, duration: 6000 },
111
+ { text: 'Good luck.\n- From the Space Guardians Leader', sizes: [65, 45], spacing: 45, duration: 6000 },
112
+ { text: 'TimeWalker', size: 65, duration: 3000 },
113
+ { text: 'Chapter 1', size: 65, duration: null }
114
+ ];
115
+
116
+ let currentPhraseIndex = 0;
117
+ let animationFrame;
118
+ let mouseX = 0;
119
+ let mouseY = 0;
120
 
121
  canvas.width = window.innerWidth;
122
  canvas.height = window.innerHeight;
123
 
124
+ class Particle {
125
+ constructor(x, y, targetX, targetY) {
126
+ this.x = Math.random() * canvas.width;
127
+ this.y = Math.random() * canvas.height;
128
+ this.targetX = targetX;
129
+ this.targetY = targetY;
130
+ this.dx = (Math.random() - 0.5) * 8;
131
+ this.dy = (Math.random() - 0.5) * 8;
132
+ this.radius = 2;
133
+ this.alpha = 1;
134
+ this.fadeSpeed = 0.02;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  }
 
136
 
137
+ draw() {
138
+ ctx.beginPath();
139
+ ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
140
+ ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`;
141
+ ctx.fill();
142
+ ctx.closePath();
143
+ }
 
 
 
 
 
144
 
145
+ update() {
146
+ const distance = Math.hypot(mouseX - this.x, mouseY - this.y);
147
+ if(distance < 100) {
148
+ this.x += this.dx;
149
+ this.y += this.dy;
150
+ } else {
151
+ this.x += (this.targetX - this.x) * 0.1;
152
+ this.y += (this.targetY - this.y) * 0.1;
153
  }
154
  }
155
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
+ function createParticles(phrase) {
158
+ let newParticles = [];
159
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
160
+
161
+ const lines = phrase.text.split('\n');
162
+
163
+ lines.forEach((line, index) => {
164
+ const size = phrase.sizes ? phrase.sizes[index] : phrase.size;
165
+ ctx.font = `${size}px Arial`;
166
+ ctx.fillStyle = 'white';
167
+ ctx.textAlign = 'center';
168
+ ctx.textBaseline = 'middle';
169
+
170
+ const spacing = phrase.spacing || size * 1.2;
171
+ const y = (canvas.height / 2 - 20) + (index - (lines.length - 1) / 2) * spacing;
172
+ ctx.fillText(line, canvas.width / 2, y);
173
+ });
174
+
175
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
176
+
177
+ for(let y = 0; y < canvas.height; y += 4) {
178
+ for(let x = 0; x < canvas.width; x += 4) {
179
+ const index = (y * canvas.width + x) * 4;
180
+ const alpha = imageData[index + 3];
181
+ if(alpha > 128) {
182
+ newParticles.push(new Particle(x, y, x, y));
183
+ }
184
+ }
185
  }
186
+
187
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
188
+ return newParticles;
189
  }
 
190
 
191
+ function transition() {
192
+ if(currentPhraseIndex < phrases.length - 1) {
193
+ currentPhraseIndex++;
194
+ const currentPhrase = phrases[currentPhraseIndex];
195
+
196
+ particles.forEach(particle => {
197
+ particle.dx = (Math.random() - 0.5) * 20;
198
+ particle.dy = (Math.random() - 0.5) * 20;
199
+ const fadeOut = setInterval(() => {
200
+ particle.alpha -= particle.fadeSpeed;
201
+ if(particle.alpha <= 0) clearInterval(fadeOut);
202
+ }, 50);
203
+ });
204
 
 
 
 
 
 
 
 
 
 
205
  setTimeout(() => {
206
+ particles = createParticles(currentPhrase);
207
+ particles.forEach(particle => {
208
+ particle.alpha = 0;
209
+ const fadeIn = setInterval(() => {
210
+ particle.alpha += particle.fadeSpeed;
211
+ if(particle.alpha >= 1) clearInterval(fadeIn);
212
+ }, 50);
213
+ });
214
+ }, 800);
215
+
216
+ if(currentPhrase.duration) {
217
+ setTimeout(transition, currentPhrase.duration);
218
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  }
220
  }
221
 
222
+ function animate() {
223
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
224
+ particles.forEach(particle => {
225
+ particle.update();
226
+ particle.draw();
227
+ });
228
+ animationFrame = requestAnimationFrame(animate);
229
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
 
231
+ canvas.addEventListener('mousemove', (e) => {
232
  mouseX = e.clientX;
233
+ mouseY = e.clientY;
234
+ });
235
+
236
+ window.addEventListener('resize', () => {
237
+ canvas.width = window.innerWidth;
238
+ canvas.height = window.innerHeight;
239
+ particles = createParticles(phrases[currentPhraseIndex]);
240
  });
241
 
242
+ particles = createParticles(phrases[0]);
243
+ particles.forEach(particle => {
244
+ particle.alpha = 0;
245
+ const fadeIn = setInterval(() => {
246
+ particle.alpha += particle.fadeSpeed;
247
+ if(particle.alpha >= 1) clearInterval(fadeIn);
248
+ }, 50);
249
  });
250
+ animate();
251
+ transition();
252
+
253
+ // Part 2 - Game Logic
254
+ function gameStart() {
255
+ setTimeout(() => {
256
+ document.getElementById('gameCanvas').style.display = 'block';
257
+ document.getElementById('stats').style.display = 'block';
258
+ document.getElementById('message').style.display = 'none';
259
+ document.getElementById('bgMusic').play();
260
+ // Additional game logic can start here
261
+ }, 1000); // Wait for 1 second before starting the game
262
+ }
263
+
264
+ // Once animation part completes or after transition, start the game logic
265
+ gameStart();
266
 
 
 
 
267
  </script>
268
  </body>
269
  </html>