Puff of smoke

Software: Away3D 4.x

Avatar
Kenney, Newbie
Posted: 05 May 2013 12:36 AM   Total Posts: 2

I’m creating a kart racing game and when the user drifts I want puffs of smoke to appear.

What I tried was just to spawn Sprite3D’s, problem is that they don’t register enterFrame events so there is no good way of removing or animating them.

Then I tried to create a particle system but I can’t figure out what is the best way to do this, so my question is as follows:

How to create a particle system that spawns a single puff of smoke when I want it to spawn?

   

Lexcuk, Newbie
Posted: 05 May 2013 02:44 PM   Total Posts: 17   [ # 1 ]

I have an example of sprite 3d smoke

//http://swf-flash.blogspot.com/2013/05/smoke-sprite3d-away3d-4.html
package 
{
 import away3d
.cameras.lenses.*; import away3d.core.base.*;
 
import away3d.core.math.*;import away3d.core.partition.*;
 
import away3d.library.assets.*;import away3d.debug.*;
 
import away3d.cameras.*;import away3d.containers.*;import away3d.entities.*;
 
import away3d.lights.*;import away3d.materials.*;import away3d.materials.lightpickers.*;
 
import away3d.materials.methods.*; import away3d.primitives.*; import away3d.textures.*;
 
import away3d.filters.*; 
 
import flash.events.*;import flash.display.*;import flash.geom.*;
 
/**
  * ...
  * @author Lexcuk
  */
 
public class Sprite3dSmoke
 {
  
public var spriteArr:Array = [];
  public var 
speedZArr:Array = [];
  public var 
speedYArr:Array = [];
  
  public var 
spriteCount:int = 0;
  public var 
length:int = 10;
  public var  
speedY:Number = 20;
  public var  
speedZ:Number = 5;
  public var 
size:Number = 100;
  public var 
color:uint;
  public var 
alpha:Number = 0.5;
  public var 
material:*;
  
  public function 
Sprite3dSmoke(objectContainer3D:ObjectContainer3D, color:uint = 0xFF0000, alpha:Number = 0.5, size:Number = 100, length:int = 10, speedY:Number = 20, speedZ:Number = 5, material:* = null ) 
  
{
   this
.color = color;
   
this.size = size;
   
this.speedY = speedY;
   
this.speedZ = speedZ;
   
this.alpha = alpha;
   
this.length = length;
   
this.material = material;
   var 
i:int;
   var 
sprite3D:Sprite3D;
   if (
material == null) {
    material 
= new TextureMaterial(new BitmapTexture(makeSmokePuffBmd()));
    
material.alphaBlending = true;
    
material.alpha = alpha;
   
}
   
for (i = 0; i < length; i++) {
    objectContainer3D
.addChild(sprite3D = new Sprite3D(material, size, size));
    
spriteArr.push(sprite3D);
    
speedZArr.push(-speedZ/2 + Math.random() * speedZ);
    
speedYArr.push(speedY/2 + Math.random() * speedY);
   
}
  }

  
public function update(pos:Vector3D):void {
   
var i:int;
   var 
s:Sprite3D;
   for (
i = 0; i < length; i++) {
    s 
= spriteArr[i];
    
s.z += speedZArr[i];
    
s.y += speedYArr[i];
    
s.x = pos.x+i / length;
   
}
   s 
= spriteArr[spriteCount];
   
speedZArr[spriteCount] = -speedZ / 2 + Math.random() * speedZ;
   
speedYArr[spriteCount] = speedY / 2 + Math.random() * speedY;
   
s.z += speedZArr[spriteCount];
   
s.y += speedYArr[spriteCount];
   
s.x = pos.x;
   
s.y = pos.y;
   
s.z = pos.z;
   
spriteCount++; if (spriteCount >= length) spriteCount = 0;
  
}

  
public function makeSmokePuffBmd():BitmapData {
   
var bitMap:BitmapData = new BitmapData(64, 64, true, 0x00000000);
   var 
i:Number;var r:uint = color >> 16;var g:uint = color >> 8 & 0xFF;
   var 
b:uint = color & 0xFF;
   for (
i = 0; i < 5000; i+=0.9) {
    
var xi:int = i % 64; var yi:int = i / 64;
    var 
a:Number = Point.distance(new Point(32, 32), new Point(xi, yi));
    if (
a < 1) a = 1; if (a > 32) a = 0;
    
a = -a / 32 * 0xFF;
    
bitMap.setPixel32(xi, yi,  a << 24 | r << 16 | g << 8 | b);
    if (
i / 64 > 64) break ;
   
}
   
return bitMap;
  
}

 }
 

} 

and you can add it’s on your container like as I do

whiteSprite3dSmoke = 
  new 
Sprite3dSmoke(container,0xFF00FF, 0.7, 100, 20, 10, 20);
  
  
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
....
 private function 
enterFrameHandler(e:Event):void {
  
var pos:Vector3D = sceneMousePosition.clone();
  
pos.y += 50;
  
whiteSprite3dSmoke.update(pos);
  
view.render();
 
} 
   

Avatar
Kenney, Newbie
Posted: 05 May 2013 04:05 PM   Total Posts: 2   [ # 2 ]

Hm, a problem I can see though is that you never remove Sprite3D’s or remove them from the array. Wouldn’t that make the game slow down after a lot of these particles have spawned?

Also, when I do spawn a lot of particles using your engine it seems to slow down the update quite a lot (because of the huge array I imagine).

Edit: Well, I just removed the Sprite3D when its scaleZ was lower than 0, also spliced it from the array. Everything seems to be working now, thanks for your help!!!

   

Lexcuk, Newbie
Posted: 05 May 2013 05:29 PM   Total Posts: 17   [ # 3 ]

In my opinion <<removed the Sprite3D when its scaleZ was lower than 0, also spliced it from the array<<, it’s not the best solution.
If you don’t need the smoke in this time you can made removeChild
I think if you don’t need smoke, you can made a something like switcher in Sprite3dSmoke.

public function update(pos:Vector3D, container:ObjectContainer3D):void {
   
var i:int;
   var 
s:Sprite3D;
   for (
i = 0; i < length; i++) {
    s 
= spriteArr[i];
    
container.addChild(s);
    
s.z += speedZArr[i];
    
s.y += speedYArr[i];
    
s.x = pos.x+i / length;
   
}
   s 
= spriteArr[spriteCount];
   
speedZArr[spriteCount] = -speedZ / 2 + Math.random() * speedZ;
   
speedYArr[spriteCount] = speedY / 2 + Math.random() * speedY;
   
s.z += speedZArr[spriteCount];
   
s.y += speedYArr[spriteCount];
   
s.x = pos.x;
   
s.y = pos.y;
   
s.z = pos.z;
   
spriteCount++; if (spriteCount >= length) spriteCount = 0;
  
}

  
public function updateAndDelete(pos:Vector3D):void {
   
var i:int;
   var 
s:Sprite3D;
   for (
i = 0; i < length; i++) {
    s 
= spriteArr[i];
    if (
s.parent == null) continue;
    
s.z += speedZArr[i];
    
s.y += speedYArr[i];
    
s.x = pos.x+i / length;
   
}
   s 
= spriteArr[spriteCount];
   if (
s.parent != null) s.parent.removeChild(s); else {
    speedZArr[spriteCount] 
= -speedZ / 2 + Math.random() * speedZ;
    
speedYArr[spriteCount] = speedY / 2 + Math.random() * speedY;
    
s.z += speedZArr[spriteCount];
    
s.y += speedYArr[spriteCount];
    
s.x = pos.x;
    
s.y = pos.y;
    
s.z = pos.z;
    
//this is
   
}
   spriteCount
++; if (spriteCount >= length) spriteCount = 0;
  
} 

and in your enterframe

private function enterFrameHandler(e:Event):void {
  
var pos:Vector3D = sceneMousePosition.clone();
  
pos.y += 50;
  if (
smokeGoneTr == false) whiteSprite3dSmoke.update(pos,container);
  if (
smokeGoneTr == true) whiteSprite3dSmoke.updateAndDelete(pos);
  
  
view.render();
 
} 
   
   

X

Away3D Forum

Member Login

Username

Password

Remember_me



X