我一直在写一个小的粒子插件,因为我想了解物理如何为游戏工作。现在我已经尽我所能把它弄干净了,但是它感觉到缺少了一些东西。我重复的代码太多了吗?这是否可以在任何方面得到改善,例如在性能方面?
https://jsfiddle.net/zdufwLv6/
new explodeLayer({
particles: 17, xSpread: 5, ySpread: 20, colorIndex: 3, radius: 0, radiusMax: 100, x: 0, y: 0
})
function explodeLayer(obj) {
var self = this;
this.elem = document.getElementsByTagName('div');
this.particle = [];
this.radius = obj.radius;
this.color = ['red', 'yellow', 'cyan', 'orchid']
this.interval = 2 * Math.PI / obj.particles;
this.init = function() {
this.create();
this.blast();
}
this.create = function() {
for(var i = 0; i < obj.particles; i++) {
document.body.appendChild(document.createElement('div'));
this.elem[i].style.background = this.color[obj.colorIndex];
this.particle.push(new this.Properties(this.interval * i, obj.x, obj.y));
this.updatePosition(i);
}
}
this.Properties = function(angle, x, y) {
this.angle = angle;
this.x = x;
this.y = y;
this.vy = y;
this.vx = y;
}
this.updatePosition = function(index) {
this.elem[index].style.left = this.particle[index].x + 'px';
this.elem[index].style.top = this.particle[index].y + 'px';
}
this.move = function() {
for(var i = 0; i < this.particle.length; i++) {
this.particle[i].vy += 0.4;
this.particle[i].x += this.particle[i].vx;
this.particle[i].y += this.particle[i].vy;
this.updatePosition(i);
}
requestAnimationFrame(function() {
self.move.call(self);
});
}
this.blast = function() {
for(var i = 0; i < this.particle.length; i++) {
this.particle[i].x = Math.round(window.innerWidth) / 2 + this.radius * Math.cos(this.particle[i].angle);
this.particle[i].y = Math.round(window.innerHeight) / 2 + this.radius * Math.sin(this.particle[i].angle);
this.particle[i].vx = obj.xSpread * Math.cos(this.particle[i].angle);
this.particle[i].vy = obj.ySpread * Math.sin(this.particle[i].angle);
this.updatePosition(i);
}
requestAnimationFrame(function() {
self.move.call(self);
});
}
this.init();
}html, body { background: rgb(30, 30, 30)}
div { padding: 8px; position: absolute; border-radius: 100%}发布于 2016-03-22 12:29:45
我建议将动画循环移出一个单独的系统,并且您的对象至少有一个render和update方法(某种程度上是一个接口)。这样,您就有了一种集中的方法来控制呈现循环,您的对象不必担心呈现循环,同时保持对如何在对象中呈现和更新的知识。
let objects = [];
// Render loop
function renderLoop(){
requestAnimationFrame(renderLoop);
objects.forEach(object => object.update());
objects.forEach(object => object.render());
}
// Add objects
objects.push(new ExplodeLayer());
objects.push(new ExplodeLayer());
objects.push(new ExplodeLayer());
objects.push(new ExplodeLayer());
// Start loop
renderLoop();explodeLayer是一个构造函数。这是一种惯例,建筑工人的第一个字母的大写字母。应该是ExplodeLayer。
还建议将requestAnimationFrame调用作为呈现循环中的第一个调用。这样,调度下一个帧之前不会被缓慢的代码阻塞,并且您可以确保下一个回调已经准备好被调用,而不管代码是否慢下来。
this.updatePosition = function(index) {
this.elem[index].style.left = this.particle[index].x + 'px';
this.elem[index].style.top = this.particle[index].y + 'px';
}如果在画布中这样做可能会更好,以获得更好的性能,但我理解在DOM中需要这样做:但是,您可以通过使用CSS3转换(特别是translate3D转换)来进一步提高性能。它们的优点是硬件加速( GPU完成工作),使它们比正常的平滑。
最后你的爆炸层是..。一层。它是由粒子组成的。建议您为单个粒子创建一个单独的类。这样,你的爆炸层可以专注于作为一个层(计算位置、管理粒子等),而粒子可以专注于单个粒子的渲染方式(纹理、颜色等)。
https://codereview.stackexchange.com/questions/123527
复制相似问题