我正在用一个简单的例子测试HTML5画布,以绘制一些等距瓷砖。我使用的是requestAnimationFrame方法。然而,我可以看到大约8%的CPU使用在Chrome任务管理器中。
PS:我在使用Typescript
这是我的抽签循环:
private Draw = () => {
this.Context.clearRect(0, 0, this.Canvas.width, this.Canvas.height);
this.Context.imageSmoothingEnabled = false;
this.DrawCtx();
requestAnimationFrame(this.Draw);
}DrawCtx用这个函数调用另一个类:
public Draw(MousePosition: Array<number>, ClickPosition: any): void {
this.MousePosition = MousePosition;
this.ClickPosition = ClickPosition;
this.DrawBackground();
this.ParseMap();
this.Container.Draw();
this.DrawTiles();
}下面是drawTiles的一个片段(其他东西只是地图数组的一些for() )
if(!curtile.isDoor && typeof(this.Map.getMap().data[x - 1]) != "undefined" && this.Map.getMap().data[x - 1][y].height != 0 && this.Map.getMap().data[x - 1][y].height == (parseInt(curtile.height) + 1)) {
this.Container.drawImage(x + y + 500, this.Resources["1.png"], curtile.left, curtile.top - 24 - ((curtile.height - 1) * 6), 64, 64);
} else if(!curtile.isDoor && typeof(this.Map.getMap().data[x][y - 1]) != "undefined" && this.Map.getMap().data[x][y - 1].height != 0 && this.Map.getMap().data[x][y - 1].height == (parseInt(curtile.height) + 1)) {
this.Container.drawImage(x + y + 500, this.Resources["2.png"], curtile.left, curtile.top - 24 - ((curtile.height - 1) * 6), 64, 64);
} else if(!curtile.isDoor && ((typeof(this.Map.getMap().data[x][y - 1]) != "undefined" && this.Map.getMap().data[x][y - 1].height != 0 && this.Map.getMap().data[x][y - 1].height == curtile.height) || typeof(this.Map.getMap().data[x - 1][y]) != "undefined" && this.Map.getMap().data[x - 1][y].height != 0 && this.Map.getMap().data[x - 1][y].height == curtile.height) && typeof(this.Map.getMap().data[x - 1][y - 1]) != "undefined" && this.Map.getMap().data[x - 1][y - 1].height != 0 && this.Map.getMap().data[x - 1][y - 1].height == (parseInt(curtile.height) + 1)) {
this.Container.drawImage(x + y + 500, this.Resources["3.png"], curtile.left, curtile.top - 24 - ((curtile.height - 1) * 6), 64, 64);
} else {
this.Container.drawImage(x + y + 500, this.Resources["tile.png"], curtile.left, curtile.top - ((curtile.height - 1) * 6), Config.Game.TileWidth, Config.Game.TileHeight);
}this.Container是我的drawImage指标体系
export default class Container {
Objects: any = [];
Context: any;
constructor(Context: any) {
this.Context = Context;
}
public drawImage(index: number, ...drawArguments: any[]) {
this.Objects.push({
index: index,
args: drawArguments
});
}
public Draw(): void {
this.Objects.sort(function(a: any, b: any) {
return (a.index > b.index) ? 1 : ((b.index > a.index) ? -1 : 0);
});
for(var i in this.Objects) {
var object = this.Objects[i];
this.Context.drawImage.apply(this.Context, object.args);
}
this.Objects = [];
}
}为什么它只为一些drawImages使用~8-9%的CPU?我的密码怎么了?还是很正常?
发布于 2016-10-02 00:11:28
对于速度,一般规则是“在可用的最低级别上写”:类型记录增加了开销,在Javascript中编写需要速度的代码。
不使用(在?)使用标准循环迭代,速度更快。
不要使用apply,直接调用该函数,这是一个好的6倍的速度(更多的Chrome)。注意,这是用于调用操作,而不是调用函数中的代码。
每次调用绘图时,都会创建和销毁一个新数组。这将产生重大影响。重用对象,永远不要取消性能循环中的任何内容。即使必须取消对数组中放置的所有新对象的引用,也不要在绘制函数的末尾创建一个新对象。重新设置它的长度。'objects.length = 0‘不会产生构造新数组对象的开销。
var currentObjectCount = 0;
var objects = [];
function drawImage(index,...etc)
var o = objects[currentObjectCount];
if(o === undefined){
objects[currentObjectCount] = o = {};
}
o.index = index;
o.args = etc;
currentObjectCount += 1;
}在添加对象集currentObjectCount = 0之前,在每个帧的开头
在呈现循环(绘制函数)中,使用currentObjectCount来修剪排序的数组
objects.length = currentObjectCount;但是,如果您可以去掉排序,那么就不要修剪数组,在for循环中使用currentObjectCount。忽略当前框架不需要的任何对象。在数组中拥有额外的未使用的项目不需要花费任何费用,在需要时重用旧的项目不需要任何费用,取消引用需要花费成本,构建成本也不高。
你必须真正排序,任何类型的预排序,你可以做,将改进排序。在drawImage调用中使用插入排序,这只是一个简单的排序,它可以进行粗略的排序,从而使真正的排序更快。
但是对于呈现,您只需要在有重叠的情况下排序,如果您在任何阶段进行对象之间的距离或冲突测试,请使用该数据优化排序,保留两个对象数组,一个用于排序,另一个用于未排序。(35年来,我已经写了100部2D游戏,我从未在主渲染循环中使用过一种类型,一直有更好的方法。)
除掉传送带操作员。它很慢,而且绘制图像的变体不多,因此值得使用...进行开销。
飞吻是快速代码使用的规则。保持简单(第二个S是使首字母缩写)。保持简单并不意味着从表面上看您的代码是什么,而是简单到核心。
https://stackoverflow.com/questions/39808380
复制相似问题