- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Canvas 上使用kineticJS创建一个简单的游戏(只是一些练习)并设法让我的玩家射击子弹。对于生成的敌人也是如此。每当最后一颗子弹离开舞台时,他们就会发射一颗子弹。
但是:我希望所有敌人(可变数量)以 2 秒的间隔发射 3 颗子弹。但我完全陷入困境,不知道如何完成它。
有人可以看看我的 fiddle ,看看发生了什么吗? http://jsfiddle.net/eRQ3P/6/
注意:第 573 行是循环函数(每 30FPS 绘制子弹等)
这是我创建新项目符号对象的代码:( fiddle 中的第 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();
}
}
提供新项目符号的函数:( fiddle 第 247 行)
function createEnemyBullet(enemy) {
var blt = new Enemybullet(player.sprite.getX(), player.sprite.getY(), enemy.sprite);
ammoLayer.add(blt.sprite);
enemy.bullets.push(blt);
}
最佳答案
这个问题最难的部分可能是弄清楚何时绘制每颗子弹,以便在每 2 秒的时间间隔内发射三颗子弹。为了使子弹均匀发射,您需要将间隔中的帧数除以该间隔中要发射的子弹数量。
因为您以每秒 30 帧的速度运行游戏,所以 2 秒等于 60 帧。
60 frames / 3 bullets = 20 frames/bullet
因此,我们将每 20 帧或每 20 次为每个敌人创建一颗新子弹 refreshLoop()
被调用,里面 refreshLoop()
,你现在必须循环遍历每个敌人在 bullets
中拥有的所有子弹。数组,因为现在可以不止一个。
事实上,bullets
中可以有多个项目符号。数组给从数组中删除项目符号的方式带来了一个新问题。以前,您依赖于这样一个事实:一次一个项目符号意味着它始终是数组中的第一个项目符号,因此您的代码称为 bullets.splice(0, 1);
。然而,当玩家四处移动并且敌人向不同位置开火时,完全有可能子弹离开屏幕并比之前发射的子弹更快被移除。这将导致正确的子弹 Sprite 被删除,但数组中的第一个子弹将从 bullets
中删除。 ,所以在 refreshLoop()
中不会再更新了,它只会坐在屏幕上什么都不做。
为了避免这种情况,需要向敌人传递子弹'draw()
函数 bullets
中的索引正在绘制的子弹所在的位置。由于无论如何您都需要循环遍历数组,因此索引已经在 refreshLoop()
中。 ,所以只需将其传递给 draw()
。现在,每次需要取出子弹时,您只需调用bullets.splice(bulletIndex, 1);
即可。
希望你不要介意;我 fork 了你的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
}
}
关于javascript - 在规定时间内向每个敌人发射 3 颗子弹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15569085/
我需要在每个vagrant up上运行vagrant,这可能吗?例如,此规定仅在第一个 vagrant up 上运行: config.vm.provision "shell", privileged:
我正在将一些 XML 传递给 RESTful Web 服务: Web 服务将解码该 XML,并且我想确保该 XML 有效。 我使用架构来创建 Java 对象,
我有一个 Django 小网站,用户可以在评论中链接到其他网站上的图片。这绝不是核心功能。 我刚刚将整个站点移至 SSL。这在大多数情况下都运行良好,但远程图像显然并不总是可以通过 SSL 获得。只有
如果我要创建一个所有 HTML 内容均由 ReactJS 组件生成的网站,它是否符合 WCAG AA 级标准? IE。屏幕阅读器能够浏览通过 JavaScript 代码呈现的内容吗? 如果答案是肯定的
我使用的是 ubuntu 13.04 机器,我已经正确安装了 vagrant。 以下是版本 Vagrant : Vagrant 1.5.1 虚拟盒子:4.2.10_Ubuntu84101 我正在运行一
我正在为 Vagrant 编写一个配置脚本,以安装部署使用 Meteor 1.6 开发的应用程序所需的所有软件包。到目前为止,脚本运行良好,但在执行过程中的三个点上,我在终端窗口中得到以下红色输出:
我需要简单地从我的 iPhone 应用程序向用户帐户发送一条推文,但是我所看到的内容对于我需要做的事情来说似乎有点繁重,而且我发现的所有内容似乎都有点旧并且我担心我添加的内容可能不符合新的 Twitt
背景 通过 union 讨论类型双关的大多数未定义或实现定义的性质通常引用以下位,这里通过@ecatmur ( https://stackoverflow.com/a/31557852/2757035
我是一名优秀的程序员,十分优秀!