我正在开发一个小游戏,只是为了练习,这是第一次。正如你在我的 fiddle 中看到的那样,当屏幕上有很多子弹和/或敌人时,它会在一段时间后开始掉帧。有没有办法通过某种方式缓存它来减少这种情况?
我读过一些关于预渲染的内容。但是因为我使用的是 Kinetic 库,所以我不认为这是我能做的事情。是否有一些提示和技巧可以减少它的帧丢失?或者使用 KineticJS 进行预渲染的方法?
这是我的 fiddle :http://jsfiddle.net/3nEUv/3/
我认为子弹的绘制是一个真正的破坏者:( fiddle 中的第 713 行)
function Enemybullet(destinationX, destinationY, enemySprite) {
this.id = 'enemyBullet';
this.x = enemySprite.getX()+(enemySprite.getWidth()/2);
this.y = enemySprite.getY()+(enemySprite.getHeight()/2);
this.damage = enemy.damage;
//The targetX and Y are compensated by the player width and height. Subtract or add the halve of the player accordingly
if (this.x > player.sprite.x) {
var targetX = (destinationX - this.x)-(player.sprite.getWidth()/2);
targetY = (destinationY - this.y)-(player.sprite.getHeight()/2);
} else {
var targetX = (destinationX - this.x)+(player.sprite.getWidth()/2);
targetY = (destinationY - this.y)+(player.sprite.getHeight()/2);
}
var distance = Math.sqrt(targetX * targetX + targetY * targetY);
this.velX = (targetX / distance) * enemyAttackSpeed;
this.velY = (targetY / distance) * enemyAttackSpeed;
this.finished = false;
this.sprite = new Kinetic.Circle({
x: this.x,
y: this.y,
radius: 2,
fill: 'black',
name: 'enemyProjectile'
});
this.draw = function(indexEnemy, indexBullet) {
var mayDelete = false;
this.x += this.velX;
this.y += this.velY;
this.sprite.setAbsolutePosition(this.x, this.y);
//console.log(this.sprite.getX());
if(collisionDetection(this, player) == true) {
player.collide(this);
mayDelete = true;
}
if (bulletLeftField(this.sprite) == true) {
mayDelete = true;
}
if (mayDelete == true) {
delete this;
this.sprite.remove();
//console.log(enemies[indexEnemy].bullets);
if (enemies[indexEnemy]) {
enemies[indexEnemy].bullets.splice(indexBullet, 1);
}
}
ammoLayer.draw();
}
}
提前致谢!
最佳答案
我能想到的一些事情会有所作为。
1/对象池化
这是回收对象的技术。创建新的(并通过垃圾收集删除旧的)是一种浪费。
这是通过将不再需要的项目符号移动到临时数组来完成的。就像它离开屏幕或击中敌人时一样。然后,当您需要新子弹时,从临时数组中取出对象并重新初始化子弹。
查看 this link (搜索标题“回收鱼”)
2/四叉树碰撞检测
这是一个很好的碰撞优化技术。不是检查你的子弹是否在每次滴答时都与每个敌人相撞,而是只检查那些与你的子弹位于同一“四边形”中的敌人。
这是一个很好的tutorial .
3/缓冲
使用屏幕外 Canvas 。我有一个用于背景、用户界面、玩家/敌人/子弹。这有一些变化,但根据我的经验,最有效的是将所有元素绘制到屏幕外层;然后每次勾选,如果该层已更改,您只会重绘(到屏幕外层)图像。完成后,您将每个屏幕外层编译为一个可见层。我已经在我的手机游戏中成功使用了这种技术,该游戏一次在屏幕上显示了 90 多个对象,在 iPhone4s 上以 60fps 的速度运行。
编辑:刚刚看到这个有趣的演示,展示了 3 种不同框架的性能,包括 Kinetic。在我的台式机和移动设备上,Kinetic 对我的影响最大。
关于javascript - 更好的缓存以消除帧丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15617678/