Pabloader 2 лет назад
Родитель
Сommit
ee031b41ed
6 измененных файлов: 73 добавлений и 14 удалений
  1. 1
    1
      bullet.js
  2. 1
    3
      game.js
  3. 2
    0
      index.html
  4. 28
    0
      shooting_pad.js
  5. 34
    3
      style.css
  6. 7
    7
      todo.md

+ 1
- 1
bullet.js Просмотреть файл

@@ -33,7 +33,7 @@ class RainDrop extends Bullet {
33 33
             if (this.y > 1.1) {
34 34
                 this.destroy();
35 35
             } else if (this.isOverlapped(shootingPad)) {
36
-                gameOver('Game over');
36
+                shootingPad.lifeOver();
37 37
                 this.destroy();
38 38
             }
39 39
         }

+ 1
- 3
game.js Просмотреть файл

@@ -1,14 +1,13 @@
1 1
 const $ = (s) => document.querySelector(s);
2 2
 const $$ = (s) => Array.from(document.querySelectorAll(s));
3 3
 const ROOT = $('#root');
4
+const X_BOUND = 0.05;
4 5
 
5 6
 const clouds = new Set();
6 7
 const bullets = new Set();
7 8
 let shootingPad = new ShootingPad();
8
-const X_BOUND = 0.05;
9 9
 let running = true;
10 10
 let direction = 1;
11
-let lives = 3;
12 11
 
13 12
 const initCloudField = () => {
14 13
     for (let y = 0; y < 6; y++) {
@@ -83,7 +82,6 @@ const loop = () => {
83 82
     requestAnimationFrame(loop);
84 83
 };
85 84
 
86
-
87 85
 document.addEventListener('keypress', () => {
88 86
     if (!running) {
89 87
         start();

+ 2
- 0
index.html Просмотреть файл

@@ -3,9 +3,11 @@
3 3
     <head>
4 4
         <title>OLC Codejam 2022</title>
5 5
         <link rel="stylesheet" href="style.css">
6
+        <meta charset="utf-8">
6 7
     </head>
7 8
     <body>
8 9
         <div id="root">
10
+            <section id="lives"></section>
9 11
         </div>
10 12
         <script src="utils.js"></script>
11 13
         <script src="entity.js"></script>

+ 28
- 0
shooting_pad.js Просмотреть файл

@@ -7,11 +7,21 @@ document.addEventListener('keyup', (e) => {
7 7
     keys[e.key] = false;
8 8
 });
9 9
 
10
+const MAX_LIVES = 3;
11
+
10 12
 class ShootingPad extends Entity {
11 13
     constructor() {
12 14
         super(0.5, 0.95, 0.04, 0.03);
13 15
         this.element.className = 'shooting-pad';
14 16
         this.lastShootTime = Date.now();
17
+        this.invulnerable = false;
18
+        this.lives = MAX_LIVES;
19
+        this.initLives();
20
+
21
+        this.element.addEventListener('animationend', () => {
22
+            this.element.style.animationName = null;
23
+            this.invulnerable = false;
24
+        });
15 25
     }
16 26
 
17 27
     update() {
@@ -33,4 +43,22 @@ class ShootingPad extends Entity {
33 43
             bullets.add(bullet);
34 44
         }
35 45
     }
46
+
47
+    initLives() {
48
+        $('#lives').textContent = `× ${this.lives}`;
49
+    }
50
+
51
+    lifeOver() {
52
+        if (this.invulnerable) return;
53
+
54
+        this.lives--;
55
+        this.initLives();
56
+
57
+        if (this.lives === 0) {
58
+            return gameOver('Game over');
59
+        } else {
60
+            this.invulnerable = true;
61
+            this.element.style.animationName = 'blink';
62
+        }
63
+    }
36 64
 }

+ 34
- 3
style.css Просмотреть файл

@@ -9,6 +9,8 @@ html, body {
9 9
     background: rgb(51, 51, 51);
10 10
     overflow: hidden;
11 11
     white-space: nowrap;
12
+    color: white;
13
+    font-family: arial;
12 14
 }
13 15
 
14 16
 #root {
@@ -37,6 +39,8 @@ html, body {
37 39
 
38 40
 .shooting-pad {
39 41
     background: red;
42
+    animation-iteration-count: 10;
43
+    animation-duration: 200ms;
40 44
 }
41 45
 
42 46
 .bullet {
@@ -53,12 +57,10 @@ html, body {
53 57
     left: 50%;
54 58
     top: 50%;
55 59
     font-size: 108px;
56
-    font-family: arial;
57
-    color: white;
58 60
 }
59 61
 
60 62
 .result:after {
61
-    content: 'Press any key to restart';
63
+    content: 'Press any key to continue';
62 64
     position: absolute;
63 65
     font-size: 48px;
64 66
     width: fit-content;
@@ -67,6 +69,17 @@ html, body {
67 69
     transform: translate(-50%);
68 70
 }
69 71
 
72
+#lives {
73
+    position: absolute;
74
+    top: 15px;
75
+    left: 15px;
76
+    font-size: 32px;
77
+}
78
+
79
+#lives:before {
80
+    content: '❤ ';
81
+    color: red;
82
+}
70 83
 
71 84
 @keyframes cloud {
72 85
     from {
@@ -78,4 +91,22 @@ html, body {
78 91
         transform: translate(-50%) scale(0.2);
79 92
         opacity: 0.1;
80 93
     }
94
+}
95
+
96
+@keyframes blink {
97
+    0% {
98
+        opacity: 1;
99
+    }
100
+    1% {
101
+        opacity: 0;
102
+    }
103
+    50% {
104
+        opacity: 0;
105
+    }
106
+    51% {
107
+        opacity: 1;
108
+    }
109
+    100% {
110
+        opacity: 1;
111
+    }
81 112
 }

+ 7
- 7
todo.md Просмотреть файл

@@ -1,10 +1,10 @@
1 1
 # TODO
2 2
 
3
-- lives
4
-- clouds should strike lightnings sometimes
5
-- bg rain effect
6
-- shooting platform sprite
7
-- boss?
8
-- umbrella shields
9
-- music & sounds
3
+- [x] lives
4
+- [ ] clouds should strike lightnings sometimes
5
+- [ ] bg rain effect
6
+- [ ] shooting platform sprite
7
+- [ ] boss?
8
+- [ ] umbrella shields
9
+- [ ] music & sounds
10 10
 

Загрузка…
Отмена
Сохранить