角色攻擊
為了使角色能攻擊,我們需要在 class 加上 attack box 的值,來決定攻擊敵人的範圍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Sprite { constructor({ position, velocity, color = 'red', offset }) { this.position = position; this.velocity = velocity; this.height = 150; this.width = 50; this.lastKey; this.attackBox = { position: { x: this.position.x, y: this.position.y, }, width: 100, height: 50, offset }, this.color = color; this.isAttacking; };
attack() { this.isAttacking = true; setTimeout(() => { this.isAttacking = false; }, 100) } }
|
如上,我們在 sprite 裡加上 attackbox ,並設定 position 跟 寬高。 isAttacking 則用來決定角色是否處於攻擊狀態,在attack()函式中,會先設定 isAttacking 為true,再用setTimeout 於 100 ms後 設訂為 false;
確認攻擊範圍
為了確認攻擊是否擊中敵人,可以建立一個確認物體碰撞的函式,來確認 attackbox是否在敵人身上。
1 2 3 4 5 6 7 8
| function rectangularCollision({ rectangle1, rectangle2 }) { return ( rectangle1.attackBox.position.x + rectangle1.attackBox.width >= rectangle2.position.x && rectangle1.attackBox.position.x <= rectangle2.position.x + rectangle2.width && rectangle1.attackBox.position.y + rectangle1.attackBox.height >= rectangle2.position.y && rectangle1.attackBox.position.y <= rectangle2.position.y + rectangle2.height ); }
|
在 animate 的函式中,就可來確認是否攻擊成功
1 2 3 4 5 6 7 8 9 10
| if ( rectangularCollision({ rectangle1: player, rectangle2: enemy, }) && player.isAttacking ) { player.isAttacking = false; }
|
事件偵聽
最後就是將 攻擊的動作加入鍵盤事件偵聽, player 我們設為空白鑑攻擊, enemy 則設為↓ 攻擊。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| window.addEventListener('keydown', (e) => { switch(e.key) { case 'd': keys.d.pressd = true; player.lastKey = 'd'; break; case 'a': keys.a.pressd = true; player.lastKey = 'a'; break; case 'w': player.velocity.y = -20; break; case ' ': player.attack(); break; case 'ArrowRight': keys.ArrowRight.pressd = true; enemy.lastKey = 'ArrowRight'; break; case 'ArrowLeft': keys.ArrowLeft.pressd = true; enemy.lastKey = 'ArrowLeft'; break; case 'ArrowUp': enemy.velocity.y = -20; break; case 'ArrowDown': enemy.attack(); break; } });
|