我目前正在创建一款格斗游戏,我有两个精灵(玩家是蓝色的,敌人是红色的).我目前有一个可以工作的计时器.然而,时间到了之后,精灵仍然可以相互攻击,中间的文本会不断变化(如果运行代码片断会更有意义).
Question:如何才能使我的精灵在计时器结束后不能互相攻击?
100问:我如何在计时器用完后阻止我的精灵移动?我觉得如果第一个问题得到回答,我可以做这个问题
注意:我没有使用任何库或框架,我使用的是原生的JavaScript、CSS和HTML.
注意:使用"回车"或"空格键",当精灵中的一个降到没有生命值的时候.然后用另一个精灵,更多地击打原来的那个.最终,文本将从"玩家1/2获胜!"到"玩家2/1赢了!",尽管生命已经消失.
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext("2d");
const winnerDisplay = document.querySelector('#winner-display');
canvas.width = 1024;
canvas.height = 576;
function logMessage(msg) {
document.querySelector('#myMessage').textContent += msg + '. ';
}
ctx.fillRect(0, 0, canvas.width, canvas.height);
const gravity = 0.7;
class Sprite {
constructor({position, velocity, color, 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
},
offset,
width: 100,
height: 50,
color: 'green'
}
this.color = color;
this.isAttacking;
this.health = 100;
}
draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.position.x, this.position.y, this.width, this.height);
//Attack box
if (this.isAttacking) {
ctx.fillStyle = this.attackBox.color;
ctx.fillRect(
this.attackBox.position.x,
this.attackBox.position.y,
this.attackBox.width,
this.attackBox.height
)
}
}
update() {
this.draw();
this.attackBox.position.x = this.position.x - this.attackBox.offset.x;
this.attackBox.position.y = this.position.y;
this.position.x = Math.max(0, Math.min(canvas.width - this.width, this.position.x + this.velocity.x));
this.position.y = Math.max(0, Math.min(canvas.height, this.position.y + this.velocity.y));
if (this.position.y + this.height + this.velocity.y >= canvas.height) {
this.velocity.y = 0;
} else {
this.velocity.y += gravity;
}
}
attack() {
this.isAttacking = true;
setTimeout(() => {
this.isAttacking = false
}, 50)
}
}
const Player = new Sprite({
position: {
x: 0,
y: 0
},
velocity: {
x: 0,
y: 0
},
offset: {
x: 0,
y: 0
},
color: 'blue'
})
const Enemy = new Sprite({
position: {
x: canvas.width,
y: 100
},
velocity: {
x: 0,
y: 0
},
offset: {
x: 50,
y: 0
},
color: 'red'
})
const keys = {
w: {
pressed: false
},
a: {
pressed: false
},
d: {
pressed: false
},
ArrowUp: {
pressed: false
},
ArrowLeft: {
pressed: false
},
ArrowRight: {
pressed: false
}
}
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 &&
rectangle1.isAttacking
)
}
function determineWinner({ Player, Enemy, timerId }) {
clearTimeout(timerId);
winnerDisplay.style.display = 'flex';
if (Player.health == Enemy.health) {
winnerDisplay.innerHTML = 'Tie!';
}
if (Player.health > Enemy.health) {
winnerDisplay.innerHTML = 'Player 1 wins!';
}
if (Player.health < Enemy.health) {
winnerDisplay.innerHTML = 'Player 2 wins!';
}
}
//Timer and end game
//Feel free to change these starting values as you need
const startingMinutes = 1;
const startingSeconds = 30;
let time = startingMinutes * 60 + startingSeconds;
let timerId;
function decreaseTimer() {
const timeLeft = document.querySelector('#time-left');
if (time > 0) {
timerId = setTimeout(decreaseTimer, 1000);
const minutes = Math.floor(time / 60);
let seconds = time % 60;
seconds = seconds < 10 ? '0' + seconds : seconds;
timeLeft.innerHTML = `0${minutes}:${seconds}`;
time--;
}
if (time == 0) {
timeLeft.innerHTML = `00:00`;
determineWinner({ Player, Enemy, timerId });
Player.position.x = 0;
Enemy.position.x = canvas.width;
}
}
decreaseTimer();
function animate() {
window.requestAnimationFrame(animate);
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
Player.update();
Enemy.update();
//Player movement
Player.velocity.x = 0;
if (keys.a.pressed == true && Player.lastKey == "a") {
Player.velocity.x = -5;
} else if (keys.d.pressed == true && Player.lastKey == "d") {
Player.velocity.x = 5;
}
//Enemy movement
Enemy.velocity.x = 0;
if (keys.ArrowLeft.pressed == true && Enemy.lastKey == "ArrowLeft") {
Enemy.velocity.x = -5;
} else if (keys.ArrowRight.pressed == true && Enemy.lastKey == "ArrowRight") {
Enemy.velocity.x = 5;
}
//Detect for the player hitting the enemy
if (rectangularCollision({rectangle1: Player, rectangle2: Enemy})) {
Player.isAttacking = false;
Enemy.health -= 20;
document.querySelector('#enemy-health').style.width = Enemy.health + '%';
}
//Detect for the enemy hitting the player
if (rectangularCollision({rectangle1: Enemy, rectangle2: Player})) {
Enemy.isAttacking = false;
Player.health -= 20;
document.querySelector('#player-health').style.width = Player.health + '%';
}
//End game based on health
if (Enemy.health <= 0 || Player.health <= 0) {
determineWinner({ Player, Enemy, timerId });
}
}
animate();
window.addEventListener('keydown', (event) => {
switch (event.key) {
//Player movement
case 'w':
Player.velocity.y = -20;
break;
case 'a':
keys.a.pressed = true;
Player.lastKey = "a";
break
case 'd':
keys.d.pressed = true;
Player.lastKey = "d";
break;
case ' ':
Player.attack();
break;
}
//Enemy movement
switch (event.key) {
case 'ArrowUp':
Enemy.velocity.y = -20;
break;
case 'ArrowRight':
keys.ArrowRight.pressed = true;
Enemy.lastKey = 'ArrowRight'
break
case 'ArrowLeft':
keys.ArrowLeft.pressed = true;
Enemy.lastKey = 'ArrowLeft'
break;
case 'Enter':
Enemy.attack();
break;
}
})
window.addEventListener('keyup', (event) => {
//Player keys
switch (event.key) {
case 'w':
keys.w.pressed = false;
break;
case 'a':
keys.a.pressed = false;
break
case 'd':
keys.d.pressed = false;
break;
}
//Enemy keys
switch (event.key) {
case 'ArrowUp':
keys.ArrowUp.pressed = false;
break;
case 'ArrowLeft':
keys.ArrowLeft.pressed = false;
break
case 'ArrowRight':
keys.ArrowRight.pressed = false;
break;
}
})
* {
box-sizing: border-box;
}
#mother-div {
position: relative;
display: inline-block;
}
#small-container {
position: absolute;
display: flex;
width: 100%;
align-items: center;
padding: 20px;
}
.healthDiv {
position: relative;
height: 30px;
width: 100%;
}
.backgroundHealth {
background-color: red;
height: 30px;
width: 100%
}
#player-health {
position: absolute;
background-color: lime;
top: 0;
right: 0;
bottom: 0;
width: 100%
}
#enemy-health {
position: absolute;
background-color: yellow;
top: 0;
right: 0;
bottom: 0;
left: 0
}
#playerHealthDiv {
display: flex;
justify-content: flex-end;
}
#timer {
background-color: red;
width: 100px;
height: 100px;
flex-shrink: 0;
border: solid white 2px;
display: flex;
align-items: center;
justify-content: center;
}
#winner-display {
position: absolute;
color: white;
align-items: center;
justify-content: center;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: none;
}
#myConsole {
background-color: black;
color: white;
min-height: 100px;
}
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE-edge">
<meta name="viewport", content="width=device-width, initial-scale=1.0">
<meta name="author" content="Christian Davis">
<link rel="stylesheet" href="styles.css">
<title>Fighting Game</title>
</head>
<body>
<!--Red container div-->
<div id="mother-div">
<!--Smaller red container div-->
<div id="small-container">
<!--Player Health-->
<div class="healthDiv" id="playerHealthDiv">
<div class="backgroundHealth"></div>
<div id="player-health"></div>
</div>
<!--Timer-->
<div id="timer">
<span id="time-left">02:00</span>
</div>
<!--Enemy Health-->
<div class="healthDiv">
<div class="backgroundHealth"></div>
<div id="enemy-health"></div>
</div>
</div>
<!--Winner display-->
<div id="winner-display"></div>
<canvas id="canvas"></canvas>
</div>
<p id="myConsole">> <span id="myMessage"></span></p>
<script src="app.js"></script>
</body>
</html>