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 は 1 つのスレッドだけで実行されるため、これらのコールバックはいずれも実行されません。

何が起こるかを詳しく見てみましょう。

イベントループ(JSコードを実行するためのキュー)では、最初はあなただけのバトル機能があります。

while ループの最初の繰り返しの後、イベント ループは次のようになります。

battle | attack | eattack

を使用setTimeout()する関数は、関数の後ろにキューに入れられますbattle()。次の繰り返しの後、次のようになります

battle | attack | eattack | attack | eattack

ただし、(e)attack()関数はまだ実行されていないため、変数healthと変数は変更されehealthません。これは、ブラウザがすべてのメモリを消費して故障するまで、永遠に続きます。

解決策として、次のようなものを導入することをお勧めします。

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

  dead();

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

多数の関数をキューに入れる代わりに、戦闘が終了するまで、1 つのラウンドの戦闘を次から次へとキューに入れます。

于 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 に答える