Javascript Starfield canvas程序占用太多CPU
我使用Javascript Starfield canvas程序占用太多CPU,javascript,html,canvas,cpu-usage,Javascript,Html,Canvas,Cpu Usage,我使用canvas创建了一个starfield,它可以正常工作: <!DOCTYPE HTML5> <html> <head> <title>StarField</title> <style> * { margin: 0; padding: 0; }
canvas
创建了一个starfield,它可以正常工作:
<!DOCTYPE HTML5>
<html>
<head>
<title>StarField</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
width: 100%;
height: 100%;
}
</style>
</head>
<body onLoad="startGame()"></body>
<script type="text/javascript">
var NO_OF_STARS = 512;
var stars = [];
function startGame() {
gameArea.start(); /* Makes the canvas */
gameRun = requestAnimationFrame(gameArea.update); /* Starts the game and coordinates all the animations */
window.addEventListener("keydown", function(e) {
if(e.keyCode == 27) { /* ESC stops everything */
stopEverything();
}
});
}
var gameArea = {
canvas : document.createElement("canvas"),
start : function() {
document.body.appendChild(this.canvas);
this.canvas.width = document.body.clientWidth;
this.canvas.height = document.body.clientHeight;
},
update : function() {
gameArea.clear(); /* Fills the canvas with #000000 */
gameArea.drawStars(); /* Draws the stars */
gameRun = requestAnimationFrame(gameArea.update); /* Repeat the whole thing */
},
drawStars : function() {
var ctx = gameArea.canvas.getContext("2d");
if(stars.length == 0) {
for(var i = 0; i < NO_OF_STARS; i++) {
var opacity = ((Math.floor(Math.random() * 10) / 10) + .1);
stars.push([getRandomInt(0, gameArea.canvas.width - 1), getRandomInt(0, gameArea.canvas.height - 1),opacity]);
ctx.beginPath();
ctx.strokeStyle = "rgba(255, 255, 255, " + opacity + ")";
ctx.moveTo(stars[i][0], stars[i][1]);
ctx.lineTo(stars[i][0] + 1, stars[i][1] + 1);
ctx.stroke();
}
} else {
for(var i = 0; i < NO_OF_STARS; i++) {
ctx.strokeStyle = "rgba(255, 255, 255, " + stars[i][2] + ")";
stars[i][0] -= ((stars[i][2] == 1.0) ? 5 :
(stars[i][2] >= 0.8) ? 4 :
(stars[i][2] >= 0.5) ? 3 :
(stars[i][2] >= 0.3) ? 2 :
1);
if(stars[i][0] < 0) {
var opacity = ((Math.floor(Math.random() * 10) / 10) + .1);
stars.splice(i, 1, [gameArea.canvas.width, getRandomInt(0, gameArea.canvas.height - 1), opacity]);
}
ctx.beginPath();
ctx.moveTo(stars[i][0], stars[i][1]);
ctx.lineTo(stars[i][0] + 1, stars[i][1] + 1);
ctx.stroke();
}
}
},
clear : function() {
var ctx = this.canvas.getContext("2d");
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
}
};
/**
* Returns a random integer between min (inclusive) and max (inclusive)
*/
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function stopEverything() {
cancelAnimationFrame(gameRun);
}
</script>
</html>
斯塔菲尔德
* {
保证金:0;
填充:0;
}
身体{
宽度:100%;
身高:100%;
}
var NO_OF_星=512;
var星=[];
函数startName(){
gameArea.start();/*生成画布*/
gameRun=requestAnimationFrame(gameArea.update);/*启动游戏并协调所有动画*/
window.addEventListener(“向下键”,函数(e){
如果(e.keyCode==27){/*ESC停止所有操作*/
停止一切();
}
});
}
var游戏区={
画布:document.createElement(“画布”),
开始:函数(){
document.body.appendChild(this.canvas);
this.canvas.width=document.body.clientWidth;
this.canvas.height=document.body.clientHeight;
},
更新:函数(){
gameArea.clear();/*用#000000填充画布*/
gameArea.drawStars();/*绘制星星*/
gameRun=requestAnimationFrame(gameArea.update);/*重复整个过程*/
},
drawStars:function(){
var ctx=gameArea.canvas.getContext(“2d”);
如果(stars.length==0){
对于(VarI=0;i=0.8)?4:
(星[i][2]>=0.5)?3:
(星[i][2]>=0.3)?2:
1);
if(星[i][0]<0){
var不透明度=((数学地板(数学随机()*10)/10)+.1);
拼接(i,1,[gameArea.canvas.width,getRandomInt(0,gameArea.canvas.height-1),不透明度);
}
ctx.beginPath();
ctx.moveTo(stars[i][0],stars[i][1]);
ctx.lineTo(星[i][0]+1,星[i][1]+1);
ctx.stroke();
}
}
},
清除:函数(){
var ctx=this.canvas.getContext(“2d”);
ctx.fillStyle=“#000000”;
ctx.fillRect(0,0,this.canvas.width,this.canvas.height);
}
};
/**
*返回最小值(含)和最大值(含)之间的随机整数
*/
函数getRandomInt(最小值、最大值){
返回Math.floor(Math.random()*(max-min+1))+min;
}
函数stopEverything(){
取消动画帧(游戏运行);
}
这里的问题是,它占用大量CPU(在装有AMD A8四核处理器的笔记本电脑上占60%到65%)。我希望这个canvas程序也能在其他有低端处理器的计算机上运行
我已经尝试减少无星星数
,但这并没有改变CPU使用率。然而,当增加它时,动画速度会大大减慢,CPU使用率也会降低(我不认为我会增加它,所以这并不重要)
我还注意到画布的大小在CPU使用率中起着重要作用。(我上面提到的笔记本电脑的分辨率为1366x768),但我希望画布能够显示整个视口
那么,如何降低CPU使用率呢?为每个星形定义路径、笔划样式并将其光栅化是相当昂贵的。尝试收集一些操作以减少负载-这都是为了做出妥协:
- 选择3-5个预定义的不透明度级别
- 绘制按预定义不透明度级别数划分的星星数
- 在循环之前使用单个beginPath()
- 使用rect()而不是moveTo+LineTo
- fill()循环完成后,继续执行下一个不透明度级别
- 获取3D上下文一次,而不是每次调用
- 对星形位置使用整数值(强制执行整数步长,在这种情况下可能不理想,但值得一试)
- 回收/重用星形条目,而不是拼接和创建新条目
- 尽可能减少计算和条件的数量
- 将帧速率降低到30 FPS(每隔一次切换RAF以绘制)。60 FPS很好,但我们也可以像电影一样以30 FPS的速度拍摄(尽管它们从运动模糊中受益;我们可以通过使用嵌入“运动模糊”的精灵而不是绘制矩形来作弊)
- 可选:将每个字段层存储为单独的画布,绘制为图像(速度更快,但需要更多内存)。可以通过旋转和/或翻转画布来进行变化