我目前正在通过Udemy的Vue.js教程进行工作。我已经到了您要制作战斗网络应用程序游戏的部分。完成之后,我决定练习重构,并遇到了这个错误。
当您单击攻击按钮,然后出现确认框询问您是否要再次玩游戏时,似乎在我的日志数组中添加了一个额外的项目,而不是完全重置游戏。
我怀疑这与过快按下攻击按钮有关,然后在运行addToLog()之前出现确认框,然后再运行它。
否则可能是我的错误代码。大声笑
请注意,我知道单击确认框上的“取消”也会出现一些错误。
index.html
<!DOCTYPE html>
<html>
<head>
<title>Monster Slayer</title>
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
<link rel="stylesheet" href="css/foundation.min.css">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<div id="app">
<section class="row">
<div class="small-6 columns">
<h1 class="text-center">YOU</h1>
<div class="healthbar">
<div class="healthbar text-center" style="background-color: green; margin: 0; color: white;" :style="{width: playerHealth + '%'}">
{{ playerHealth }}
</div>
</div>
</div>
<div class="small-6 columns">
<h1 class="text-center">BADDY</h1>
<div class="healthbar">
<div class="healthbar text-center" style="background-color: green; margin: 0; color: white;" :style="{width: computerHealth + '%'}">
{{ computerHealth }}
</div>
</div>
</div>
</section>
<section class="row controls" v-if="!isRunning">
<div class="small-12 columns">
<button id="start-game" @click="startGame">START GAME</button>
</div>
</section>
<section class="row controls" v-else>
<div class="small-12 columns">
<button id="attack" @click="attack">ATTACK</button>
<button id="special-attack" @click="specialAttack">SPECIAL ATTACK</button>
<button id="heal" @click="heal">HEAL</button>
<button id="restart" @click="restart">RESTART</button>
</div>
</section>
<section class="row log" v-if="turns.length > 0">
<div class="small-12 columns">
<ul>
<li v-for="turn in turns" :class="{'player-turn': turn.isPlayer, 'monster-turn': !turn.isPlayer}">
{{ turn.text }}
</li>
</ul>
</div>
</section>
</div>
<script src="app.js"></script>
</body>
</html>
css / app.css
.text-center {
text-align: center;
}
.healthbar {
width: 80%;
height: 40px;
background-color: #eee;
margin: auto;
transition: width 500ms;
}
.controls,
.log {
margin-top: 30px;
text-align: center;
padding: 10px;
border: 1px solid #ccc;
box-shadow: 0px 3px 6px #ccc;
}
.turn {
margin-top: 20px;
margin-bottom: 20px;
font-weight: bold;
font-size: 22px;
}
.log ul {
list-style: none;
font-weight: bold;
text-transform: uppercase;
}
.log ul li {
margin: 5px;
}
.log ul .player-turn {
color: blue;
background-color: #e4e8ff;
}
.log ul .monster-turn {
color: red;
background-color: #ffc0c1;
}
button {
font-size: 20px;
background-color: #eee;
padding: 12px;
box-shadow: 0 1px 1px black;
margin: 10px;
}
#start-game {
background-color: #aaffb0;
}
#start-game:hover {
background-color: #76ff7e;
}
#attack {
background-color: #ff7367;
}
#attack:hover {
background-color: #ff3f43;
}
#special-attack {
background-color: #ffaf4f;
}
#special-attack:hover {
background-color: #ff9a2b;
}
#heal {
background-color: #aaffb0;
}
#heal:hover {
background-color: #76ff7e;
}
#restart {
background-color: #ffffff;
}
#restart:hover {
background-color: #c7c7c7;
}
app.js
new Vue({
el: app,
data: {
playerHealth: 100,
computerHealth: 100,
isRunning: false,
turns: [],
},
methods: {
startGame: function() {
this.isRunning = true;
this.playerHealth = 100;
this.computerHealth = 100;
this.clearLog();
},
attackController: function(attacker, maxRange, minRange) {
let receiver = this.setReceiver(attacker);
let damage = 0;
if (attacker === 'player') {
damage = this.randomDamage(maxRange, minRange);
this.computerHealth -= damage;
}
if (attacker === 'computer') {
damage = this.randomDamage(maxRange, minRange);
this.playerHealth -= damage;
}
this.addToLog(attacker, receiver, damage);
if (this.checkWin()) {
return;
}
},
attack: function() {
this.attackController('player', 10, 3);
this.attackController('computer', 10, 3);
},
specialAttack: function() {
this.attackController('player', 30, 5);
this.attackController('computer', 30, 5);
},
heal: function() {
if (this.playerHealth <= 90) {
this.playerHealth += 10;
} else {
this.playerHealth = 100;
}
this.turns.unshift({
isPlayer: true,
text: 'Player heals for ' + 10,
});
},
randomDamage: function(max, min) {
return Math.floor(Math.random() * max, min);
},
checkWin: function() {
if (this.computerHealth <= 0) {
this.alertBox('YOU WIN! New Game?');
} else if (this.playerHealth <= 0) {
this.alertBox('LOSER!!! New Game?');
}
return false;
},
alertBox: function(message) {
if (confirm(message)) {
this.isRunning = false;
this.startGame();
} else {
this.isRunning = false;
}
return true;
},
restart: function() {
this.isRunning = false;
this.startGame();
},
addToLog: function(attacker, receiver, damage) {
this.turns.unshift({
isPlayer: attacker === 'player',
text: attacker + ' hits ' + receiver + ' for ' + damage,
});
},
clearLog: function() {
this.turns = [];
},
setReceiver: function(attacker) {
if (attacker === 'player') {
return 'computer';
} else {
return 'player';
}
},
damageOutput: function(attacker, health) {
if (attacker === 'player') {
damage = this.randomDamage(maxRange, minRange);
this.computerHealth -= damage;
}
},
},
});
如果您愿意,Github仓库是here。谢谢!
最佳答案
您的attack
(和specialAttack
)功能会同时攻击两个玩家:
attack: function() {
this.attackController('player', 10, 3);
this.attackController('computer', 10, 3);
},
当前,它正在检查每个
attackController
调用是否获胜。因此,当第一个攻击者(player
)获胜时,游戏将重置,第二个玩家进行攻击。因此,我的建议是将
checkWin
从attackController
移到attack
函数中: attack: function() {
this.attackController('player', 10, 3);
this.attackController('computer', 10, 3);
this.checkWin();
},
与
specialAttack
相同。代码/ JSFiddle:https://jsfiddle.net/acdcjunior/wwc1xnyc/10/
请注意,当玩家获胜时,在上面的代码中,即使游戏结束了,计算机仍将“反击”。如果您想终止该操作,请在游戏结束后让checkWin返回:
checkWin: function() {
if (this.computerHealth <= 0) {
this.alertBox('YOU WIN! New Game?');
return true;
} else if (this.playerHealth <= 0) {
this.alertBox('LOSER!!! New Game?');
return true;
}
return false;
},
并将
if
添加到attack
(和specialAttack
): attack: function() {
this.attackController('player', 10, 3);
if (this.checkWin()) return;
this.attackController('computer', 10, 3);
this.checkWin();
},
更新的小提琴:https://jsfiddle.net/acdcjunior/wwc1xnyc/13/