Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Question about particles system — Gideros Forum

Question about particles system

EscEsc Member
edited December 2014 in Game & application design
Hello all,
after lurking for a while, here it goes a question...
I'm using @GregBug particles system and it works just fine when I show a single emitter, but I don't know how to use it in a game where many emitters are working at the same time, ie: in a game where you shoot enemies and many explosions are displayed on screen at the same time. I've tried to create an array with as many emitters I think will be on screen at the same time, and before doing an emitter:setPosition(x,y) and emitter:start() I go through the array and check if not arrayfx[n]:started() but it doesn't work very well. Am I approaching this in the wrong way ?

Comments

  • seppseppseppsepp Member
    Accepted Answer
    but it doesn't work very well
    Don't get me wrong - I don't want to appear unfriendly - , but what exactly does this ^^ statement mean ;) ?
  • Another approach could be to assign one or more emitters to your enemy class, and start them only on certain conditions (ie. enemy.hit = true, or enemy.hp<1)

    :)
  • Ok, so I've tried @pie approach and it's working.
    I was having the problem of assigning the emitter to self. It should be to stage instead.
    In the ball class, the line : self.emitter = CEmitter.new(0,0,0,stage)
     
    menu = Core.class(Sprite)
     
    wi = application:getContentWidth()
    he = application:getContentHeight()
     
    function menu:init()
    	application:setBackgroundColor(0x000000)
    	ball_list = {}
    	for i=1,5 do
    		local b = ball.new()
    		ball_list[i] = b	
    		self:addChild(ball_list[i])
    	end	
    	self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
    end
     
     
    function menu:onEnterFrame()
     
    	for i=1,#ball_list do
    		ball_list[i]:update()		
     
    	end
    end	
     
    -------------------------------------------------------
     
    ball = Core.class(Sprite)
     
    function ball:init()
    	ballbmp = Bitmap.new(Texture.new("ball3.png",true))
    	ballbmp:setAnchorPoint(.5,.5)
     
    	self:addChild(ballbmp)
     
    	self.posX = wi/2
    	self.posY = he/2
    	self.speedX = math.random(-5,5)
    	self.speedY = math.random(-5,5)
    	self.hitR,self.hitL,self.hitU,self.hitD = false,false,false,false
     
    	local sparklesGFX = Texture.new("ball3.png")
    	sparkles = CParticles.new(sparklesGFX, 10, .2, 0, "add")
    	sparkles:setSize(0.5, 1)
    	sparkles:setDirection(0,360)
    	sparkles:setSpeed(140, 255)
    	sparkles:setAlpha(255)
    	sparkles:setAlphaMorphIn(255, 0.1)
    	sparkles:setAlphaMorphOut(0, 0.2)
     
    	sparkles:setColor(50,50,50, 255, 255, 255)
    	sparkles:setLoopMode(1)
     
    	self.emitter = CEmitter.new(0,0,0,stage)
    	self.emitter:assignParticles(sparkles)
     
    end
     
     
    function ball:update()
    	self:setPosition(self.posX,self.posY)
    	self.posX = self.posX + self.speedX
    	self.posY = self.posY + self.speedY
     
     
    	if self.posY < self:getWidth()/2 then
    		self.hitU = true
    		--self.posY = self:getWidth()/2
    		self.speedY = self.speedY * -1
    	end
    	if self.posX < self:getWidth()/2 then
    		self.hitL = true
    		--self.posX = 0
    		self.speedX = self.speedX * -1
    	end	
    	if self.posX > wi-self:getWidth()/2 then
    		self.hitR = true
    		--self.posX = wi
    		self.speedX = self.speedX * -1
    	end
    	if self.posY > he-self:getWidth()/2 then
    		self.hitD = true
    		--self.posY = he
    		self.speedY = self.speedY * -1
    	end
     
    	if self.hitU then		
    			--print("I")
    			self.emitter:setPosition(self.posX, self.posY - self:getWidth()/2)
    			self.emitter:start()			
    			self.hitU = false
    	end
    	if self.hitL then		
    			--print("I")
    			self.emitter:setPosition(self.posX - self:getWidth()/2, self.posY )
    			self.emitter:start()			
    			self.hitL = false
    	end
    	if self.hitR then					
    			self.emitter:setPosition(self.posX + self:getWidth()/2, self.posY )
    			self.emitter:start()			
    			self.hitR = false
    	end
    	if self.hitD then					
    			self.emitter:setPosition(self.posX, self.posY + self:getWidth()/2 )
    			self.emitter:start()			
    			self.hitD = false
    	end
    end
  • @Esc in my experience TNT emitters can't be local, I suppose the same applies if these are defined as properties of a "local parent" (self.emitter, in local b = ball.new() ). I can't explain you why, since I am not sure I understood it completely..

    I'm sorry I don't have time now to put a dummy project together, try this (not tested, could be worthless... :-\" ):
     
    function menu:init()
    	application:setBackgroundColor(0x000000)
    	ball_list = {}
     
    	for i=1,5 do
    		ball_list[i] = ball.new()
    		self:addChild(ball_list[i])
    	end	
    	self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
    end
     
    --and in ball.init
    --self.emitter = CEmitter.new(0,0,0,self)
     
    --maybe you should also check who is parent to menu instance
    Just to say, my emitters are created with "self" as 4th parameter :)

    P.s.
    I would try to avoid continuous onEnterFrame check: I don't know what do you have in mind, this could be right or wrong depending on your specific needs and situation:

    if you dispatch a "personalized" event to your ball for every hit it gets, you just have to update the balls who need it instead of checking them all 30 times per second. If you have many balls this could save a lot of cpu load.

    Another "easier" (and maybe "lighter") way could be to do something like:
    function menu:updateBall(ball_ID)
    	ball_list[ball_ID]:update()
    end
    hope this helps! :)
  • Thank you @pie,
    tried assigning directly ball_list[i] = ball.new() and works just fine as well. No improvements saving memory though.

    About the onEnterFrame(), in my setup the balls are moving constantly and checking for a collision with the edges of the screen... I don't understand the how to dispatch a personalized event on hit without prior checking for the hit.
  • @Esc My mistake, I focused on the emitter part and didn't look to all the remaining code. :)
Sign In or Register to comment.