1

私は自分のキャンバスに kineticJS を使って簡単なゲームを作成しようとしています (ちょっとした練習です)。出現する敵も同様です。最後の弾丸がステージを離れるたびに、彼らは弾丸を撃ちます。

ただし、すべての敵(可変数)が2秒間隔で3発撃つようにしたいです。しかし、私は完全に立ち往生しており、それを成し遂げる方法がわかりません。

誰か私のフィドルを見て、何が起こっているか見てもらえますか? http://jsfiddle.net/eRQ3P/6/

注:573行目はループする関数です(そして30FPSごとに弾丸などを描画します)

新しい弾丸オブジェクトを作成するコードは次のとおりです:(フィドルの406行目)

function Enemybullet(destinationX, destinationY, enemySprite) {

    this.id = 'bullet';
    this.x = enemySprite.getX()+(enemySprite.getWidth()/2);
    this.y = enemySprite.getY()+(enemySprite.getHeight()/2);

    var targetX = destinationX - this.x,
        targetY = destinationY - this.y,
        distance = Math.sqrt(targetX * targetX + targetY * targetY);

    this.velX = (targetX / distance) * 5;
    this.velY = (targetY / distance) * 5;

    this.finished = false;

    this.sprite = new Kinetic.Circle({
        x: this.x,
        y: this.y, 
        radius: 3,
        fill: 'black',
        name: 'enemyProjectile'
    });

    this.draw = function(index) {

        var mayDelete = false;

        this.x += this.velX;
        this.y += this.velY;

        this.sprite.setAbsolutePosition(this.x, this.y);
        //console.log(this.sprite.getX());

/*
        if(enemyCollision(this) == true) {
            mayDelete = true;
        }*/

        if (bulletLeftField(this.sprite) == true) {
            mayDelete = true;
        }

        if (mayDelete == true) {
            this.sprite.remove();
            enemies[index].bullets.splice(0, 1);
            createEnemyBullet(enemies[index]);
        }



        ammoLayer.draw();
    }
}

そして、新しい箇条書きを提供する関数: (フィドルの 247 行目)

function createEnemyBullet(enemy) {
    var blt = new Enemybullet(player.sprite.getX(), player.sprite.getY(), enemy.sprite);
    ammoLayer.add(blt.sprite);
    enemy.bullets.push(blt);
}
4

1 に答える 1

1

おそらく、この問題の最も難しい部分は、2 秒間隔で 3 発発射されるように各弾丸をいつ描画するかを考え出すことです。弾丸を均等に発射するには、間隔内のフレーム数をその間隔内で発射する弾丸の数で割ります。

毎秒 30 フレームでゲームを実行しているため、2 秒は 60 フレームに相当します。

60 frames / 3 bullets = 20 frames/bullet

そのため、20 フレームごと、または 20 回目の呼び出しごとに各敵に新しい弾丸を作成します。refreshLoop()内部refreshLoop()では、各敵がそのbullets配列に持っているすべての弾丸をループする必要があります。 1つ以上。

配列に複数の弾丸が存在する可能性があるという事実は、bullets配列から弾丸を削除する方法に新しい問題をもたらします。以前は、一度に 1 つの箇条書きは常に配列の最初の箇条書きになるという事実に依存していたため、コードはbullets.splice(0, 1);. ただし、プレイヤーが動き回って敵が別の場所で発砲すると、弾丸が画面から出て、その前に発射された弾丸よりも早く除去される可能性があります。これにより、正しい弾丸スプライトが削除されますが、配列の最初の弾丸が から削除されるbulletsため、 で更新されなくなりrefreshLoop()、何もせずに画面に留まります。

これを回避するには、敵の弾丸の関数に、描画される弾丸が配置されているdraw()インデックスを渡す必要があります。bulletsとにかく配列をループする必要があるため、インデックスは で既に手元にrefreshLoop()あるので、これを に渡すだけdraw()です。これで、弾丸を削除する必要があるたびに、呼び出すことができますbullets.splice(bulletIndex, 1);

気にしないでください。以下にリストされている変更で更新するために、あなたのフィドルをフォークしました。

編集:持続射撃の代わりにバースト射撃用の新しいフィドル。

// Inside your Enemybullet definition
// One simple change to draw(), pass in the index of the bullet in the array
this.draw = function(indexEnemy, indexBullet) {

    var mayDelete = false;

    ...

    if (bulletLeftField(this.sprite) == true) {
        mayDelete = true;
    }

    if (mayDelete == true) {
        this.sprite.remove();

        // Since you now have multiple bullets, you'll have to make
        // sure you're removing the correct one from the array
        enemies[indexEnemy].bullets.splice(indexBullet, 1);
    }

    ammoLayer.draw();
}

...

// Inside your refreshLoop function
// If there are enemies they should be checked
if (enemies.length > 0) {
    for (var i = 0; i < enemies.length; i++) {
        enemies[i].draw();

        // At 30 frames per second, 3 bullets in 2 seconds would be
        // one bullet for every 20 frames. So, every 20 frames,
        // create a new bullet for each enemy
        if ((enemyShootTimer % 20) == 0) {
            createEnemyBullet(enemies[i]);
        }

        // The same way you draw all of the player's bullets,
        // loop through the array of bullets for this enemy,
        // and draw each one, passing in the new parameters
        if (enemies[i].bullets.length > 0) {
            for (var j = 0; j < enemies[i].bullets.length; j++) {
                enemies[i].bullets[j].draw(i, j);
            }
        }
    }
}

// Update loop for burst-fire instead of sustained fire
var burstTime = 10; // 10 frames between bullets, 3 per second
var needToShoot = ((enemyShootTimer % burstTime) == 0);
if (enemies.length > 0) {
    for (var i = 0; i < enemies.length; i++) {
        enemies[i].draw();

        // if the enemies still have bullets to shoot this burst
        // and if 10 frames have passed since the last shot
        // ( enemyBurstCounter is declared outside refreshLoop() )
        if (enemyBurstCounter < 3 && needToShoot) {
            createEnemyBullet(enemies[i]);
        }
        if (enemies[i].bullets.length > 0) {
            for (var j = 0; j < enemies[i].bullets.length; j++) {
                enemies[i].bullets[j].draw(i, j);
            }
        }
    }
    if ((enemyShootTimer % 60) == 0) {
        enemyBurstCounter = 0; // if 2 seconds have passed, reset burst counter
    } else if (needToShoot) {
        enemyBurstCounter++; // if the enemies shot, update burst counter
    }
}
于 2013-03-22T13:02:58.847 に答える