How to create realistic snow using CBEffects

Hi, Caleb.

I’ve been messing around with CBEffects trying to create a realistic snow effect to no effect. I found this nice Javascript example of what I’d like, but it uses cosine and sine functions for particle movement. I was wondering if you could help me build something like this using CBEffects.

http://thecodeplayer.com/walkthrough/html5-canvas-snow-effect

Thanks.

I’m not sure about the whole CBEffects thing because iv’e never used it but you can try this.

I think if you do a little bit of touch up and polish this will look perfect!

You can put this in a main.lua and play it. It’s a sample.

centerX = display.contentCenterX centerY = display.contentCenterY actualW = display.actualContentWidth actualH = display.actualContentHeight local physics = require( "physics" ) physics.start() local snow = {} local sCounter = 1 local sTimer local BG = display.newRect( centerX, centerY, actualW, actualH ) BG: setFillColor( 0.5, 0.6, 1 ) local function createSnow() local randomSize = math.random( 1, 3 ) local randomX = math.random( centerX - actualH/2, centerX + actualH/2 ) local randomLeftRight = math.random( -50, 50 ) local randomDown = math.random( 101, 150 ) snow[sCounter] = display.newCircle( randomX, centerY - actualH/2 - 20, randomSize ) snow[sCounter].value = sCounter physics.addBody( snow[sCounter], "dynamic" ) snow[sCounter].gravityScale = 0 snow[sCounter]:setLinearVelocity( randomLeftRight, randomDown ) snow[sCounter].alpha = 0.8 sCounter = sCounter + 1 end sTimer = timer.performWithDelay( 150, createSnow, -1 )

Good luck!

–SonicX278

Thats pretty good snow SonicX278 - how do you go about coding that, trial and error or ‘off the top’ of a very clever head :slight_smile: ?

Here’s the beauty of a particle effects system:

local vent = CBE.newVent({preset = "snow"})
  • Caleb

That was off the top of my head in 2 min. Nothing fancy. Could be better.

–SonicX278

Oh and if you don’t want physics you can easily get transition.to working.

–SonicX278

One important thing to note about @SonicX278’s approach: Your particles are never destroyed. If you run it for any reasonable amount of time, things will quickly get messy. You should add a routine in there somewhere to destroy particles or hide them to reuse them or something.

  • Caleb

I’m on my mobile phone right now but that is very easy to do. It’s one simple function. I will be able to fix that problem later on today.

–SonicX278

Aye. Here’s an improved version of @SonicX278’s code, without the unnecessary globals, with snowflakes that don’t bump into objects in the scene, and with a method that removes snowflakes as they go outside the screen. Also, I’ve removed the unneeded table in favor of local snowflakes and a group, which is cleaner and won’t fail when the number of snowflakes goes over 15 digits (admittedly rarely, but still… :D).
 

The loop through each snowflake is required because @SonicX278 used physics. Without physics, we could use a transition and remove the snowflake when it’s done, but with it, we need to know when a snowflake goes outside the screen.

local centerX = display.contentCenterX local centerY = display.contentCenterY local actualW = display.actualContentWidth local actualH = display.actualContentHeight local physics = require( "physics" ) physics.start() local sTimer local BG = display.newRect( centerX, centerY, actualW, actualH ) BG:setFillColor( 0.5, 0.6, 1 ) local snow = display.newGroup() local function checkFlakes() for i = snow.numChildren, 1, -1 do if snow[i].y - snow[i].contentHeight \> actualH then display.remove(snow[i]) end end end local function createSnowflake() local randomSize = math.random( 1, 3 ) local randomX = math.random( centerX - actualH \* 0.5, centerX + actualH \* 0.5 ) local randomLeftRight = math.random( -50, 50 ) local randomDown = math.random( 101, 150 ) local flake = display.newCircle( randomX, centerY - actualH \* 0.5 - 20, randomSize ) physics.addBody(flake, "kinematic") flake.isSensor = true -- So it doesn't collide with objects in the scene flake:setLinearVelocity( randomLeftRight, randomDown ) flake.alpha = 0.8 snow:insert(flake) end sTimer = timer.performWithDelay( 150, createSnowflake, -1 ) Runtime:addEventListener("enterFrame", checkFlakes)

