2013-03-22 2 views
1

Я пытаюсь создать простую игру с кинетикой на моем холсте (только на практике) и сумел заставить моего игрока стрелять в пули. То же самое касается врагов, которые порождаются. Они стреляют в пулю каждый раз, когда последняя пуля покидает сцену.Стреляйте 3 пули в заданное время от каждого врага

Однако: я хотел бы, чтобы все враги (переменное число) стреляли 3 пули с интервалом в 2 секунды. Но я застрял полностью и не могу понять, как это сделать.

Может ли кто-нибудь посмотреть мою скрипку и посмотреть, что случилось? http://jsfiddle.net/eRQ3P/6/

Примечание: линия 573 является функцией петли (А рисуют пули и такой каждый 30fps)

Вот код, где я создать новый объект пули: (Line 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); 
} 

ответ

1

Вероятно, самая трудная частью этой проблемы является выясняя, когда нужно нарисовать каждую пулю, чтобы сделать три выстрела за каждые 2-секундный интервал. Чтобы пламя срабатывало равномерно, вы хотите разделить количество кадров в интервале на количество пуль, чтобы стрелять в этот интервал.

Поскольку вы используете игру со скоростью 30 кадров в секунду, 2 секунды равно 60 кадрам.

60 frames/3 bullets = 20 frames/bullet

Итак, мы собираемся создать новую пулю для каждого врага каждые 20 кадров, или каждый двадцатый раз refreshLoop() называется, и внутри refreshLoop(), теперь вы должны перебрать все пули каждого у врага есть массив bullets, потому что теперь может быть больше, чем один.

То, что может быть более одной пули в массиве bullets, вводит новую проблему, чтобы пули удалялись из массива. Раньше вы полагались на то, что одна пуля за раз означает, что она всегда будет первой в массиве, поэтому ваш код называется bullets.splice(0, 1);. Однако, когда игрок движется и враги стреляют в разных местах, вполне возможно, что пуля покинет экран и удаляется раньше, чем тот, который был уволен перед ним. Это приведет к удалению правильного пулевого спрайта, но первая пуля в массиве будет удалена с bullets, поэтому она больше не будет обновляться в refreshLoop(), и она просто сидит на экране, ничего не делая.

Для того чтобы избежать этого, необходимо передать вражеским пулям draw() значение индекса в bullets, на котором находится нарисованная пуля. Так как вам все равно нужно прокручивать массив, индекс уже под рукой в ​​refreshLoop(), поэтому просто передайте это draw(). Теперь, каждый раз, когда нужно удалить пулю, вы можете просто позвонить bullets.splice(bulletIndex, 1);

Надеюсь, вы не против; Я разветвил ваш fiddle, чтобы обновить его с изменениями, перечисленными ниже.

EDIT: Новый fiddle для взрыва, а не постоянного пожара.

// 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 
    } 
} 
+0

Это была логика синхронизации, которая в этом случае не помогла мне. Кажется, что пули стреляют с регулярным интервалом, но не в пары из 3 (поп, поп, поп .... жду ... поп, поп, поп ... и т. Д.) – CaptainCarl

+1

Я действительно спрашивал, может быть то, что вы хотели ... Я уточню это вместо этого. – jonhopkins

+0

Отредактировал ответ новой скрипкой и добавил измененный код внизу – jonhopkins

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