2

自分が取り組んでいるゲームのアニメーションがありますが、繰り返されないようです。スペースバーを押すと、キャンバスの上部に円を「発射」するイベントがトリガーされます。問題は、キーをもう一度押すとアニメーションが開始されないことです。これが私が書いたサンプルコードです:

var canvas, ctx,
    spaceKey = false,
    upKey = false,
    downKey = false,
    canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d'),
    shotX = 150, shotY = 280;

function loop() {
    if (spaceKey) shoot();
}

function keyDown(e) {
    if (e.keyCode == 32) spaceKey = true;
}
function keyUp(e) {
    if (e.keyCode == 32) spaceKey = false;
}

function shoot() {
    setTimeout(function() { if (shotY > 0) {
        ctx.clearRect(shotX-5,shotY-5,600,20);
        ctx.beginPath();
        ctx.arc(shotX, shotY,4,0,Math.PI * 2, false);
        ctx.fillStyle = "yellow";
        ctx.fill();
        ctx.closePath();

        shotY = shotY - 1;

        shoot();

    } else
        ctx.clearRect(shotX-5,shotY-5,600,20);
    }, 100);
}

(function init() {
    setInterval(loop, 10);
    document.addEventListener('keydown', keyDown, false);
    document.addEventListener('keyup', keyUp, false);
})();
//init();

私が使用する理由はkeyUpkeyDown異なるキーを使用する他の関数があるためです。このコードは、この機能のみを表示するように変更されました。私が話していることをわかりやすくするために、JSFiddleを作成しました。私が持っている他の機能も同様に構造化されて機能しますが、唯一の違いは、その持続時間がキーを押すことによって直接制御されないことです。

4

2 に答える 2

2

あなたのコードはあまり再利用できません。オブジェクトを使用してキャンバス上のエンティティを表すことを検討する必要があります。私はあなたの仕事をする簡単なコードを作成しましたが、それはあまり再利用可能ではありません(あなたが作成したボールのような単純なエンティティを作成するためにそれを再利用することはできますが)。このjsFiddleを確認してください。

コードの問題は、その黄色いボールが画面のtoに到達したときに、shotYが0の場合、画面からボールを​​消去しますが、をリセットしshotYたり、ホーム(元の位置)でボールを再描画したりしないことです。 )。

これを行うための単純なBallオブジェクトを作成しました-

function Ball() {
    this.x = 150;
    this.y = 295;
}
Ball.prototype.draw = function(newx, newy) {
    ctx.clearRect(this.x-5,this.y-5,600,20);
    newx = newx || this.x;
    newy = newy || this.y;
    this.x = newx; this.y = newy;
    var ball = this;
    ctx.beginPath( );
    ctx.arc(ball.x, ball.y,4,0,Math.PI * 2, false);
    ctx.fillStyle = "yellow";
    ctx.fill();
    ctx.closePath();
}
Ball.prototype.shootUp = function() {
    var ball = this;
    inter = setInterval(function () {
        if(ball.x <= 0) clearInterval(inter);
        ball.draw(ball.x, ball.y-20);
    }, 100);
}

関数を変更しましたshoot-

function shoot() {
    var currentBall = new Ball();
    currentBall.draw();
    currentBall.shootUp();
}

繰り返しになりますが、これは単なる例です。あなたはそれに多くの改善を加えることができます。まず、すべての入力を管理するための入力エンジンが必要です。次に、キャンバス上にあるすべてのオブジェクトを表す汎用エンティティクラスが必要です。のようにBall。そして最後に、これらすべてをバインドするゲームエンジンが必要です。

于 2013-03-22T05:32:38.687 に答える
2

「弾丸」は1つだけです。弾丸は、でインスタンス化される個別のオブジェクトである必要がありますshoot()

私が通常「パーティクル」を処理する方法は、各インスタンスを格納するシングルトンオブジェクトを作成し、メインループでそれらすべてを更新することです。

簡単なBulletオブジェクトは次のとおりです。

function Bullet(){
    this.x = 150;
    this.y = 280;
    this.velX = 0;
    this.velY = -1;

    this.update = function(){
        this.y += this.velY;
    };

    this.draw = function(){
        ctx.beginPath();
        ctx.arc(this.x, this.y,4,0,Math.PI * 2, false);
        ctx.fillStyle = "yellow";
        ctx.fill();
        ctx.closePath();
    };
};

そして、これが弾丸を処理するBulletRendererシングルトンです。

BulletRenderer = function(){
    var bullets = [];

    this.push = function(bullet){
        bullets.push(bullet);
    };

    this.render = function(){
        for (var i in bullets){
            if (bullets[i].active){
                bullets[i].update();
                bullets[i].draw();
            } else {
                delete bullets[i];
            }
        }
    };

    return this;
}();

この例では、フレームごとにキャンバスをクリアしています。現在、射撃機構はレーザーのように機能します。個人的に私はこの振る舞いを変えるでしょう。

http://jsfiddle.net/NAJus/18/

于 2013-03-22T05:36:20.670 に答える