0

我的脚本运行,但是当它到达 setTimeout 部分时,它只是不喜欢它:( 浏览器崩溃,我必须退出。浏览器是错误的还是我搞砸了?

var health=100;
var ehealth=100;
var atk;
var eatk;

function attack(x){
x=Math.floor(Math.random()*11);
atk=x;
ehealth=ehealth-atk
document.write('Enemy Health:' + '   ' + ehealth + '   ')
}

function eattack(x){
x=Math.floor(Math.random()*11);
eatk=x;
health=health-eatk
document.write('Health:' + '   ' + health )
}

function dead(){
if(health<=0){
    document.write('You Lose');
}else{
    if(ehealth<=0){
  document.write('You Win');
}
}
}

function battle(){
document.write('Enemy Health:' + '&nbsp; &nbsp;' + ehealth + '&nbsp; &nbsp; Health: &nbsp; &nbsp;' + health + '<br/>\n')
while(health>=0&&ehealth>=0){
setTimeout(function(){
    attack(0)
},400)
setTimeout(function(){
eattack(0)
},400)
document.write("<br/>\n");
dead();
}
}

我是什么做的 :(

4

3 回答 3

1

问题是你的while循环:

while(health>=0&&ehealth>=0){
setTimeout(function(){
    attack(0)
},400)

您正在设置攻击功能以执行“无限”次数。

于 2013-10-22T11:57:43.133 回答
1

您的 while 循环不会终止。你触发了无穷无尽的 setTimeout() 回调,但是由于 JS 只在一个线程中执行,这些回调都不会被执行。

让我们更详细地看看会发生什么:

在事件循环(要执行的 JS 代码的队列)中,首先只有你的战斗功能。

在 while 循环的第一次迭代之后,事件循环仍然是这样的:

battle | attack | eattack

使用setTimeout()get 的函数在你的函数后面排队battle()。在下一次迭代之后,它看起来像这样

battle | attack | eattack | attack | eattack

但是仍然没有(e)attack()执行任何函数,因此healthandehealth变量保持不变。这种情况会一直持续下去,直到您的浏览器耗尽所有内存并崩溃。

作为解决方案,我建议引入如下内容:

function battleRound() {
  attack(0);
  eattack(0);

  dead();

  if( health>=0&&ehealth>=0 ) {
    // still a round to go
    setTimeout( battleRound, 400 );
  }
}

与其对众多函数进行排队,不如将一轮又一轮的战斗排入队列,直到战斗结束。

于 2013-10-22T12:02:44.093 回答
0

通常,您的代码会尝试设置无限数量的超时处理程序。

setTimeout 设置一些函数在将来运行,但它立即结束运行,不等到函数运行。因此,while 循环无限运行,因为内部没有任何东西会改变健康状况。

其他更好的解决方案是使用间隔 - 例如:

var game_interval;

function turn () {
  attack(0);
  eattack(0);
  if (health<=0 || ehealth<=0) {
    clearInterval(game_interval);
    dead();
  }
}

game_interval = setInterval(400,turn);
turn(); // first turn immediately
于 2013-10-22T12:26:41.083 回答