0

以下のコードは、ユーザーがスペースバーを押したときに小さな赤い div を画面の上に移動するためのものです。関数「撃つ」で、新しいdivを作成し、「moveLazer」関数から画面を上に移動し始める前にタイムアウトを設定します。

問題: 数回撮影すると、1 つの div が画面の上部に到達すると「lazerLifeCycle」変数がクリアされますが、まだ動いているがまだ上部にない 2 番目または 3 番目の div のタイムアウトもクリアされます。私が見たところ、 setInterval を使用しても問題は解決しません。lazerLifeCycle がグローバルであるため、私はそれを知っていますが、それを行う正しい方法がわかりません。助けてください!jsとhtmlは以下です。コピーして貼り付けて試してみたい場合は、2 つの異なるファイルであることに注意してください。Firefox または Chrome で実行します。IEでは何もしません。

//level3.js

var lazerId = 1;

var init = function(){
    var ship = document.getElementById('randRect');
    ship.style.left = '700px';
    ship.style.top = '300px';
}

document.onkeyup = function(e) {
  if(e.keyCode == 37) {
    moveLeft();
  } else if(e.keyCode == 39){
    moveRight();
  } else if(e.keyCode == 32){
    shoot();
  }
}

var shoot = function(){
    lazerId = lazerId + 1;
    var ship = document.getElementById('randRect');
    width = parseInt(ship.clientWidth);
    xPos = parseInt(ship.style.left);
    middle = ((xPos + (width/2)) - 3) + 'px'; //-3 is to center it i think
    var lazer = document.createElement('div');
    lazer.id = lazerId;
    var body = document.getElementById('body');
    body.appendChild(lazer);
    lazer.style.position = 'absolute';
    lazer.style.width = '7px';
    lazer.style.height = '13px';
    lazer.style.left = middle;
    lazer.style.top = '287px';
    lazer.style.backgroundColor = 'red';
    lazerLifeCycle = setTimeout('moveLazer(' + lazerId.toString() + ');', 10);
}

var moveLazer = function(lazerElementId){
    var lazer = document.getElementById(lazerElementId.toString());
    var lazerTop = parseInt(lazer.style.top);
    if( (lazerTop - 1) < 0){
        lazer.style.top = '0px';
        clearTimeout(lazerLifeCycle);
    } else {
        lazer.style.top = (lazerTop - 1) +'px'
        lazerLifeCycle = setTimeout('moveLazer(' + lazerElementId.toString() + ');', 10);
    }
}

var moveLeft = function(){
    var ship = document.getElementById('randRect');
    shipXPos = parseInt(ship.style.left);
    if( (shipXPos - 15) < 0){
        ship.style.left = 0+'px';
    } else {
        ship.style.left = shipXPos - 15+'px';
    }
}

var moveRight = function(){
        var ship = document.getElementById('randRect');
    shipXPos = parseInt(ship.style.left);
    if( (shipXPos + 15) > 1300){
        ship.style.left = 1300+'px';
    } else {
        ship.style.left = shipXPos + 15+'px';
    }
}

window.onload = init;

//level3.html
<html>
    <head>
        <title>random</title>
        <style type="text/css">
            .random{
                position:absolute;
                background: orange;
                padding: 7px;
            }
        </style>
        <script src="level3.js" type="text/javascript">
        </script>
    </head>
    <body id="body">
        <div id="randRect" class="random"><center><-- or --><center></div>
    </body>
</html>
4

1 に答える 1

0

ワーキングデモ

OK、単純化されたコードと変更されたコードがあります。

var shoot = function(){
    lazerLifeCycle = moveLazer(lazerId);
}

var moveLazer = function(lazerElementId){
    var lazer = document.getElementById(lazerElementId.toString());
    var lazerTop = parseInt(lazer.style.top);
    if( (lazerTop - 1) < 0){
        lazer.style.top = '0px';
    } else {
        lazer.style.top = (lazerTop - 1) +'px'
        setTimeout(function(){moveLazer(lazerElementId);}, 10);
    }
}

基本的に、タイムアウトのクリアについて心配する必要はありません。指示しない限り、タイムアウトは再発しないからです。また、複数のレーザーを発射できる場所にするには、最初に渡された ID を参照する必要がありますmoveLazer。基本的にはレーザーが上に当たるまで続きます。また、複数のショットのサポートを可能にします。</p>

于 2012-06-28T17:08:55.773 に答える