3D粒子的排列和分散

 

在这里先介绍一个十分好用的loader类—BulkLoader,这是它的API文档。它能把管理所有需要加载的文件,并支持多种加载类型,加载后可以直接从类中得到各类型的实例,十分方便。这里有官方的一个使用例子。

ContractedBlock.gif ExpandedBlockStart.gif Code
import br.com.stimuli.loading.BulkLoader;

    
/ /instantiate a BulkLoader with a name : a way to reference this instance from another classes without having to set a expolicit reference on many places
    var bulkLoader : BulkLoader 
= new BulkLoader("main loading");
    
// add items to be loaded
    bulkLoader.add("my_xml_file.xml");
    bulkLoader.add(
"main.swf");
    
// you can also use a URLRequest object
    var backgroundURL : URLRequest = new URLRequest("background.jpg");
    bulkLoader.add(backgroundURL);

    
// add event listeners for the loader itself :
    
// event fired when all items have been loaded
    bulkLoader.addEventListener(BulkLoader.COMPLETE, onCompleteHandler);
    
// event fired when loading progress has been made:
    bulkLoader.addEventListener(BulkLoader.PROGRESS, _onProgressHandler);

    
// start loading all items
    bulkLoader.start();

    function _onProgressHandler(evt : ProgressEvent) : 
void{
        trace(
"Loaded" , evt.bytesLoaded," of ",  evt.bytesTotal);
    }

    function onCompleteHandler(evt : ProgressEvent) : 
void{
            trace(
"All items are loaeded and ready to consume");
            
// grab the main movie clip:
            var mainMovie : MovieClip = bulkLoader.getMovieClip("main.swf");
            
// Get the xml object:
            var mXML : XML = bulkLoader.getXML("my_xml_file.xml");
            
// grab the bitmap for the background image by a string:
            var myBitmap : Bitmap = bulkLoader.getBitmap("background.jpg");
            
// grab the bitmap for the background image using the url rquest object:
            var myBitmap : Bitmap = bulkLoader.getBitmap(backgroundURL);
    }

    
// In any other class you can access those assets without having to pass around references to the bulkLoader instance.
    
// In another class  you get get a reference to the "main loading" bulkLoader:
    var mainLoader : BulkLoader = BulkLoader.getLoader("main loading");
    
// now grab the xml:
    var mXML : XML = mainLoader.getXML("my_xml_file.xml");
    
// or shorter:
    var mXML : XML = BulkLoader.getLoader("main loading").getXML("my_xml_file.xml");

 

回到正题,我们看看如何实现粒子的散落效果。首先我们在3D场景添加一块地板

var cm:ColorMaterial  =   new  ColorMaterial( 0x212121 1 );
floor 
=   new  Plane(cm,  1100 1100 1 1 );
floor.rotationX 
=   90 ;
floor.y 
=   - 550 ;
scene.addChild(floor);

 

然后添加粒子阵,damp属性为碰撞后质量损失的值

pixels  =   new  MotionPixels(bfx, floor);
pixels.damp 
=   0.4 ;
scene.addChild(pixels);

 

在这个粒子阵里添加粒子

            var offsetX: int   =   int (bmd.width  *  . 5   *  intervalIn  /  intervalOut);
            var offsetY:
int   =   int (bmd.height  *  . 5   *  intervalIn  /  intervalOut);
            var m:
int   =   0 , n: int   =   0 ;
            
for  (var i: int   =  bmd.height; i  >   0 ; i  -=  intervalOut)
            {
                
for  (var j: int   =   0 ; j  <  bmd.width; j  +=  intervalOut)
                {
                    var color:
uint   =  bmd.getPixel32(j, i);
                    
if  (color  >   0 ) pixels.addPixel3D( new  MotionPixel(color, n  -  offsetX, m  -  offsetY,  0 ));
                    n 
+=  intervalIn;
                }
                n 
=   0 ;
                m 
+=  intervalIn;
            }

 

我们看看这个MotionPixel类

         public  function MotionPixel(color: uint , x:Number = 0 , y:Number = 0 , z:Number = 0 )
        {
            super(color, x, y, z);
            
            weight 
=   int (Math.random()  *   35   +   5 );
            
            radomXYZ();
            
            sx 
=  x;
            sy 
=  y;
            sz 
=  z;
        }
        
        
public  function radomXYZ(): void
        {
            vx 
=   int (Math.random()  *   60   -   30 );
            vy 
=   0 ;
            vz 
=   int (Math.random()  *   60   -   30 );
        }

在构造函数里,每个粒子都拥有初始位置,初始速度和重量。设置X和Z的初始速度目的为了有“分散”的效果,总不能让粒子都落在一条直线上吧。而重量则是决定在粒子Y方向速度的因素。

 

我们看看最重要的一个类MotionPixels类。里面包括了所有粒子的分散和聚合算法。有深入了解PV3D的朋友都知道所有继承了DisplayObject3D类的子类都可以override project方法。这个方法是pv3d里面重要的渲染方法之一。我们在这里面加上两个函数,让粒子在渲染到屏幕之前进行排列。

ContractedBlock.gif ExpandedBlockStart.gif Code
if (isBreaking) startBreakUp(p);
if (isGrouping) startGroup(p);

 

我大概说一下算法的原理,由于粒子拥有初速度vx0,vy0,vz0,其中vx0,vz0我们不用改变,它们是粒子能够分散到四周的重要条件。看看vy0,初速度我为0,假设粒子和地板之间的距离为d,有这样一个公式vy -= dy * p.weight * .004,当距离越远,加速度就越大,这个不难理解。当粒子和地板发生碰撞,也就是d=0的时候,vy改变方向:vy *= -1。并且vx,vy,vz都会损失速度vx *= _damp,vy *= _damp;vz *= _damp;。直到vx=vy=vz=0,粒子停止运动。当所有粒子停止运动后,获得下一张图片的象素位置和颜色,改变现有粒子的初始位置和颜色一致。然后从现在的位置返回到初始位置组成了一个新的图案。

 

如何你有任何意见和建议,欢迎和本人交流。

 

Preview:http://niuniuzhu.cn/p/PixelsRank

转载于:https://www.cnblogs.com/niuniuzhu/archive/2008/08/25/1275578.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值