您好,我是编程的新手,我制作了一个简单的JavaScript,可以绘制简单的canvas.arc圆并以2D x,y坐标移动。
出于好奇,我用1个粒子10、100、1000等来运行动画,以此类推,并增加了粒子的数量。
我观察到的是粒子平稳地移动到几百个,但随后变得非常滞后*(抱歉,我不知道这种现象的正确定义)
我当时在想,我的计算机怎么能运行更加复杂,如此顺畅却又难以运行我难以编写的脚本的游戏和软件?
我想知道背后的原因或背后的理论!
ps抱歉,无论如何我对英语不满意,请发布可帮助我理解此问题的资源或其他链接。
这是代码。它非常简单,但是如果有改善性能的方法,请告诉我id,以备将来编写脚本之需。
尝试增加粒子数:
var particleCount = 10000;
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
function(callback){
window.setTimeOut(callback,1000/60);
};
})();
var particleCount = 100,
particles = [];
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var wW = window.innerWidth, wH = window.innerHeight;
canvas.width = wW;
canvas.height = wH;
function paintCanvas(){
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.fillRect(0,0,wW,wH);
}
function Particle(){
this.x = Math.random() * wW;
this.y = Math.random() * wH;
var numx = Math.random()*2;
var numy = Math.random()*2;
numx *= Math.floor(Math.random()*2) == 1 ? 1 : -1;
numy *= Math.floor(Math.random()*2) == 1 ? 1 : -1;
this.vx = numx;
this.vy = numy;
this.radius = Math.random() * (Math.random()*5);
this.draw = function(){
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,false);
ctx.fill();
}
}
for (var i=0; i<particleCount; i++){
particles.push(new Particle());
}
function draw(){
paintCanvas();
for(var i = 0; i < particleCount; i++){
p = particles[i];
p.draw();
}
update();
}
function update(){
for (var i =0; i < particleCount; i++){
p = particles[i];
p.x += p.vx;
p.y += p.vy;
if(p.x + p.radius > wW){
p.x = p.radius;
}
else if(p.x - p.radius < 0){
p.x = wW - p.radius;
}
if(p.y + p.radius > wH){
p.y = p.radius;
}
else if(p.y - p.radius < 0){
p.y = wH - p.radius;
}
}
}
function animloop(){
draw();
requestAnimFrame(animloop);
}
animloop();
作为小提琴:https://jsfiddle.net/b8xbv7fu/
最佳答案
JavaScript很慢
这是javascript的本质,而不是代码的错误。 Javascript是一种高级解释语言。高级手段是使用CPU无法直接理解的对象和结构进行大量抽象的,因此需要额外的工作才能完成一些更基本的事情。解释意味着要执行指令,有一个程序会解释每个指令,然后调用特殊的内置(本机)函数来运行程序的逻辑。这也会产生开销。
当您将Javascript与C ++之类的语言进行比较时,您将无法竞争。 C ++是一种编译的中低级语言。编译是指在其可以运行之前,将其代码转换为机器语言或对由操作系统装入的可移植内部机器语言进行操作码。机器语言基本上是CPU可以理解的一组指令,可以直接执行而无需其他代码。
它为程序员提供了一个较低的抽象级别,有些人说它更难编写代码,更适合于CPU的设计。另外,编译器可以利用诸如CPU寄存器(非常快的变量)之类的特定硬件。并发(CPU有两个逻辑设备,一个用于浮点运算,一个用于整数运算FPALU和ALU(算术逻辑单元)。)如果要加数字,有些则是浮点运算,有些则是整数,如果仔细编写,编译器将确保这些操作是同时完成的。 C ++和类似语言还可以利用Javascript无法利用的许多其他功能。 (直接访问硬件,具有多线程能力,直接内存访问以及使用可以快速移动大量数据的特殊内存指令。
编译后的低级语言之所以称为本机语言,是因为CPU可以理解该代码,而Javascript必须在每次需要它才能运行时都解释每条指令。
最好的Java脚本(使用通常称为ASM.js的语言子集)是编译语言的十分之一。 Javascript绝不会与C / C ++等语言竞争
您还可以使用最低级别的语言,即汇编语言,仅使用CPU可以使用的指令为一种类型的CPU专门编写该语言。几乎没有抽象,写得好比C / C ++快2倍或更多。
Javascript是开始学习的好地方
学习Java脚本是一个好的开始,您学习Java的技能可以转移到任何其他语言。 JavaScript已经走了很长一段路。 10年前,在JS中闻所未闻的1000个动画对象现在可以编写合理的2D和3D游戏。
您指的滞后是由于帧速率下降。如果可以,JavaScript将以每秒60帧的速度运行。如果您付出很多工作,将被迫跳过一帧。结果是帧速率变化,并且出现抖动或抖动的动画。有补偿的方法。
在为JS编写游戏时,一定要熟悉JS的工作原理,慢速和快速。可悲的是,一般规则是代码越容易编写,结果越慢。通过仅执行所需的操作(例如,不在屏幕上时不处理对象物理,并且不根据需要预先计算数据,您真的需要1000个对象还是需要100个图像)来做到明智的设计也很重要。 10个预先绘制的粒子具有相似的效果)
Javascript是一门伟大的语言,具有表现力,宽容性和可移植性。但是,您必须接受它的缺点(即它的速度很慢)。如果您想编写高性能游戏,则最好学习C ++。