2013-03-22 2 views
2

У меня есть анимация для игры, над которой я работаю, которая, похоже, не повторится. Когда нажимается пробел, он вызывает событие, которое «стреляет» по кругу вверху холста. Проблема в том, что при повторном нажатии клавиши она не будет инициировать анимацию. Вот пример кода, который я написал:Javascript canvas анимация не может использоваться более одного раза

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(); 

Причина я использую keyUp и keyDown потому, что у меня есть другие функции, которые используют разные ключи. Этот код был изменен для отображения только этой функции. Чтобы было легче видеть, о чем я говорю, я создал JSFiddle. Другие функции, которые у меня есть, аналогично структурированы и работают, с той лишь разницей, что его продолжительность не контролируется напрямую нажатием клавиши.

+1

Если зажать пробел, вы получите ** ** несколько KeyDown события увольняют. В вашем коде это приводит к тому, что желтый шар ускоряется, когда он поднимается по экрану. Вы пытаетесь ускорить игру или пытаетесь стрелять несколькими шарами с одинаковой скоростью? – markE

+0

Это должно быть несколько пуль.Я думал, что заметил, что все быстрее. –

+0

Если пуля находится в движении вверх по экрану, пользователь может нажать пробел и запустить еще одну пулю? Или пользователь должен подождать, пока текущая пуля не выйдет из экрана? – markE

ответ

2

Я не считаю, что ваш код много повторно используется. Вы должны рассмотреть возможность использования объектов для представления объектов на холсте. Я создал простой код, который выполняет вашу работу, но он также не много повторно используется (хотя вы можете повторно использовать его для создания простой сущности, такой как созданный вами шар). Проверьте это jsFiddle.

Проблемы с кодом, когда что желтый шар достигает до экрана, то shotY является 0, то вы стираете мяч с экрана, но не сбрасывайте shotY и не перерисовывать мяч в его доме (исходное положение).

Я создал простой Ball объект, чтобы получить это done-

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. И, наконец, у вас должен быть игровой движок, чтобы связать все эти вещи.

+0

Это именно то, что я искал! Моя большая проблема в том, что я не создаю объекты при кодировании, что, вероятно, объясняет половину проблем, которые у меня есть. Я обязательно буду учитывать все ваши предложения! –

2

У вас есть только одна «пуля». Ваши пули должны быть отдельными объектами, которые создаются на shoot().

Способ, которым я обычно обрабатываю «частицы», заключается в создании одиночного объекта для хранения каждого экземпляра и обновления всех их в основном цикле.

Вот простой пуля объект:

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/

+0

+1 для номенклатуры ... Я назвал его 'Ball', вы называете его' Bullet' !! Совет. Вы должны назначать методы прототипу конструктора, а не самому объекту. – ShuklaSannidhya

+0

@Saan - Ха-ха. «Вы должны назначать методы прототипу конструктора, а не самому объекту». «Почему? – slamborne

+1

Поскольку определение методов при создании экземпляра объекта является серьезной проблемой производительности. Вы должны добавить их в свой прототип, чтобы все экземпляры могли передавать эти методы из прототипа, а не иметь собственную копию этих методов. - http://stackoverflow.com/questions/15497259/overriding-methods-in-javascript/15497685#15497685 – ShuklaSannidhya

Смежные вопросы