3
\$\begingroup\$

I have been writing a small particle plugin since I want to learn how physics works for games. Now I have tried to get this as clean as I possible could but It feels something is missing. Am I repeating too much code? Could this be improved in any way such as in performance?

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%}

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

I would suggest moving out your animation loop to a separate system, and that your object at least have a render and update method (sort of an interface). That way, you have a centralized way to control the render loop, you're objects don't have to worry about the render loop while keeping the knowledge of how to render and update inside the object.

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 is a constructor. It's a convention that constructors have the first letter of words in capital letters. It should be ExplodeLayer.

Also suggesting you move requestAnimationFrame call as the first call in the render loop. That way, scheduling the next frame won't be blocked by slow code before it and you're assured that the next callback is ready to be called regardless of slowdowns in code.

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 is probably better when done in canvas for better performance, but I understand that there is an itch to do it in the DOM :D However, you can further improve performance by using CSS3 transforms, specifically the translate3D transforms. They have the advantage of being hardware-accelerated (the GPU does the work), making them smoother than normal.

Lastly, your explode layer is... a layer. It's comprised of particles. Suggesting you create a separate class for a single particle. That way, your explode layer can focus on being a layer (calculating position, managing particles, etc.), while particles can focus on how an individual particle renders (textures, colors etc.).

\$\endgroup\$
1
  • \$\begingroup\$ Great answer!! Thank you so much for all those valuable details. \$\endgroup\$
    – Asperger
    Mar 22, 2016 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.