[EDIT]: Sorry, @Rob2, I just realized @SonicX278 and I hijacked the thread to talk about non-CBE particles… To answer the original question, the one-liner should do the trick.

  • Caleb

Oh sorry! I just saw that I’m not in the general questions forum!

–SonicX278

I’m not sure about the whole CBEffects thing because iv’e never used it but you can try this.

I think if you do a little bit of touch up and polish this will look perfect!

You can put this in a main.lua and play it. It’s a sample.

centerX = display.contentCenterX centerY = display.contentCenterY actualW = display.actualContentWidth actualH = display.actualContentHeight local physics = require( "physics" ) physics.start() local snow = {} local sCounter = 1 local sTimer local BG = display.newRect( centerX, centerY, actualW, actualH ) BG: setFillColor( 0.5, 0.6, 1 ) local function createSnow() local randomSize = math.random( 1, 3 ) local randomX = math.random( centerX - actualH/2, centerX + actualH/2 ) local randomLeftRight = math.random( -50, 50 ) local randomDown = math.random( 101, 150 ) snow[sCounter] = display.newCircle( randomX, centerY - actualH/2 - 20, randomSize ) snow[sCounter].value = sCounter physics.addBody( snow[sCounter], "dynamic" ) snow[sCounter].gravityScale = 0 snow[sCounter]:setLinearVelocity( randomLeftRight, randomDown ) snow[sCounter].alpha = 0.8 sCounter = sCounter + 1 end sTimer = timer.performWithDelay( 150, createSnow, -1 )

Good luck!

–SonicX278

Thats pretty good snow SonicX278 - how do you go about coding that, trial and error or ‘off the top’ of a very clever head :slight_smile: ?

Here’s the beauty of a particle effects system:

local vent = CBE.newVent({preset = "snow"})
  • Caleb

That was off the top of my head in 2 min. Nothing fancy. Could be better.

–SonicX278

Oh and if you don’t want physics you can easily get transition.to working.

–SonicX278

One important thing to note about @SonicX278’s approach: Your particles are never destroyed. If you run it for any reasonable amount of time, things will quickly get messy. You should add a routine in there somewhere to destroy particles or hide them to reuse them or something.

  • Caleb

I’m on my mobile phone right now but that is very easy to do. It’s one simple function. I will be able to fix that problem later on today.

–SonicX278

Aye. Here’s an improved version of @SonicX278’s code, without the unnecessary globals, with snowflakes that don’t bump into objects in the scene, and with a method that removes snowflakes as they go outside the screen. Also, I’ve removed the unneeded table in favor of local snowflakes and a group, which is cleaner and won’t fail when the number of snowflakes goes over 15 digits (admittedly rarely, but still… :D).
 

The loop through each snowflake is required because @SonicX278 used physics. Without physics, we could use a transition and remove the snowflake when it’s done, but with it, we need to know when a snowflake goes outside the screen.

local centerX = display.contentCenterX local centerY = display.contentCenterY local actualW = display.actualContentWidth local actualH = display.actualContentHeight local physics = require( "physics" ) physics.start() local sTimer local BG = display.newRect( centerX, centerY, actualW, actualH ) BG:setFillColor( 0.5, 0.6, 1 ) local snow = display.newGroup() local function checkFlakes() for i = snow.numChildren, 1, -1 do if snow[i].y - snow[i].contentHeight \> actualH then display.remove(snow[i]) end end end local function createSnowflake() local randomSize = math.random( 1, 3 ) local randomX = math.random( centerX - actualH \* 0.5, centerX + actualH \* 0.5 ) local randomLeftRight = math.random( -50, 50 ) local randomDown = math.random( 101, 150 ) local flake = display.newCircle( randomX, centerY - actualH \* 0.5 - 20, randomSize ) physics.addBody(flake, "kinematic") flake.isSensor = true -- So it doesn't collide with objects in the scene flake:setLinearVelocity( randomLeftRight, randomDown ) flake.alpha = 0.8 snow:insert(flake) end sTimer = timer.performWithDelay( 150, createSnowflake, -1 ) Runtime:addEventListener("enterFrame", checkFlakes)

[EDIT]: Sorry, @Rob2, I just realized @SonicX278 and I hijacked the thread to talk about non-CBE particles… To answer the original question, the one-liner should do the trick.

  • Caleb

Oh sorry! I just saw that I’m not in the general questions forum!

–SonicX278