Jump to content

Weird behavior of PIXI.particles.ParticleContainer, no children are displayed


caymanbruce
 Share

Recommended Posts

I have tried to put my sprites into a ParticleContainer but they won't show up. But if I put them into a PIXI.Container they show up. I don't understand.

Here is my code:

this.objectContainer = new PIXI.particles.ParticleContainer(6000, {scale: true, position: true, rotation: true, alpha: true});
// this.objectContainer = new Container();

// Code for building a single sprite:
const g = new Graphics();
g.beginFill(0x24D5EF);
g.lineStyle(0);
g.drawCircle(radius, radius, radius);
g.endFill();
const rt = RenderTexture.create(g.width, g.height);
this.renderer.render(g, rt);

const sprite = Sprite.from(rt);

 

I have only 600 objects to display and I define my ParticleContainer as above. It worked before when all object information are local, but now I get my object information from the server. But the sprites are still built on the client. Nothing else had changed. Why does it work in a normal Container but not in ParticleContainer anymore?

Link to comment
Share on other sites

19 minutes ago, xerver said:

Does each use that same render texture, or do you create a new one each time?

This part is used in a loop to create the particle objects. So I think it creates a new Texture each time when creating a new sprite. But this is in essential the same code I use before and no problem for ParticleContainer. I have two copies of my code to compare the difference because I am afraid I might break something after my code changes but there is nothing special for the new one. Only this time the radius is from the server not from client. But the radius are different for each particle object.

const g = new Graphics();
g.beginFill(0x24D5EF);
g.lineStyle(0);
g.drawCircle(radius, radius, radius);
g.endFill();
const rt = RenderTexture.create(g.width, g.height);
this.renderer.render(g, rt);

const sprite = Sprite.from(rt);

 

Link to comment
Share on other sites

15 hours ago, xerver said:

All Sprites in a ParticleContainer must share a BaseTexture

Got it. If I want the sprites to have different radius and different colors can I still use ParticlesContainer? When I create a renderTexture I always need to specify its width and height first. I think once I have created it the size is fixed?  

EDIT: I have pulled the code building a Texture out and make sure every particle is using the same texture. But using the ParticleContainer still won't show anything to the screen.

And I look into the source code of ParticlesContainer. In its renderWebGL method it does use the same baseTexture which is child[0]'s baseTexture, but its renderCanvas method use loop the loop through all the children and draw them using their own baseTexture:

const resolution = child._texture.baseTexture.resolution;
context.drawImage(
  child._texture.baseTexture.source,
  frame.x * resolution,
  frame.y * resolution,
  frame.width * resolution,
  frame.height * resolution,
  positionX * resolution,
  positionY * resolution,
  finalWidth * resolution,
  finalHeight * resolution
);           

The above code draws the child using its own baseTexture, does that mean every child can have its own baseTexture if I render the particleContainer using renderCanvas?  If in canvas Container's performance for rendering thousands of sprites is not that different with ParticleContainer I will just use Container. But I am also curious about what is the true difference under the hood.

Link to comment
Share on other sites

In canvas, there is very little difference between ParticleContainer and Container. The real benefit of ParticleContainer is that on webgl we can push transform updates to the GPU, at the cost of losing some feature support.

Unless you are experiencing a real performance issue with using Container, I wouldn't worry about using ParticleContainer. ParticleContainer becomes useful when showing hundreds of thousands of particle sprites in WebGL.

Link to comment
Share on other sites

  • 1 month later...

I have the same problem, except my canvas setup is as per Pixi 4.3.4.

I have added comments where my issue consistently occurs. 

Help would be much appreciated as I've spent days on changing this with no luck...

