├── images ├── shop.png ├── kenji │ ├── Run.png │ ├── Death.png │ ├── Fall.png │ ├── Idle.png │ ├── Jump.png │ ├── Attack1.png │ ├── Attack2.png │ └── Take hit.png ├── background.png └── samuraiMack │ ├── Fall.png │ ├── Idle.png │ ├── Jump.png │ ├── Run.png │ ├── Attack1.png │ ├── Attack2.png │ ├── Death.png │ ├── TakeHit.png │ └── Take Hit - white silhouette.png ├── README.md ├── LICENSE.md ├── js ├── utilitis.js └── classes.js ├── index.html └── index.js /images/shop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/shop.png -------------------------------------------------------------------------------- /images/kenji/Run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/kenji/Run.png -------------------------------------------------------------------------------- /images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/background.png -------------------------------------------------------------------------------- /images/kenji/Death.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/kenji/Death.png -------------------------------------------------------------------------------- /images/kenji/Fall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/kenji/Fall.png -------------------------------------------------------------------------------- /images/kenji/Idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/kenji/Idle.png -------------------------------------------------------------------------------- /images/kenji/Jump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/kenji/Jump.png -------------------------------------------------------------------------------- /images/kenji/Attack1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/kenji/Attack1.png -------------------------------------------------------------------------------- /images/kenji/Attack2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/kenji/Attack2.png -------------------------------------------------------------------------------- /images/kenji/Take hit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/kenji/Take hit.png -------------------------------------------------------------------------------- /images/samuraiMack/Fall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/samuraiMack/Fall.png -------------------------------------------------------------------------------- /images/samuraiMack/Idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/samuraiMack/Idle.png -------------------------------------------------------------------------------- /images/samuraiMack/Jump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/samuraiMack/Jump.png -------------------------------------------------------------------------------- /images/samuraiMack/Run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/samuraiMack/Run.png -------------------------------------------------------------------------------- /images/samuraiMack/Attack1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/samuraiMack/Attack1.png -------------------------------------------------------------------------------- /images/samuraiMack/Attack2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/samuraiMack/Attack2.png -------------------------------------------------------------------------------- /images/samuraiMack/Death.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/samuraiMack/Death.png -------------------------------------------------------------------------------- /images/samuraiMack/TakeHit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/samuraiMack/TakeHit.png -------------------------------------------------------------------------------- /images/samuraiMack/Take Hit - white silhouette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ELDADBRHANO/Fight-Game/HEAD/images/samuraiMack/Take Hit - white silhouette.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fight-Game 2 | This is a game made with Canvas and HTML. The objective of the game is to defeat your opponent by reducing their health to zero. 3 | 4 | ### The left player controlled by : 'A' , 'S' , 'W' and for attack press space. 5 | 6 | 7 | ## How to Play 8 | The left player is controlled by the keys 'A' (move left), 'S' (crouch), 'W' (jump), and space (attack). The right player is controlled by the arrow keys 👉 (move right), 👈 (move left), 👆 (jump), and 👇 (attack). 9 | 10 | ## Hosting 11 | This game is hosted on Netlify. You can play it by clicking on the following link: 12 | ### https://eldadbrhano-fight-game.netlify.app/ 13 | 14 | 15 | ## Future Improvements 16 | While the game is fully functional, there are still some improvements that could be made. These include: 17 | 18 | - Adding more levels 19 | - Adding sound effects 20 | - Adding a timer for each round 21 | 22 | ## Conclusion 23 | Thank you for playing Fight-Game! We hope you enjoyed it. If you have any feedback or suggestions, please don't hesitate to contact me. 24 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Eldad Brhano 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /js/utilitis.js: -------------------------------------------------------------------------------- 1 | 2 | function rectangularCollision({ rectangle1, rectangle2 }) { 3 | return ( 4 | rectangle1.attackBox.position.x + rectangle1.attackBox.width >= 5 | rectangle2.position.x && 6 | rectangle1.attackBox.position.x <= 7 | rectangle2.position.x + rectangle2.width && 8 | rectangle1.attackBox.position.y + rectangle1.attackBox.height >= 9 | rectangle2.position.y && 10 | rectangle1.attackBox.position.y <= rectangle2.position.y + rectangle2.height 11 | ); 12 | } 13 | 14 | function announceWinner({player,enemy,timerId}) { 15 | clearTimeout(timerId) 16 | document.getElementById('displayText').style.display='flex' 17 | if(player.health === enemy.health){ 18 | document.getElementById('displayText').innerHTML='Tie' 19 | }else if(player.health > enemy.health){ 20 | document.getElementById('displayText').innerHTML='Player 1 wins' 21 | }else if(player.health < enemy.health){ 22 | document.getElementById('displayText').innerHTML='player 2 wins' 23 | } 24 | } 25 | 26 | let timer = 60; 27 | let timerId; 28 | function decreaseTimer() { 29 | if (timer > 0) { 30 | timerId = setTimeout(decreaseTimer, 1000); 31 | timer-- 32 | document.getElementById('timer').innerHTML = timer; 33 | }; 34 | 35 | if(timer===0){ 36 | announceWinner({player,enemy}) 37 | } 38 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 14 | 15 | 16 | 17 |
18 |
27 | 28 |
39 |
40 |
51 |
52 | 53 |
67 | 10 68 |
69 | 70 |
79 |
80 |
91 |
92 |
93 |
94 |
108 | Tie 109 |
110 | 111 | 117 | 118 | 119 | 120 |
121 | 122 | -------------------------------------------------------------------------------- /js/classes.js: -------------------------------------------------------------------------------- 1 | class Sprite { 2 | constructor({ 3 | position, 4 | imageSrc, 5 | scale = 1, 6 | frameMax = 1, 7 | offset = { x: 0, y: 0 }, 8 | }) { 9 | this.position = position; 10 | this.width = 50; 11 | this.height = 150; 12 | this.image = new Image(); 13 | this.image.src = imageSrc; 14 | this.scale = scale; 15 | this.frameMax = frameMax; 16 | this.frameCurrent = 0; 17 | this.frameElapsed = 0; 18 | this.frameHold = 5; 19 | this.offset = offset; 20 | } 21 | 22 | draw() { 23 | c.drawImage( 24 | this.image, 25 | this.frameCurrent * (this.image.width / this.frameMax), 26 | 0, 27 | this.image.width / this.frameMax, 28 | this.image.height, 29 | this.position.x - this.offset.x, 30 | this.position.y - this.offset.y, 31 | (this.image.width / this.frameMax) * this.scale, 32 | this.image.height * this.scale 33 | ); 34 | } 35 | 36 | animateFrame() { 37 | this.frameElapsed++; 38 | 39 | 40 | if (this.frameElapsed % this.frameHold === 0) { 41 | if (this.frameCurrent < this.frameMax - 1) { 42 | this.frameCurrent++; 43 | } else { 44 | this.frameCurrent = 0; 45 | } 46 | } 47 | } 48 | update() { 49 | this.draw(); 50 | this.animateFrame(); 51 | } 52 | } 53 | 54 | class Fight extends Sprite { 55 | constructor({ 56 | position, 57 | velocity, 58 | color = "red", 59 | imageSrc, 60 | scale = 1, 61 | frameMax = 1, 62 | offset = { x: 0, y: 0 }, 63 | sprites, 64 | attackBox = { offset: {}, width: undefined, height: undefined }, 65 | }) { 66 | super({ 67 | position, 68 | imageSrc, 69 | scale, 70 | frameMax, 71 | offset, 72 | }); 73 | this.velocity = velocity; 74 | this.width = 50; 75 | this.height = 150; 76 | this.lastKey; 77 | this.attackBox = { 78 | position: { 79 | x: this.position.x, 80 | y: this.position.y, 81 | }, 82 | offset: attackBox.offset, 83 | width: attackBox.width, 84 | height: attackBox.height, 85 | }; 86 | this.color = color; 87 | this.isAttacking; 88 | this.health = 100; 89 | (this.frameCurrent = 0), (this.frameElapsed = 0), (this.frameHold = 5); 90 | this.sprites = sprites; 91 | this.dead = false; 92 | 93 | 94 | for (const sprite in this.sprites) { 95 | sprites[sprite].image = new Image(); 96 | sprites[sprite].image.src = sprites[sprite].imageSrc; 97 | } 98 | } 99 | 100 | update() { 101 | this.draw(); 102 | if (!this.dead) this.animateFrame() 103 | 104 | // attackBoxes 105 | this.attackBox.position.x = this.position.x + this.attackBox.offset.x; 106 | this.attackBox.position.y = this.position.y + this.attackBox.offset.y; 107 | 108 | // c.fillRect(this.attackBox.position.x, this.attackBox.position.y,this.attackBox.width,this.attackBox.height) 109 | 110 | this.position.x += this.velocity.x; 111 | this.position.y += this.velocity.y; 112 | 113 | // gravity func 114 | if (this.position.y + this.height + this.velocity.y >= canvas.height - 96) { 115 | this.velocity.y = 0; 116 | this.position.y = 330; 117 | } else this.velocity.y += gravity; 118 | } 119 | 120 | attack() { 121 | this.switchSprites("attack1"); 122 | this.isAttacking = true; 123 | } 124 | 125 | 126 | takeHit() { 127 | this.health -= 20; 128 | 129 | if(this.health <=0){ 130 | this.switchSprites("death") 131 | }else this.switchSprites("takeHit") 132 | } 133 | 134 | switchSprites(sprite) { 135 | 136 | if(this.image === this.sprites.death.image) { 137 | if(this.frameCurrent === this.sprites.death.frameMax - 1) 138 | this.dead = true; 139 | return 140 | } 141 | 142 | 143 | // overriding animations with the attack animation 144 | if ( 145 | this.image === this.sprites.attack1.image && 146 | this.frameCurrent < this.sprites.attack1.frameMax - 1 147 | ) 148 | return; 149 | 150 | // override when fighter gets hit 151 | if ( 152 | this.image === this.sprites.takeHit.image && 153 | this.frameCurrent < this.sprites.takeHit.frameMax - 1 154 | ) 155 | return 156 | 157 | switch (sprite) { 158 | case "idele": 159 | if (this.image !== this.sprites.idele.image) { 160 | this.image = this.sprites.idele.image; 161 | this.frameMax = this.sprites.idele.frameMax; 162 | this.frameCurrent = 0; 163 | } 164 | break; 165 | 166 | case "run": 167 | if (this.image !== this.sprites.run.image) { 168 | this.image = player.sprites.run.image; 169 | this.frameMax = this.sprites.run.frameMax; 170 | this.frameCurrent = 0; 171 | } 172 | break; 173 | 174 | case "jump": 175 | if (this.image !== this.sprites.jump.image) { 176 | this.image = this.sprites.jump.image; 177 | this.frameMax = this.sprites.jump.frameMax; 178 | this.frameCurrent = 0; 179 | } 180 | break; 181 | 182 | case "fall": 183 | if (this.image !== this.sprites.fall.image) { 184 | this.image = this.sprites.fall.image; 185 | this.frameMax = this.sprites.fall.frameMax; 186 | this.frameCurrent = 0; 187 | } 188 | break; 189 | 190 | case "attack1": 191 | if (this.image !== this.sprites.attack1.image) { 192 | this.image = this.sprites.attack1.image; 193 | this.frameMax = this.sprites.attack1.frameMax; 194 | this.frameCurrent = 0; 195 | } 196 | break; 197 | 198 | case "takeHit": 199 | if (this.image !== this.sprites.takeHit.image) { 200 | this.image = this.sprites.takeHit.image; 201 | this.frameMax = this.sprites.takeHit.frameMax; 202 | this.frameCurrent = 0; 203 | } 204 | break; 205 | 206 | case "death": 207 | if (this.image !== this.sprites.death.image) { 208 | this.image = this.sprites.death.image; 209 | this.frameMax = this.sprites.death.frameMax; 210 | this.frameCurrent = 0; 211 | } 212 | break; 213 | default: 214 | break; 215 | } 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const canvas = document.getElementById("canvas"); 2 | const c = canvas.getContext("2d"); 3 | 4 | canvas.width = 1024; 5 | canvas.height = 576; 6 | 7 | c.fillRect(0, 0, canvas.width, canvas.height); 8 | 9 | const gravity = 0.7; 10 | 11 | const backgroundImg = new Sprite({ 12 | position: { 13 | x: 0, 14 | y: 0, 15 | }, 16 | imageSrc: "./images/background.png", 17 | }); 18 | 19 | const shop = new Sprite({ 20 | position: { 21 | x: 600, 22 | y: 128, 23 | }, 24 | imageSrc: "./images/shop.png", 25 | scale: 2.75, 26 | frameMax: 6, 27 | }); 28 | 29 | const player = new Fight({ 30 | position: { 31 | x: 0, 32 | y: 0, 33 | }, 34 | velocity: { 35 | x: 0, 36 | y: 0, 37 | }, 38 | offset: { 39 | x: 0, 40 | y: 0, 41 | }, 42 | imageSrc: "./images/samuraiMack/idle.png", 43 | frameMax: 8, 44 | scale: 2.75, 45 | offset: { 46 | x: 215, 47 | y: 187, 48 | }, 49 | sprites: { 50 | idele: { 51 | imageSrc: "./images/samuraiMack/Idle.png", 52 | frameMax: 8, 53 | }, 54 | run: { 55 | imageSrc: "./images/samuraiMack/Run.png", 56 | frameMax: 8, 57 | }, 58 | jump: { 59 | imageSrc: "./images/samuraiMack/Jump.png", 60 | frameMax: 2, 61 | }, 62 | fall: { 63 | imageSrc: "./images/samuraiMack/Fall.png", 64 | frameMax: 2, 65 | }, 66 | attack1: { 67 | imageSrc: "./images/samuraiMack/Attack1.png", 68 | frameMax: 6, 69 | }, 70 | takeHit: { 71 | imageSrc: "./images/samuraiMack/Take Hit - white silhouette.png", 72 | frameMax: 4, 73 | }, 74 | death: { 75 | imageSrc: "./images/samuraiMack/Death.png", 76 | frameMax: 6, 77 | }, 78 | }, 79 | attackBox: { 80 | offset: { 81 | x: 100, 82 | y: 50, 83 | }, 84 | width: 160, 85 | height: 50, 86 | }, 87 | }); 88 | 89 | const enemy = new Fight({ 90 | position: { 91 | x: 400, 92 | y: 100, 93 | }, 94 | velocity: { 95 | x: 0, 96 | y: 0, 97 | }, 98 | color: "blue", 99 | offset: { 100 | x: -50, 101 | y: 0, 102 | }, 103 | imageSrc: "./images/kenji/Idle.png", 104 | frameMax: 4, 105 | scale: 2.75, 106 | offset: { 107 | x: 215, 108 | y: 202, 109 | }, 110 | sprites: { 111 | idele: { 112 | imageSrc: "./images/kenji/idle.png", 113 | frameMax: 4, 114 | }, 115 | run: { 116 | imageSrc: "./images/kenji/Run.png", 117 | frameMax: 8 118 | }, 119 | jump: { 120 | imageSrc: "./images/kenji/Jump.png", 121 | frameMax: 2, 122 | }, 123 | fall: { 124 | imageSrc: "./images/kenji/Fall.png", 125 | frameMax: 2, 126 | }, 127 | attack1: { 128 | imageSrc: "./images/kenji/Attack1.png", 129 | frameMax: 4, 130 | }, 131 | takeHit: { 132 | imageSrc: "./images/kenji/Take hit.png", 133 | frameMax: 3, 134 | }, 135 | death: { 136 | imageSrc: "./images/kenji/Death.png", 137 | frameMax: 7, 138 | }, 139 | }, 140 | attackBox: { 141 | offset: { 142 | x: -175, 143 | y: 50, 144 | }, 145 | width: 175, 146 | height: 50, 147 | }, 148 | }); 149 | 150 | enemy.draw(); 151 | 152 | const keys = { 153 | a: { 154 | pressed: false, 155 | }, 156 | d: { 157 | pressed: false, 158 | }, 159 | w: { 160 | pressed: false, 161 | }, 162 | ArrowRight: { 163 | pressed: false, 164 | }, 165 | ArrowLeft: { 166 | pressed: false, 167 | }, 168 | }; 169 | 170 | decreaseTimer(); 171 | 172 | function animate() { 173 | window.requestAnimationFrame(animate); 174 | c.fillStyle = "black"; 175 | c.fillRect(0, 0, canvas.width, canvas.height); 176 | backgroundImg.update(); 177 | shop.update(); 178 | c.fillStyle = 'rgba(255,255,255,0.12)' 179 | c.fillRect(0,0,canvas.width,canvas.height) 180 | player.update(); 181 | enemy.update(); 182 | 183 | player.velocity.x = 0; 184 | enemy.velocity.x = 0; 185 | 186 | // player movment 187 | 188 | if (keys.a.pressed && player.lastKey === "a") { 189 | player.velocity.x = -5; 190 | player.switchSprites("run"); 191 | } 192 | else if (keys.d.pressed && player.lastKey === "d") { 193 | player.velocity.x = 5; 194 | player.switchSprites("run"); 195 | } 196 | else { 197 | player.switchSprites("idele"); 198 | } 199 | 200 | // jump 201 | if (player.velocity.y < 0) { 202 | player.switchSprites("jump"); 203 | } else if (player.velocity.y > 0) { 204 | player.switchSprites("fall"); 205 | } 206 | 207 | // enemyy movement 208 | if (keys.ArrowLeft.pressed && enemy.lastKey === "ArrowLeft") { 209 | enemy.velocity.x = -5; 210 | enemy.switchSprites("run"); 211 | } 212 | else if (keys.ArrowRight.pressed && enemy.lastKey === "ArrowRight") { 213 | enemy.velocity.x = 5; 214 | enemy.switchSprites("run"); 215 | } 216 | else { 217 | enemy.switchSprites("idele"); 218 | } 219 | 220 | // jump 221 | if (enemy.velocity.y < 0) { 222 | enemy.switchSprites("jump"); 223 | } else if (enemy.velocity.y > 0) { 224 | enemy.switchSprites("fall"); 225 | } 226 | 227 | // detect for collision && enemy get hit 228 | if ( 229 | rectangularCollision({ rectangle1: player, rectangle2: enemy }) && 230 | player.isAttacking && 231 | player.frameCurrent === 4 232 | ) { 233 | enemy.takeHit(); 234 | player.isAttacking = false; 235 | enemy.health -= 10; 236 | gsap.to("#enemyHealth",{ 237 | width: enemy.health + "%" 238 | }) 239 | } 240 | 241 | // if player miss attack 242 | if (player.isAttacking && player.frameCurrent === 4) { 243 | player.isAttacking = false; 244 | } 245 | if ( 246 | rectangularCollision({ rectangle1: enemy, rectangle2: player }) && 247 | enemy.isAttacking && 248 | enemy.frameCurrent === 2 249 | ) { 250 | player.takeHit() 251 | enemy.isAttacking = false; 252 | player.health -= 10; 253 | gsap.to("#playerHealth",{ 254 | width: player.health + "%" 255 | }) 256 | console.log("enemy attack successful"); 257 | } 258 | 259 | if (enemy.isAttacking && enemy.frameCurrent === 2) { 260 | enemy.isAttacking = false; 261 | } 262 | 263 | // end game based on health 264 | if (enemy.health <= 0 || player.health <= 0) { 265 | announceWinner({ player, enemy, timerId }); 266 | } 267 | } 268 | 269 | animate(); 270 | 271 | window.addEventListener("keydown", (e) => { 272 | if(!player.dead){ 273 | 274 | switch (e.key) { 275 | case "d": 276 | keys.d.pressed = true; 277 | player.lastKey = "d"; 278 | break; 279 | case "a": 280 | keys.a.pressed = true; 281 | player.lastKey = "a"; 282 | break; 283 | case "w": 284 | player.velocity.y = -20; 285 | break; 286 | case " ": 287 | player.attack(); 288 | break; 289 | 290 | default: 291 | break; 292 | } 293 | } 294 | 295 | if (!enemy.dead) { 296 | 297 | switch (e.key) { 298 | case "ArrowRight": 299 | keys.ArrowRight.pressed = true; 300 | enemy.lastKey = "ArrowRight"; 301 | break; 302 | case "ArrowLeft": 303 | keys.ArrowLeft.pressed = true; 304 | enemy.lastKey = "ArrowLeft"; 305 | break; 306 | case "ArrowUp": 307 | enemy.velocity.y = -20; 308 | break; 309 | case "ArrowDown": 310 | enemy.attack(); 311 | break; 312 | 313 | default: 314 | break; 315 | } 316 | } 317 | }); 318 | 319 | window.addEventListener("keyup", (e) => { 320 | switch (e.key) { 321 | case "d": 322 | keys.d.pressed = false; 323 | break; 324 | case "a": 325 | keys.a.pressed = false; 326 | break; 327 | case "w": 328 | keys.w.pressed = false; 329 | lastKey = "w"; 330 | break; 331 | } 332 | // enemy cases 333 | switch (e.key) { 334 | case "ArrowRight": 335 | keys.ArrowRight.pressed = false; 336 | break; 337 | case "ArrowLeft": 338 | keys.ArrowLeft.pressed = false; 339 | break; 340 | case "w": 341 | keys.w.pressed = false; 342 | lastKey = "w"; 343 | break; 344 | default: 345 | break; 346 | } 347 | }); 348 | --------------------------------------------------------------------------------