首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >游戏中的爆炸动画插件

游戏中的爆炸动画插件
EN

Code Review用户
提问于 2016-03-22 09:36:08
回答 1查看 704关注 0票数 3

我一直在写一个小的粒子插件,因为我想了解物理如何为游戏工作。现在我已经尽我所能把它弄干净了,但是它感觉到缺少了一些东西。我重复的代码太多了吗?这是否可以在任何方面得到改善,例如在性能方面?

https://jsfiddle.net/zdufwLv6/

代码语言:javascript
复制
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();
}
代码语言:javascript
复制
html, body { background: rgb(30, 30, 30)} 
div { padding: 8px; position: absolute; border-radius: 100%}
EN

回答 1

Code Review用户

回答已采纳

发布于 2016-03-22 12:29:45

我建议将动画循环移出一个单独的系统,并且您的对象至少有一个renderupdate方法(某种程度上是一个接口)。这样,您就有了一种集中的方法来控制呈现循环,您的对象不必担心呈现循环,同时保持对如何在对象中呈现和更新的知识。

代码语言:javascript
复制
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调用作为呈现循环中的第一个调用。这样,调度下一个帧之前不会被缓慢的代码阻塞,并且您可以确保下一个回调已经准备好被调用,而不管代码是否慢下来。

代码语言:javascript
复制
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完成工作),使它们比正常的平滑。

最后你的爆炸层是..。一层。它是由粒子组成的。建议您为单个粒子创建一个单独的类。这样,你的爆炸层可以专注于作为一个层(计算位置、管理粒子等),而粒子可以专注于单个粒子的渲染方式(纹理、颜色等)。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/123527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档