/************************************

PIXI APP setup as per documentation
here.


...


// LOADER SIGNALS
loader.onComplete.add(onAssetsLoaded);
loader.onProgress.add(onProgress);
loader.onError.add(onError);
loader.add('{{tokens.workingDir}}/images/sprite-sheet.json');
loader.load(onLoad);

************************************/


	function onLoad(loader, resources)
	{
		px_textures = resources['{{tokens.workingDir}}/images/sprite-sheet.json'].textures;

		// BACKGROUND
		world.loadingObj = "Background";
		var bgTile = new PIXI.extras.TilingSprite(px_textures.background_repeat_2, worldWidth, worldHeight);
		app.stage.addChild(bgTile);

		/******************
		 *  GRAPHICS 
		 ************************/
			var gfx = new PIXI.Graphics();

			// Mini Map
			world.loadingObj = "Mini Map";
			gameConfig.mapDivSize = parseInt(worldWidth/gameConfig.mapSize);
			gfx.beginFill("0x000000", 0.5);
			gfx.drawRect(0, 0, gameConfig.mapSize, gameConfig.mapSize);
			px_map = new PIXI.Sprite(gfx.generateCanvasTexture());
			px_map.pivot.set(-clientViewPort.halfWidth + gameConfig.mapSize + 20, -clientViewPort.halfHeight + gameConfig.mapSize + 20);
			app.stage.addChild(px_map);
			gfx.clear();

			// Block Cooldown
			world.loadingObj = "Block Cooldown";
			var circleSize = 200;
			gfx.beginFill("0x000000", 0.4);
			gfx.drawCircle(circleSize, circleSize, circleSize);
			px_blockCooldown = new PIXI.Sprite(gfx.generateCanvasTexture());
			gfx.clear();

			// Block Cooldown White Ring
			world.loadingObj = "Cooldown White Ring";
			var circleSize = 200;
			gfx.lineStyle(4, "0xFFFFFF", 0.4);
			gfx.lineWidth = 8;
			gfx.drawCircle(circleSize, circleSize, circleSize);
			px_blockCooldownRing = new PIXI.Sprite(gfx.generateCanvasTexture());
			gfx.clear();

			// Levelup White Ring
			world.loadingObj = "Levelup Ring";
			var circleSize = 100;
			gfx.lineStyle(4, "0xFFFFFF", 1);
			gfx.lineWidth = 4;
			gfx.drawCircle(circleSize, circleSize, circleSize);
			px_levelupRing = new PIXI.Sprite(gfx.generateCanvasTexture());
			gfx.clear();

			// Reach Area
			world.loadingObj = "Reach Areas";
			var lineWidth = 2;
			var lineAlpha = 0.1;
			var circleSize = 600;
			var circlePos = lineWidth*2 + circleSize;

			gfx.lineStyle(lineWidth, "0xFF0000", lineAlpha);
			gfx.drawCircle(circlePos, circlePos, circleSize);
			px_reachArea_r = new PIXI.Sprite(gfx.generateCanvasTexture());
			px_reachArea_r.renderable = false;
			px_reachArea_r.anchor.set(0.5,0.5);
			px_reachArea_r.scale.set(1,1);
			px_reachArea_r.height = px_reachArea_r.width = circleSize*2;
			gfx.clear();

			circleSize = 400;
			circlePos = lineWidth*2 + circleSize;
			gfx.lineStyle(lineWidth, "0x00FF00", lineAlpha);
			gfx.drawCircle(circlePos, circlePos, circleSize);
			px_reachArea_g = new PIXI.Sprite(gfx.generateCanvasTexture());
			px_reachArea_g.renderable = false;
			px_reachArea_g.anchor.set(0.5,0.5);
			px_reachArea_g.scale.set(1,1);
			px_reachArea_g.height = px_reachArea_g.width = circleSize*2;
			gfx.clear();

			circleSize = 300;
			circlePos = lineWidth*2 + circleSize;
			gfx.lineStyle(lineWidth, "0x0000FF", lineAlpha);
			gfx.drawCircle(circleSize, circleSize, circleSize);
			px_reachArea_b = new PIXI.Sprite(gfx.generateCanvasTexture());
			px_reachArea_b.renderable = false;
			px_reachArea_b.anchor.set(0.5,0.5);
			px_reachArea_b.scale.set(1,1);
			px_reachArea_b.height = px_reachArea_b.width = circleSize*2;
			gfx.clear();

			circleSize = 300;
			circlePos = lineWidth*2 + circleSize;
			gfx.lineStyle(lineWidth, "0x5A3094", lineAlpha);
			gfx.drawCircle(circlePos, circlePos, circleSize);
			px_reachArea_p = new PIXI.Sprite(gfx.generateCanvasTexture());
			px_reachArea_p.renderable = false;
			px_reachArea_p.anchor.set(0.5,0.5);
			px_reachArea_p.scale.set(1,1);
			px_reachArea_p.height = px_reachArea_p.width = circleSize*2;
			gfx.clear();

			// Spawn Ring
			world.loadingObj = "Teleport Ring";
			circleSize = 50;
			gfx.beginFill(colorPaletteSVG.p.toString(), 0.5);
			gfx.drawCircle(circleSize, circleSize, circleSize);
			px_spawnRing = new PIXI.Sprite(gfx.generateCanvasTexture());
			gfx.clear();

			// Blue - Speed Boost Circle
			world.loadingObj = "Speed Boost Circle";
			circleSize = 100;
			maxCircleSize = 200;
			gfx.beginFill(colorPaletteSVG.b.toString(), 0.3);
			gfx.drawCircle(circleSize, circleSize, circleSize);
			px_speedCircle = new PIXI.Sprite(gfx.generateCanvasTexture());
			gfx.clear();
			
			// MASK (clip things outside the background border)
			world.loadingObj = "World Clip Bounds";
			px_mask_outter_bounds = new PIXI.Graphics();
			px_mask_outter_bounds.drawRect(0, 0, worldWidth, worldHeight);
			app.stage.mask = px_mask_outter_bounds;
			app.stage.addChild(px_mask_outter_bounds);

		/******************
		 *  ENERGY 
		 ************************/

/****************************************

**  FAILS TO RENDER EVERY TIME

**  classColors.length = 4;
**  energyCount = 640;
**  1,2,3 works perfect
**  the 4th iteration sets everything up but simply does not render!
**  I even change the colour order and its always the 4th one which does not render
**  I have tried changing the ParticleContainers size, no love. 

****************************************/

			var i, j, color, energyCount;
			for (i=0; i<classColors.length; i++)
			{
				color = classColors[i];
				energyCount = energy[color].length;
				world.loadingObj = "Gems (" + color + ")";

				window["px_energy_" + color + "_container"] = new PIXI.particles.ParticleContainer(5000, {
					position: true,
					rotation: true
				}, 5000);
				app.stage.addChild(window["px_energy_" + color + "_container"]);

				// Push gem => particle container
				for (j=0; j<energyCount; j++) {
					window["px_energy_" + color + "_container"].addChild(createGem(energy[color][j], color));
				}
			}

		/******************
		 *  SPIKES 
		 ************************/
			// TOP
			world.loadingObj = "Spikes top";
			px_spike_top_container = new PIXI.particles.ParticleContainer(spikes.top_count +20, {
				position: true,
				rotation: true,
			});
			app.stage.addChild(px_spike_top_container);
			for (i=0; i<spikes.top_count; i++) {
				px_spike_top_container.addChild(createSpike(spikes.top[i]));
			}

			// RIGHT
			world.loadingObj = "Spikes right";
			px_spike_right_container = new PIXI.particles.ParticleContainer(spikes.right_count +20, {
				position: true,
				rotation: true,
			});
			app.stage.addChild(px_spike_right_container);
			for (i=0; i<spikes.right_count; i++) {
				px_spike_right_container.addChild(createSpike(spikes.right[i]));
			}

			// BOTTOM
			world.loadingObj = "Spikes bottom";
			px_spike_bottom_container = new PIXI.particles.ParticleContainer(spikes.bottom_count +20, {
				position: true,
				rotation: true,
			});
			app.stage.addChild(px_spike_bottom_container);
			for (i=0; i<spikes.bottom_count; i++) {
				px_spike_bottom_container.addChild(createSpike(spikes.bottom[i]));
			}

/****************************************

**  FAILS TO RENDER EVERY TIME

**  spikes.left_count = 20;
**  The above 3 ParticleContainres work perfectly
**  the 4th iteration sets everything up but simply does not render!

****************************************/
			// LEFT
			world.loadingObj = "Spikes left";
			px_spike_left_container = new PIXI.particles.ParticleContainer(spikes.left_count +20, {
				position: true,
				rotation: true,
			});
			app.stage.addChild(px_spike_left_container);
			for (i=0; i<spikes.left_count; i++) {
				px_spike_left_container.addChild(createSpike(spikes.left[i]));
			}
		
		/******************
		 *  OTHER SPRITES
		 ************************/
			// Chain
			world.loadingObj = "Chain";
			px_chain = new PIXI.Sprite(px_textures["chain-repeat-2"]);
			px_chain.anchor.set(0.5,0.5);
			px_chain.cacheAsBitmap = true;
			px_chain.renderable = false;

			// Skulls
			world.loadingObj = "Skulls";
			px_skull = new PIXI.Sprite(px_textures["skull"]);
			px_skull.cacheAsBitmap = true;
			px_skull.renderable = false;

		/******************
		 *  APP STAGE FINAL TOUCHES
		 ************************/
			app.setPosition();
			app.renderer.resize(window.innerWidth, window.innerHeight);
	}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...