axmol/samples/Lua/TestLua/Resources/luaScript/ParticleTest/ParticleTest.lua

1522 lines
43 KiB
Lua

local SceneIdx = -1
local MAX_LAYER = 42
local emitter = nil
local background = nil
local labelAtlas = nil
local titleLabel = nil
local subtitleLabel = nil
local baseLayer_entry = nil
local s = CCDirector:sharedDirector():getWinSize()
local function backAction()
SceneIdx = SceneIdx - 1
if SceneIdx < 0 then
SceneIdx = SceneIdx + MAX_LAYER
end
return CreateParticleLayer()
end
local function restartAction()
return CreateParticleLayer()
end
local function nextAction()
SceneIdx = SceneIdx + 1
SceneIdx = math.mod(SceneIdx, MAX_LAYER)
return CreateParticleLayer()
end
local function backCallback(sender)
local scene = CCScene:create()
scene:addChild(backAction())
scene:addChild(CreateBackMenuItem())
CCDirector:sharedDirector():replaceScene(scene)
end
local function restartCallback(sender)
local scene = CCScene:create()
scene:addChild(restartAction())
scene:addChild(CreateBackMenuItem())
CCDirector:sharedDirector():replaceScene(scene)
end
local function nextCallback(sender)
local scene = CCScene:create()
scene:addChild(nextAction())
scene:addChild(CreateBackMenuItem())
CCDirector:sharedDirector():replaceScene(scene)
end
local function toggleCallback(sender)
if emitter ~= nil then
if emitter:getPositionType() == kCCPositionTypeGrouped then
emitter:setPositionType(kCCPositionTypeFree)
elseif emitter:getPositionType() == kCCPositionTypeFree then
emitter:setPositionType(kCCPositionTypeRelative)
elseif emitter:getPositionType() == kCCPositionTypeRelative then
emitter:setPositionType(kCCPositionTypeGrouped)
end
end
end
local function setEmitterPosition()
if emitter ~= nil then
nodeEmitter = tolua.cast(emitter, "CCNode")
nodeEmitter:setPosition(s.width / 2, s.height / 2)
end
end
local function update(dt)
if emitter ~= nil then
local str = "" .. emitter:getParticleCount()
labelAtlas:setString("" .. str)
end
end
local function baseLayer_onEnterOrExit(tag)
local scheduler = CCDirector:sharedDirector():getScheduler()
if tag == 0 then
baseLayer_entry = scheduler:scheduleScriptFunc(update, 0, false)
elseif tag == 1 then
scheduler:unscheduleScriptEntry(baseLayer_entry)
end
end
local function getBaseLayer()
local layer = CCLayerColor:create(ccc4(127,127,127,255))
emitter = nil
titleLabel = CCLabelTTF:create("", "Arial", 28)
layer:addChild(titleLabel, 100, 1000)
titleLabel:setPosition(s.width / 2, s.height - 50)
subtitleLabel = CCLabelTTF:create("", "Arial", 16)
layer:addChild(subtitleLabel, 100)
subtitleLabel:setPosition(s.width / 2, s.height - 80)
local item1 = CCMenuItemImage:create(s_pPathB1, s_pPathB2)
local item2 = CCMenuItemImage:create(s_pPathR1, s_pPathR2)
local item3 = CCMenuItemImage:create(s_pPathF1, s_pPathF2)
local item4 = CCMenuItemToggle:create(CCMenuItemFont:create("Free Movement"))
item4:addSubItem(CCMenuItemFont:create("Relative Movement"))
item4:addSubItem(CCMenuItemFont:create("Grouped Movement"))
item1:registerScriptTapHandler(backCallback)
item2:registerScriptTapHandler(restartCallback)
item3:registerScriptTapHandler(nextCallback)
item4:registerScriptTapHandler(toggleCallback)
local menu = CCMenu:create()
menu:addChild(item1)
menu:addChild(item2)
menu:addChild(item3)
menu:addChild(item4)
menu:setPosition(CCPointMake(0, 0))
item1:setPosition(CCPointMake(s.width/2 - item2:getContentSize().width * 2, item2:getContentSize().height / 2))
item2:setPosition(CCPointMake(s.width/2, item2:getContentSize().height / 2))
item3:setPosition(CCPointMake(s.width/2 + item2:getContentSize().width * 2, item2:getContentSize().height / 2))
item4:setPosition(ccp(0, 100))
item4:setAnchorPoint(ccp(0, 0))
layer:addChild(menu, 100)
labelAtlas = CCLabelAtlas:create("0000", "fps_images.png", 12, 32, string.byte('.'))
layer:addChild(labelAtlas, 100)
labelAtlas:setPosition(ccp(s.width - 66, 50))
-- moving background
background = CCSprite:create(s_back3)
layer:addChild(background, 5)
background:setPosition(ccp(s.width / 2, s.height - 180))
local move = CCMoveBy:create(4, ccp(300, 0))
local move_back = move:reverse()
local seq = CCSequence:createWithTwoActions(move, move_back)
background:runAction(CCRepeatForever:create(seq))
local function onTouchEnded(x, y)
local pos = CCPointMake(0, 0)
if background ~= nil then
pos = background:convertToWorldSpace(CCPointMake(0, 0))
end
if emitter ~= nil then
local newPos = ccpSub(CCPointMake(x, y), pos)
emitter:setPosition(newPos.x, newPos.y)
end
end
local function onTouch(eventType, x, y)
if eventType == CCTOUCHBEGAN then
return true
else
return onTouchEnded(x, y)
end
end
layer:setTouchEnabled(true)
layer:registerScriptTouchHandler(onTouch)
layer:registerScriptHandler(baseLayer_onEnterOrExit)
return layer
end
---------------------------------
-- ParticleReorder
---------------------------------
local ParticleReorder_Order = nil
local ParticleReorder_entry = nil
local ParticleReorder_layer = nil
local function reorderParticles(dt)
update(dt)
for i = 0, 1 do
local parent = ParticleReorder_layer:getChildByTag(1000 + i)
local child1 = parent:getChildByTag(1)
local child2 = parent:getChildByTag(2)
local child3 = parent:getChildByTag(3)
if math.mod(ParticleReorder_Order, 3) == 0 then
parent:reorderChild(child1, 1)
parent:reorderChild(child2, 2)
parent:reorderChild(child3, 3)
elseif math.mod(ParticleReorder_Order, 3) == 1 then
parent:reorderChild(child1, 3)
parent:reorderChild(child2, 1)
parent:reorderChild(child3, 2)
elseif math.mod(ParticleReorder_Order, 3) == 2 then
parent:reorderChild(child1, 2)
parent:reorderChild(child2, 3)
parent:reorderChild(child3, 1)
end
end
ParticleReorder_Order = ParticleReorder_Order + 1
end
local function ParticleReorder_onEnterOrExit(tag)
local scheduler = CCDirector:sharedDirector():getScheduler()
if tag == 0 then
ParticleReorder_entry = scheduler:scheduleScriptFunc(reorderParticles, 1.0, false)
elseif tag == 1 then
scheduler:unscheduleScriptEntry(ParticleReorder_entry)
end
end
local function ParticleReorder()
ParticleReorder_layer = getBaseLayer()
ParticleReorder_Order = 0
ParticleReorder_layer:setColor(ccc3(0, 0, 0))
ParticleReorder_layer:removeChild(background, true)
background = nil
local ignore = CCParticleSystemQuad:create("Particles/SmallSun.plist")
local parent1 = CCNode:create()
local parent2 = CCParticleBatchNode:createWithTexture(ignore:getTexture())
ignore:unscheduleUpdate()
for i = 0, 1 do
local parent = nil
if i == 0 then
parent = parent1
else
parent = parent2
end
local emitter1 = CCParticleSystemQuad:create("Particles/SmallSun.plist")
emitter1:setStartColor(ccc4f(1,0,0,1))
emitter1:setBlendAdditive(false)
local emitter2 = CCParticleSystemQuad:create("Particles/SmallSun.plist")
emitter2:setStartColor(ccc4f(0,1,0,1))
emitter2:setBlendAdditive(false)
local emitter3 = CCParticleSystemQuad:create("Particles/SmallSun.plist")
emitter3:setStartColor(ccc4f(0,0,1,1))
emitter3:setBlendAdditive(false)
local neg = nil
if i == 0 then
neg = 1
else
neg = -1
end
emitter1:setPosition(ccp( s.width / 2 - 30, s.height / 2 + 60 * neg))
emitter2:setPosition(ccp( s.width / 2, s.height / 2 + 60 * neg))
emitter3:setPosition(ccp( s.width / 2 + 30, s.height / 2 + 60 * neg))
parent:addChild(emitter1, 0, 1)
parent:addChild(emitter2, 0, 2)
parent:addChild(emitter3, 0, 3)
ParticleReorder_layer:addChild(parent, 10, 1000 + i)
end
ParticleReorder_layer:registerScriptHandler(ParticleReorder_onEnterOrExit)
titleLabel:setString("Reordering particles")
subtitleLabel:setString("Reordering particles with and without batches batches")
return ParticleReorder_layer
end
---------------------------------
-- ParticleBatchHybrid
---------------------------------
local ParticleBatchHybrid_entry = nil
local ParticleBatchHybrid_parent1 = nil
local ParticleBatchHybrid_parent2 = nil
local function switchRender(dt)
update(dt)
local cond = (emitter:getBatchNode() ~= nil)
emitter:removeFromParentAndCleanup(false)
local str = "Particle: Using new parent: "
local newParent = nil
if cond == true then
newParent = ParticleBatchHybrid_parent2
str = str .. "CCNode"
else
newParent = ParticleBatchHybrid_parent1
str = str .. "CCParticleBatchNode"
end
newParent:addChild(emitter)
cclog(str)
end
local function ParticleBatchHybrid_onEnterOrExit(tag)
local scheduler = CCDirector:sharedDirector():getScheduler()
if tag == 0 then
ParticleBatchHybrid_entry = scheduler:scheduleScriptFunc(switchRender, 2.0, false)
elseif tag == 1 then
scheduler:unscheduleScriptEntry(ParticleBatchHybrid_entry)
--emitter:release()
end
end
local function ParticleBatchHybrid()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
emitter = CCParticleSystemQuad:create("Particles/LavaFlow.plist")
---- emitter:retain()
local batch = CCParticleBatchNode:createWithTexture(emitter:getTexture())
batch:addChild(emitter)
layer:addChild(batch, 10)
local node = CCNode:create()
layer:addChild(node)
ParticleBatchHybrid_parent1 = batch
ParticleBatchHybrid_parent2 = node
layer:registerScriptHandler(ParticleBatchHybrid_onEnterOrExit)
titleLabel:setString("Paticle Batch")
subtitleLabel:setString("Hybrid: batched and non batched every 2 seconds")
return layer
end
---------------------------------
-- ParticleBatchMultipleEmitters
---------------------------------
local function ParticleBatchMultipleEmitters()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
local emitter1 = CCParticleSystemQuad:create("Particles/LavaFlow.plist")
emitter1:setStartColor(ccc4f(1,0,0,1))
local emitter2 = CCParticleSystemQuad:create("Particles/LavaFlow.plist")
emitter2:setStartColor(ccc4f(0,1,0,1))
local emitter3 = CCParticleSystemQuad:create("Particles/LavaFlow.plist")
emitter3:setStartColor(ccc4f(0,0,1,1))
emitter1:setPosition(ccp(s.width / 1.25, s.height / 1.25))
emitter2:setPosition(ccp(s.width / 2, s.height / 2))
emitter3:setPosition(ccp(s.width / 4, s.height / 4))
local batch = CCParticleBatchNode:createWithTexture(emitter1:getTexture())
batch:addChild(emitter1, 0)
batch:addChild(emitter2, 0)
batch:addChild(emitter3, 0)
layer:addChild(batch, 10)
titleLabel:setString("Paticle Batch")
subtitleLabel:setString("Multiple emitters. One Batch")
return layer
end
---------------------------------
-- DemoFlower
---------------------------------
local function DemoFlower()
local layer = getBaseLayer()
emitter = CCParticleFlower:create()
-- emitter:retain()
background:addChild(tolua.cast(emitter, "CCNode"), 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_stars1))
setEmitterPosition()
titleLabel:setString("ParticleFlower")
return layer
end
---------------------------------
-- DemoGalaxy
---------------------------------
local function DemoGalaxy()
local layer = getBaseLayer()
emitter = CCParticleGalaxy:create()
-- emitter:retain()
background:addChild(tolua.cast(emitter,"CCNode"), 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
setEmitterPosition()
titleLabel:setString("ParticleGalaxy")
return layer
end
---------------------------------
-- DemoFirework
---------------------------------
local function DemoFirework()
local layer = getBaseLayer()
emitter = CCParticleFireworks:create()
-- emitter:retain()
background:addChild(tolua.cast(emitter,"CCNode"), 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_stars1))
setEmitterPosition()
titleLabel:setString("ParticleFireworks")
return layer
end
---------------------------------
-- DemoSpiral
---------------------------------
local function DemoSpiral()
local layer = getBaseLayer()
emitter = CCParticleSpiral:create()
-- emitter:retain()
background:addChild(tolua.cast(emitter,"CCNode"), 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
setEmitterPosition()
titleLabel:setString("ParticleSpiral")
return layer
end
---------------------------------
-- DemoSun
---------------------------------
local function DemoSun()
local layer = getBaseLayer()
emitter = CCParticleSun:create()
-- emitter:retain()
background:addChild(tolua.cast(emitter,"CCNode"), 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
setEmitterPosition()
titleLabel:setString("ParticleSun")
return layer
end
---------------------------------
-- DemoMeteor
---------------------------------
local function DemoMeteor()
local layer = getBaseLayer()
emitter = CCParticleMeteor:create()
-- emitter:retain()
background:addChild(tolua.cast(emitter,"CCNode"), 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
setEmitterPosition()
titleLabel:setString("ParticleMeteor")
return layer
end
---------------------------------
-- DemoFire
---------------------------------
local function DemoFire()
local layer = getBaseLayer()
emitter = CCParticleFire:create()
-- emitter:retain()
background:addChild(tolua.cast(emitter,"CCNode"), 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
local pos_x, pos_y = tolua.cast(emitter,"CCNode"):getPosition()
tolua.cast(emitter,"CCNode"):setPosition(pos_x, 100)
titleLabel:setString("ParticleFire")
return layer
end
---------------------------------
-- DemoSmoke
---------------------------------
local function DemoSmoke()
local layer = getBaseLayer()
emitter = CCParticleSmoke:create()
-- emitter:retain()
background:addChild(tolua.cast(emitter,"CCNode"), 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
local pos_x, pos_y = tolua.cast(emitter,"CCNode"):getPosition()
tolua.cast(emitter,"CCNode"):setPosition(pos_x, 100)
setEmitterPosition()
titleLabel:setString("ParticleSmoke")
return layer
end
---------------------------------
-- DemoExplosion
---------------------------------
local function DemoExplosion()
local layer = getBaseLayer()
emitter = CCParticleExplosion:create()
-- emitter:retain()
background:addChild(tolua.cast(emitter,"CCNode"), 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_stars1))
tolua.cast(emitter, "CCParticleSystem"):setAutoRemoveOnFinish(true)
setEmitterPosition()
titleLabel:setString("ParticleExplosion")
return layer
end
---------------------------------
-- DemoSnow
---------------------------------
local function DemoSnow()
local layer = getBaseLayer()
emitter = CCParticleSnow:create()
-- emitter:retain()
local nodeEmitter = tolua.cast(emitter, "CCNode")
background:addChild(nodeEmitter, 10)
local pos_x, pos_y = nodeEmitter:getPosition()
nodeEmitter:setPosition(pos_x, pos_y - 110)
local systemEmitter = tolua.cast(emitter, "CCParticleSystem")
systemEmitter:setLife(3)
systemEmitter:setLifeVar(1)
-- gravity
systemEmitter:setGravity(CCPointMake(0, -10))
-- speed of particles
systemEmitter:setSpeed(130)
systemEmitter:setSpeedVar(30)
local startColor = systemEmitter:getStartColor()
startColor.r = 0.9
startColor.g = 0.9
startColor.b = 0.9
systemEmitter:setStartColor(startColor)
local startColorVar = systemEmitter:getStartColorVar()
startColorVar.b = 0.1
systemEmitter:setStartColorVar(startColorVar)
systemEmitter:setEmissionRate(systemEmitter:getTotalParticles() / systemEmitter:getLife())
systemEmitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_snow))
setEmitterPosition()
titleLabel:setString("ParticleSnow")
return layer
end
---------------------------------
-- DemoRain
---------------------------------
local function DemoRain()
local layer = getBaseLayer()
emitter = CCParticleRain:create()
-- emitter:retain()
local nodeEmitter = tolua.cast(emitter, "CCNode")
background:addChild(nodeEmitter, 10)
local pos_x, pos_y = nodeEmitter:getPosition()
nodeEmitter:setPosition(pos_x, pos_y - 100)
tolua.cast(emitter, "CCParticleSystem"):setLife(4)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
setEmitterPosition()
titleLabel:setString("ParticleRain")
return layer
end
---------------------------------
-- DemoBigFlower
---------------------------------
local function DemoBigFlower()
local layer = getBaseLayer()
emitter = CCParticleSystemQuad:new()
emitter:initWithTotalParticles(50)
emitter:autorelease()
background:addChild(emitter, 10)
----emitter:release() -- win32 : use this line or remove this line and use autorelease()
emitter:setTexture( CCTextureCache:sharedTextureCache():addImage(s_stars1) )
emitter:setDuration(-1)
-- gravity
emitter:setGravity(CCPointMake(0, 0))
-- angle
emitter:setAngle(90)
emitter:setAngleVar(360)
-- speed of particles
emitter:setSpeed(160)
emitter:setSpeedVar(20)
-- radial
emitter:setRadialAccel(-120)
emitter:setRadialAccelVar(0)
-- tagential
emitter:setTangentialAccel(30)
emitter:setTangentialAccelVar(0)
-- emitter position
emitter:setPosition(160, 240)
emitter:setPosVar(ccp(0, 0))
-- life of particles
emitter:setLife(4)
emitter:setLifeVar(1)
-- spin of particles
emitter:setStartSpin(0)
emitter:setStartSizeVar(0)
emitter:setEndSpin(0)
emitter:setEndSpinVar(0)
-- color of particles
emitter:setStartColor(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setStartColorVar(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setEndColor(ccc4f(0.1, 0.1, 0.1, 0.2))
emitter:setEndColorVar(ccc4f(0.1, 0.1, 0.1, 0.2))
-- size, in pixels
emitter:setStartSize(80.0)
emitter:setStartSizeVar(40.0)
emitter:setEndSize(kParticleStartSizeEqualToEndSize)
-- emits per second
emitter:setEmissionRate(emitter:getTotalParticles() / emitter:getLife())
-- additive
emitter:setBlendAdditive(true)
setEmitterPosition()
titleLabel:setString("ParticleBigFlower")
return layer
end
---------------------------------
-- DemoRotFlower
---------------------------------
local function DemoRotFlower()
local layer = getBaseLayer()
emitter = CCParticleSystemQuad:new()
emitter:initWithTotalParticles(300)
emitter:autorelease()
background:addChild(emitter, 10)
----emitter:release() -- win32 : Remove this line
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_stars2))
-- duration
emitter:setDuration(-1)
-- gravity
emitter:setGravity(ccp(0, 0))
-- angle
emitter:setAngle(90)
emitter:setAngleVar(360)
-- speed of particles
emitter:setSpeed(160)
emitter:setSpeedVar(20)
-- radial
emitter:setRadialAccel(-120)
emitter:setRadialAccelVar(0)
-- tagential
emitter:setTangentialAccel(30)
emitter:setTangentialAccelVar(0)
-- emitter position
emitter:setPosition(160, 240)
emitter:setPosVar(ccp(0, 0))
-- life of particles
emitter:setLife(3)
emitter:setLifeVar(1)
-- spin of particles
emitter:setStartSpin(0)
emitter:setStartSpinVar(0)
emitter:setEndSpin(0)
emitter:setEndSpinVar(2000)
-- color of particles
emitter:setStartColor(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setStartColorVar(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setEndColor(ccc4f(0.1, 0.1, 0.1, 0.2))
emitter:setEndColorVar(ccc4f(0.1, 0.1, 0.1, 0.2))
-- size, in pixels
emitter:setStartSize(30.0)
emitter:setStartSizeVar(0)
emitter:setEndSize(kParticleStartSizeEqualToEndSize)
-- emits per second
emitter:setEmissionRate(emitter:getTotalParticles() / emitter:getLife())
-- additive
emitter:setBlendAdditive(false)
setEmitterPosition()
titleLabel:setString("ParticleRotFlower")
return layer
end
---------------------------------
-- DemoModernArt
---------------------------------
local function DemoModernArt()
local layer = getBaseLayer()
emitter = CCParticleSystemQuad:new()
emitter:initWithTotalParticles(1000)
emitter:autorelease()
background:addChild(emitter, 10)
----emitter:release()
-- duration
emitter:setDuration(-1)
-- gravity
emitter:setGravity(CCPointMake(0,0))
-- angle
emitter:setAngle(0)
emitter:setAngleVar(360)
-- radial
emitter:setRadialAccel(70)
emitter:setRadialAccelVar(10)
-- tagential
emitter:setTangentialAccel(80)
emitter:setTangentialAccelVar(0)
-- speed of particles
emitter:setSpeed(50)
emitter:setSpeedVar(10)
-- emitter position
emitter:setPosition(s.width / 2, s.height / 2)
emitter:setPosVar(ccp(0, 0))
-- life of particles
emitter:setLife(2.0)
emitter:setLifeVar(0.3)
-- emits per frame
emitter:setEmissionRate(emitter:getTotalParticles() / emitter:getLife())
-- color of particles
emitter:setStartColor(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setStartColorVar(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setEndColor(ccc4f(0.1, 0.1, 0.1, 0.2))
emitter:setEndColorVar(ccc4f(0.1, 0.1, 0.1, 0.2))
-- size, in pixels
emitter:setStartSize(1.0)
emitter:setStartSizeVar(1.0)
emitter:setEndSize(32.0)
emitter:setEndSizeVar(8.0)
-- texture
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
-- additive
emitter:setBlendAdditive(false)
setEmitterPosition()
titleLabel:setString("Varying size")
return layer
end
---------------------------------
-- DemoRing
---------------------------------
local function DemoRing()
local layer = getBaseLayer()
emitter = CCParticleFlower:create()
-- emitter:retain()
local nodeEmitter = tolua.cast(emitter, "CCNode")
background:addChild(nodeEmitter, 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_stars1))
local systemEmitter = tolua.cast(emitter, "CCParticleSystem")
systemEmitter:setLifeVar(0)
systemEmitter:setLife(10)
systemEmitter:setSpeed(100)
systemEmitter:setSpeedVar(0)
systemEmitter:setEmissionRate(10000)
setEmitterPosition()
titleLabel:setString("Ring Demo")
return layer
end
---------------------------------
-- ParallaxParticle
---------------------------------
local function ParallaxParticle()
local layer = getBaseLayer()
background:getParent():removeChild(background, true)
background = nil
local p = CCParallaxNode:create()
layer:addChild(p, 5)
local p1 = CCSprite:create(s_back3)
local p2 = CCSprite:create(s_back3)
p:addChild(p1, 1, CCPointMake(0.5, 1), CCPointMake(0, 250))
p:addChild(p2, 2, CCPointMake(1.5, 1), CCPointMake(0, 50))
emitter = CCParticleFlower:create()
-- emitter:retain()
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
local nodeEmitter = tolua.cast(emitter, "CCNode")
p1:addChild(nodeEmitter, 10)
nodeEmitter:setPosition(250, 200)
local par = CCParticleSun:create()
p2:addChild(tolua.cast(par,"CCNode"), 10)
par:setTexture(CCTextureCache:sharedTextureCache():addImage(s_fire))
local move = CCMoveBy:create(4, CCPointMake(300,0))
local move_back = move:reverse()
local seq = CCSequence:createWithTwoActions(move, move_back)
p:runAction(CCRepeatForever:create(seq))
titleLabel:setString("Parallax + Particles")
return layer
end
---------------------------------
-- DemoParticleFromFile
---------------------------------
local function DemoParticleFromFile(name)
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
emitter = CCParticleSystemQuad:new()
emitter:autorelease()
local filename = "Particles/" .. name .. ".plist"
emitter:initWithFile(filename)
layer:addChild(emitter, 10)
setEmitterPosition()
titleLabel:setString(name)
return layer
end
---------------------------------
-- RadiusMode1
---------------------------------
local function RadiusMode1()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
emitter = CCParticleSystemQuad:new()
emitter:initWithTotalParticles(200)
layer:addChild(emitter, 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage("Images/stars-grayscale.png"))
-- duration
emitter:setDuration(kCCParticleDurationInfinity)
-- radius mode
emitter:setEmitterMode(kCCParticleModeRadius)
-- radius mode: start and end radius in pixels
emitter:setStartRadius(0)
emitter:setStartRadiusVar(0)
emitter:setEndRadius(160)
emitter:setEndRadiusVar(0)
-- radius mode: degrees per second
emitter:setRotatePerSecond(180)
emitter:setRotatePerSecondVar(0)
-- angle
emitter:setAngle(90)
emitter:setAngleVar(0)
-- emitter position
emitter:setPosition(s.width / 2, s.height / 2)
emitter:setPosVar(ccp(0, 0))
-- life of particles
emitter:setLife(5)
emitter:setLifeVar(0)
-- spin of particles
emitter:setStartSpin(0)
emitter:setStartSpinVar(0)
emitter:setEndSpin(0)
emitter:setEndSpinVar(0)
-- color of particles
emitter:setStartColor(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setStartColorVar(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setEndColor(ccc4f(0.1, 0.1, 0.1, 0.2))
emitter:setEndColorVar(ccc4f(0.1, 0.1, 0.1, 0.2))
-- size, in pixels
emitter:setStartSize(32)
emitter:setStartSizeVar(0)
emitter:setEndSize(kCCParticleStartSizeEqualToEndSize)
-- emits per second
emitter:setEmissionRate(emitter:getTotalParticles() / emitter:getLife())
-- additive
emitter:setBlendAdditive(false)
titleLabel:setString("Radius Mode: Spiral")
return layer
end
---------------------------------
-- RadiusMode2
---------------------------------
local function RadiusMode2()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
emitter = CCParticleSystemQuad:new()
emitter:initWithTotalParticles(200)
layer:addChild(emitter, 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage("Images/stars-grayscale.png"))
-- duration
emitter:setDuration(kCCParticleDurationInfinity)
-- radius mode
emitter:setEmitterMode(kCCParticleModeRadius)
-- radius mode: start and end radius in pixels
emitter:setStartRadius(100)
emitter:setStartRadiusVar(0)
emitter:setEndRadius(kCCParticleStartRadiusEqualToEndRadius)
emitter:setEndRadiusVar(0)
-- radius mode: degrees per second
emitter:setRotatePerSecond(45)
emitter:setRotatePerSecondVar(0)
-- angle
emitter:setAngle(90)
emitter:setAngleVar(0)
-- emitter position
emitter:setPosition(s.width / 2, s.height / 2)
emitter:setPosVar(ccp(0, 0))
-- life of particles
emitter:setLife(4)
emitter:setLifeVar(0)
-- spin of particles
emitter:setStartSpin(0)
emitter:setStartSpinVar(0)
emitter:setEndSpin(0)
emitter:setEndSpinVar(0)
-- color of particles
emitter:setStartColor(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setStartColorVar(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setEndColor(ccc4f(0.1, 0.1, 0.1, 0.2))
emitter:setEndColorVar(ccc4f(0.1, 0.1, 0.1, 0.2))
-- size, in pixels
emitter:setStartSize(32)
emitter:setStartSizeVar(0)
emitter:setEndSize(kCCParticleStartSizeEqualToEndSize)
-- emits per second
emitter:setEmissionRate(emitter:getTotalParticles() / emitter:getLife())
-- additive
emitter:setBlendAdditive(false)
titleLabel:setString("Radius Mode: Semi Circle")
return layer
end
---------------------------------
-- Issue704
---------------------------------
local function Issue704()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
emitter = CCParticleSystemQuad:new()
emitter:initWithTotalParticles(100)
layer:addChild(emitter, 10)
emitter:setTexture(CCTextureCache:sharedTextureCache():addImage("Images/fire.png"))
-- duration
emitter:setDuration(kCCParticleDurationInfinity)
-- radius mode
emitter:setEmitterMode(kCCParticleModeRadius)
-- radius mode: start and end radius in pixels
emitter:setStartRadius(50)
emitter:setStartRadiusVar(0)
emitter:setEndRadius(kCCParticleStartRadiusEqualToEndRadius)
emitter:setEndRadiusVar(0)
-- radius mode: degrees per second
emitter:setRotatePerSecond(0)
emitter:setRotatePerSecondVar(0)
-- angle
emitter:setAngle(90)
emitter:setAngleVar(0)
-- emitter position
emitter:setPosition(s.width / 2, s.height / 2)
emitter:setPosVar(ccp(0, 0))
-- life of particles
emitter:setLife(5)
emitter:setLifeVar(0)
-- spin of particles
emitter:setStartSpin(0)
emitter:setStartSpinVar(0)
emitter:setEndSpin(0)
emitter:setEndSpinVar(0)
-- color of particles
emitter:setStartColor(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setStartColorVar(ccc4f(0.5, 0.5, 0.5, 1.0))
emitter:setEndColor(ccc4f(0.1, 0.1, 0.1, 0.2))
emitter:setEndColorVar(ccc4f(0.1, 0.1, 0.1, 0.2))
-- size, in pixels
emitter:setStartSize(16)
emitter:setStartSizeVar(0)
emitter:setEndSize(kCCParticleStartSizeEqualToEndSize)
-- emits per second
emitter:setEmissionRate(emitter:getTotalParticles() / emitter:getLife())
-- additive
emitter:setBlendAdditive(false)
local rot = CCRotateBy:create(16, 360)
emitter:runAction(CCRepeatForever:create(rot))
titleLabel:setString("Issue 704. Free + Rot")
subtitleLabel:setString("Emitted particles should not rotate")
return layer
end
---------------------------------
-- Issue870
---------------------------------
local Issue870_index = nil
local Issue870_entry = nil
local function updateQuads(dt)
update(dt)
Issue870_index = math.mod(Issue870_index + 1, 4)
local rect = CCRectMake(Issue870_index * 32, 0, 32, 32)
emitter:setTextureWithRect(emitter:getTexture(), rect)
end
local function Issue870_onEnterOrExit(tag)
local scheduler = CCDirector:sharedDirector():getScheduler()
if tag == 0 then
Issue870_entry = scheduler:scheduleScriptFunc(updateQuads, 2.0, false)
elseif tag == 1 then
scheduler:unscheduleScriptEntry(Issue870_entry)
end
end
local function Issue870()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
local system = CCParticleSystemQuad:new()
system:initWithFile("Particles/SpinningPeas.plist")
system:setTextureWithRect(CCTextureCache:sharedTextureCache():addImage("Images/particles.png"), CCRectMake(0,0,32,32))
layer:addChild(system, 10)
emitter = system
Issue870_index = 0
layer:registerScriptHandler(Issue870_onEnterOrExit)
titleLabel:setString("Issue 870. SubRect")
subtitleLabel:setString("Every 2 seconds the particle should change")
return layer
end
---------------------------------
-- MultipleParticleSystems
---------------------------------
local function MultipleParticleSystems()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
CCTextureCache:sharedTextureCache():addImage("Images/particles.png")
for i = 0, 4 do
local particleSystem = CCParticleSystemQuad:create("Particles/SpinningPeas.plist")
particleSystem:setPosition(i * 50, i * 50)
particleSystem:setPositionType(kCCPositionTypeGrouped)
layer:addChild(particleSystem)
end
emitter = nil
titleLabel:setString("Multiple particle systems")
subtitleLabel:setString("v1.1 test: FPS should be lower than next test")
return layer
end
---------------------------------
-- MultipleParticleSystemsBatched
---------------------------------
local function MultipleParticleSystemsBatched()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
local batchNode = CCParticleBatchNode:createWithTexture(nil, 3000)
layer:addChild(batchNode, 1, 2)
for i = 0, 4 do
local particleSystem = CCParticleSystemQuad:create("Particles/SpinningPeas.plist")
particleSystem:setPositionType(kCCPositionTypeGrouped)
particleSystem:setPosition(i * 50, i * 50)
batchNode:setTexture(particleSystem:getTexture())
batchNode:addChild(particleSystem)
end
emitter = nil
titleLabel:setString("Multiple particle systems batched")
subtitleLabel:setString("v1.1 test: should perform better than previous test")
return layer
end
---------------------------------
-- AddAndDeleteParticleSystems
---------------------------------
local AddAndDeleteParticleSystems_entry = nil
local AddAndDeleteParticleSystems_batchNode = nil
local function removeSystem(dt)
update(dt)
local ChildrenCount = AddAndDeleteParticleSystems_batchNode:getChildren():count()
if ChildrenCount > 0 then
cclog("remove random system")
local rand = math.mod(math.random(1, 999999), ChildrenCount - 1)
AddAndDeleteParticleSystems_batchNode:removeChild(AddAndDeleteParticleSystems_batchNode:getChildren():objectAtIndex(rand), true)
--add new
local particleSystem = CCParticleSystemQuad:create("Particles/Spiral.plist")
particleSystem:setPositionType(kCCPositionTypeGrouped)
particleSystem:setTotalParticles(200)
particleSystem:setPosition(math.mod(math.random(1, 999999), 300) ,math.mod(math.random(1, 999999), 400))
cclog("add a new system")
local randZ = math.floor(math.random() * 100)
AddAndDeleteParticleSystems_batchNode:addChild(particleSystem, randZ, -1)
end
end
local function AddAndDeleteParticleSystems_onEnterOrExit(tag)
local scheduler = CCDirector:sharedDirector():getScheduler()
if tag == 0 then
AddAndDeleteParticleSystems_entry = scheduler:scheduleScriptFunc(removeSystem, 2.0, false)
elseif tag == 1 then
scheduler:unscheduleScriptEntry(AddAndDeleteParticleSystems_entry)
end
end
local function AddAndDeleteParticleSystems()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
--adds the texture inside the plist to the texture cache
AddAndDeleteParticleSystems_batchNode = CCParticleBatchNode:createWithTexture(nil, 16000)
layer:addChild(AddAndDeleteParticleSystems_batchNode, 1, 2)
for i = 0, 5 do
local particleSystem = CCParticleSystemQuad:create("Particles/Spiral.plist")
AddAndDeleteParticleSystems_batchNode:setTexture(particleSystem:getTexture())
particleSystem:setPositionType(kCCPositionTypeGrouped)
particleSystem:setTotalParticles(200)
particleSystem:setPosition(i * 15 + 100, i * 15 + 100)
local randZ = math.floor(math.random() * 100)
AddAndDeleteParticleSystems_batchNode:addChild(particleSystem, randZ, -1)
end
layer:registerScriptHandler(AddAndDeleteParticleSystems_onEnterOrExit)
emitter = nil
titleLabel:setString("Add and remove Particle System")
subtitleLabel:setString("v1.1 test: every 2 sec 1 system disappear, 1 appears")
return layer
end
---------------------------------
-- ReorderParticleSystems *
-- problem
---------------------------------
local ReorderParticleSystems_entry = nil
local ReorderParticleSystems_batchNode = nil
local function reorderSystem(dt)
update(dt)
local child = ReorderParticleSystems_batchNode:getChildren():randomObject()
-- problem: there's no getZOrder() for CCObject
-- ReorderParticleSystems_batchNode:reorderChild(child, child:getZOrder() - 1)
ReorderParticleSystems_batchNode:reorderChild(child, math.random(0, 99999))
end
local function ReorderParticleSystems_onEnterOrExit(tag)
local scheduler = CCDirector:sharedDirector():getScheduler()
if tag == 0 then
ReorderParticleSystems_entry = scheduler:scheduleScriptFunc(reorderSystem, 2.0, false)
elseif tag == 1 then
scheduler:unscheduleScriptEntry(ReorderParticleSystems_entry)
end
end
local function ReorderParticleSystems()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background ,true)
background = nil
ReorderParticleSystems_batchNode = CCParticleBatchNode:create("Images/stars-grayscale.png", 3000)
layer:addChild(ReorderParticleSystems_batchNode, 1, 2)
for i = 0, 2 do
local particleSystem = CCParticleSystemQuad:new()
particleSystem:initWithTotalParticles(200)
particleSystem:setTexture(ReorderParticleSystems_batchNode:getTexture())
-- duration
particleSystem:setDuration(kCCParticleDurationInfinity)
-- radius mode
particleSystem:setEmitterMode(kCCParticleModeRadius)
-- radius mode: 100 pixels from center
particleSystem:setStartRadius(100)
particleSystem:setStartRadiusVar(0)
particleSystem:setEndRadius(kCCParticleStartRadiusEqualToEndRadius)
particleSystem:setEndRadiusVar(0) -- not used when start == end
-- radius mode: degrees per second
-- 45 * 4 seconds of life = 180 degrees
particleSystem:setRotatePerSecond(45)
particleSystem:setRotatePerSecondVar(0)
-- angle
particleSystem:setAngle(90)
particleSystem:setAngleVar(0)
-- emitter position
particleSystem:setPosVar(ccp(0, 0))
-- life of particles
particleSystem:setLife(4)
particleSystem:setLifeVar(0)
-- spin of particles
particleSystem:setStartSpin(0)
particleSystem:setStartSpinVar(0)
particleSystem:setEndSpin(0)
particleSystem:setEndSpinVar(0)
-- color of particles
local startColor = ccColor4F:new()
startColor.r = 0
startColor.g = 0
startColor.b = 0
startColor.a = 1
if i == 0 then startColor.r = 1
elseif i == 1 then startColor.g = 1
elseif i == 2 then startColor.b = 1
end
particleSystem:setStartColor(startColor)
particleSystem:setStartColorVar(ccc4f(0, 0, 0, 0))
local endColor = startColor
particleSystem:setEndColor(endColor)
particleSystem:setEndColorVar(ccc4f(0, 0, 0, 0))
-- size, in pixels
particleSystem:setStartSize(32)
particleSystem:setStartSizeVar(0)
particleSystem:setEndSize(kCCParticleStartSizeEqualToEndSize)
-- emits per second
particleSystem:setEmissionRate(particleSystem:getTotalParticles() / particleSystem:getLife())
-- additive
particleSystem:setPosition(i * 10 + 120, 200)
ReorderParticleSystems_batchNode:addChild(particleSystem)
particleSystem:setPositionType(kCCPositionTypeFree)
particleSystem:release()
end
layer:registerScriptHandler(ReorderParticleSystems_onEnterOrExit)
emitter = nil
titleLabel:setString("reorder systems")
subtitleLabel:setString("changes every 2 seconds")
return layer
end
---------------------------------
-- PremultipliedAlphaTest
---------------------------------
local function PremultipliedAlphaTest()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 255))
layer:removeChild(background, true)
background = nil
emitter = CCParticleSystemQuad:create("Particles/BoilingFoam.plist")
local tBlendFunc = ccBlendFunc:new()
tBlendFunc.src = 1 --GL_ONE
tBlendFunc.dst = 0x0303 --GL_ONE_MINUS_SRC_ALPHA
emitter:setBlendFunc(tBlendFunc)
--assert(emitter:getOpacityModifyRGB(), "Particle texture does not have premultiplied alpha, test is useless")
emitter:setStartColor(ccc4f(1, 1, 1, 1))
emitter:setEndColor(ccc4f(1, 1, 1, 0))
emitter:setStartColorVar(ccc4f(0, 0, 0, 0))
emitter:setEndColorVar(ccc4f(0, 0, 0, 0))
layer:addChild(emitter, 10)
titleLabel:setString("premultiplied alpha")
subtitleLabel:setString("no black halo, particles should fade out")
return layer
end
---------------------------------
-- PremultipliedAlphaTest2
---------------------------------
local function PremultipliedAlphaTest2()
local layer = getBaseLayer()
layer:setColor(ccc3(0, 0, 0))
layer:removeChild(background, true)
background = nil
emitter = CCParticleSystemQuad:create("Particles/TestPremultipliedAlpha.plist")
layer:addChild(emitter ,10)
titleLabel:setString("premultiplied alpha 2")
subtitleLabel:setString("Arrows should be faded")
return layer
end
---------------------------------
-- Particle Test
---------------------------------
function CreateParticleLayer()
if SceneIdx == 0 then return ParticleReorder()
elseif SceneIdx == 1 then return ParticleBatchHybrid()
elseif SceneIdx == 2 then return ParticleBatchMultipleEmitters()
elseif SceneIdx == 3 then return DemoFlower()
elseif SceneIdx == 4 then return DemoGalaxy()
elseif SceneIdx == 5 then return DemoFirework()
elseif SceneIdx == 6 then return DemoSpiral()
elseif SceneIdx == 7 then return DemoSun()
elseif SceneIdx == 8 then return DemoMeteor()
elseif SceneIdx == 9 then return DemoFire()
elseif SceneIdx == 10 then return DemoSmoke()
elseif SceneIdx == 11 then return DemoExplosion()
elseif SceneIdx == 12 then return DemoSnow()
elseif SceneIdx == 13 then return DemoRain()
elseif SceneIdx == 14 then return DemoBigFlower()
elseif SceneIdx == 15 then return DemoRotFlower()
elseif SceneIdx == 16 then return DemoModernArt()
elseif SceneIdx == 17 then return DemoRing()
elseif SceneIdx == 18 then return ParallaxParticle()
elseif SceneIdx == 19 then return DemoParticleFromFile("BoilingFoam")
elseif SceneIdx == 20 then return DemoParticleFromFile("BurstPipe")
elseif SceneIdx == 21 then return DemoParticleFromFile("Comet")
elseif SceneIdx == 22 then return DemoParticleFromFile("debian")
elseif SceneIdx == 23 then return DemoParticleFromFile("ExplodingRing")
elseif SceneIdx == 24 then return DemoParticleFromFile("LavaFlow")
elseif SceneIdx == 25 then return DemoParticleFromFile("SpinningPeas")
elseif SceneIdx == 26 then return DemoParticleFromFile("SpookyPeas")
elseif SceneIdx == 27 then return DemoParticleFromFile("Upsidedown")
elseif SceneIdx == 28 then return DemoParticleFromFile("Flower")
elseif SceneIdx == 29 then return DemoParticleFromFile("Spiral")
elseif SceneIdx == 30 then return DemoParticleFromFile("Galaxy")
elseif SceneIdx == 31 then return DemoParticleFromFile("Phoenix")
elseif SceneIdx == 32 then return RadiusMode1()
elseif SceneIdx == 33 then return RadiusMode2()
elseif SceneIdx == 34 then return Issue704()
elseif SceneIdx == 35 then return Issue870()
--elseif SceneIdx == 36 then return Issue1201()
-- v1.1 tests
elseif SceneIdx == 36 then return MultipleParticleSystems()
elseif SceneIdx == 37 then return MultipleParticleSystemsBatched()
elseif SceneIdx == 38 then return AddAndDeleteParticleSystems()
elseif SceneIdx == 39 then return ReorderParticleSystems()
elseif SceneIdx == 40 then return PremultipliedAlphaTest()
elseif SceneIdx == 41 then return PremultipliedAlphaTest2()
end
end
function ParticleTest()
cclog("ParticleTest")
local scene = CCScene:create()
SceneIdx = -1
scene:addChild(nextAction())
scene:addChild(CreateBackMenuItem())
return scene
end