我正在尝试用我的画布上的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);
}
答案 0 :(得分:1)
这个问题最困难的部分可能是弄清楚何时抽出每个子弹,每隔2秒钟发射一次子弹。要使子弹均匀点火,您需要将间隔中的帧数除以该间隔内要点击的子弹数。
因为你以每秒30帧的速度运行游戏,所以2秒等于60帧。
60 frames / 3 bullets = 20 frames/bullet
所以,我们要为每个敌人每20帧创建一个新的子弹,或者每20次调用refreshLoop()
,在refreshLoop()
内,你现在必须遍历所有的每个敌人在其bullets
数组中都有子弹,因为现在不仅可以有一个。
bullets
阵列中可能有多个子弹的事实会给子弹从阵列中移除的方式带来新的问题。以前,您依赖的事实是,一次一个子弹意味着它将始终是数组中的第一个,因此您的代码称为bullets.splice(0, 1);
。然而,当玩家四处移动并且敌人在不同位置射击时,完全有可能让子弹离开屏幕并且比在其之前发射的子弹更早被移除。这将导致删除正确的子弹精灵,但数组中的第一个子弹将从bullets
中删除,因此它不再在refreshLoop()
中更新,它只会坐在屏幕无所事事。
为了避免这种情况,有必要向敌人的子弹'draw()
函数传递被绘制的子弹所在的bullets
中的索引。由于您无论如何都需要遍历数组,因此索引已经在refreshLoop()
中,因此请将其传递给draw()
。现在,每次需要移除子弹时,您只需拨打bullets.splice(bulletIndex, 1);
我希望你不介意;我分叉了您的fiddle,使用下面列出的更改进行更新。
编辑:新的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
}
}