Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw multiple instances of the same primitive in PIXI.js?

I call a "primitive" an object rendered with drawCircle(), drawRect(), …

Considering that:

  1. The positions of the primitives change (with constraint (1))
  2. The objects represented by the primitives* are frequently created/destroyed

What is the fastest way to draw multiple instances of the same primitives at different locations:

  • Creating a graphics object, adding it to the container once for all, clearing it each frame, and calling multiples drawSomething() on it with different positions each frame ?
  • Creating a graphics object for each primitive each frame, calling a single drawSomething() into it, and adding it to the container at a specified position ?
  • Another solution ?

For the sake of clarity, if I have bullets simply rendered with drawCircle(), and knowing that I receive the complete state of the game each frame (that is the constraint (1)), what is the fastest way to render them all ?

(1): I do not know that at instant t bullet 1 is at position p1 and at instant t+1 bullet 1 is at position p2. But I do know that at instant t there is a bullet at position p1 and at instant t+1 there is a bullet at position p2.

like image 529
Jim Avatar asked Aug 18 '15 16:08

Jim


1 Answers

I would go with option 3: Another Solution.

It is generally better to use Bitmap Sprites when possible, since they are more optimized for the GPU. (More info here https://github.com/pixijs/pixi.js/issues/1390)

You can easily render your primitive graphics into a reusable texture.

// Render a circle to a texture
var texture = new PIXI.RenderTexture(renderer, 16, 16);
var graphics = new PIXI.Graphics();
graphics.beginFill(0x44FFFF);
graphics.drawCircle(8, 8, 8);
graphics.endFill();
texture.render(graphics);

Then create a sprite from the texture

var s = new PIXI.Sprite(texture);

Here's an example that creates multiple sprites from a single texture.

http://jsfiddle.net/gzh14bcn/

Notice how this code doesn't even require an update function to redraw each frame. You just render the stage once at the end.

So if you have multiple bullets, you can just create a Sprite for each bullet and update it's position as it moves. Once it's off screen, remove reference to it and the GC will clean it up.

If you want to optimize even further, you should consider using an Object Pool for your bullets. https://en.wikipedia.org/wiki/Object_pool_pattern

like image 112
Karmacon Avatar answered Oct 14 '22 12:10

Karmacon