本人水平有限...平时没事闲的也就研究一下2D的东西,3D太复杂怕怕~~(╯﹏╰)b

效果图,重力值设置的比较小不够明显,但是看得出来,注意DEBUG下136帧:

 

 

进一步发散

Release版,提高了40帧-_-

 

新建一个XNA Windows项目XnaStructure3,

第一步:新加一个struct:StructParticle2D_Meteor.cs,代码如下:

代码
 最大偏移位置   
        
/// </summary>   
        public float FloatSPMaxRandomPos   
        {   
            
get { return floatSPMaxRandomPos; }   
            
set { floatSPMaxRandomPos = value; }   
        }   
        
internal float floatSPMaxRandomPos;   
        
/// <summary>   
        
/// 最小偏移位置   
        
/// </summary>   
        public float FloatSPMinRandomPos   
        {   
            
get { return floatSPMinRandomPos; }   
            
set { floatSPMinRandomPos = value; }   
        }   
        
internal float floatSPMinRandomPos;   
        
/// <summary>   
        
/// 初始位置   
        
/// </summary>   
        public Vector2[] Vector2SPStartPos   
        {   
            
get { return vector2SPStartPos; }   
            
set { vector2SPStartPos = value; }   
        }   
        
internal Vector2[] vector2SPStartPos;   
        
/// <summary>   
        
/// 随机体积   
        
/// </summary>   
        public float[] FloatSPOrigin   
        {   
            
get { return floatSPOrigin; }   
            
set { floatSPOrigin = value; }   
        }   
        
internal float[] floatSPOrigin;   
        
/// <summary>   
        
/// 随机方向   
        
/// </summary>   
        public int[] IntSPRandomRotation   
        {   
            
get { return intSPRandomRotation; }   
            
set { intSPRandomRotation = value; }   
        }   
        
internal int[] intSPRandomRotation;   
        
/// <summary>   
        
/// 随机速度   
        
/// </summary>   
        public float[] FloatSPRandomSpeed   
        {   
            
get { return floatSPRandomSpeed; }   
            
set { floatSPRandomSpeed = value; }   
        }   
        
float[] floatSPRandomSpeed;   
        
/// <summary>   
        
/// 随机位置   
        
/// </summary>   
        public Vector2[] Vector2SPRandomPos   
        {   
            
get { return vector2SPRandomPos; }   
            
set { vector2SPRandomPos = value; }   
        }   
        
internal Vector2[] vector2SPRandomPos;   
        
/// <summary>   
        
/// 惯性   
        
/// </summary>   
        public float[] FloatSPRandomInertiaX   
        {   
            
get { return floatSPRandomInertiaX; }   
            
set { floatSPRandomInertiaX = value; }   
        }   
        
internal float[] floatSPRandomInertiaX;   
  
        
internal int intBPCount;   
        
public int IntBPCount   
        {   
            
get { return intBPCount; }   
            
set { intBPCount = value; }   
        }   
  
        
internal float floatBPMaxX;   
        
public float FloatBPMaxX   
        {   
            
get { return floatBPMaxX; }   
            
set { floatBPMaxX = value; }   
        }   
  
        
internal float floatBPMinX;   
        
public float FloatBPMinX   
        {   
            
get { return floatBPMinX; }   
            
set { floatBPMinX = value; }   
        }   
  
        
internal float floatBPMaxY;   
        
public float FloatBPMaxY   
        {   
            
get { return floatBPMaxY; }   
            
set { floatBPMaxY = value; }   
        }   
  
        
internal float floatBPMinY;   
        
public float FloatBPMinY   
        {   
            
get { return floatBPMinY; }   
            
set { floatBPMinY = value; }   
        }   
  
        
internal float floatBPMoveParamX;   
        
public float FloatBPMoveParamX   
        {   
            
get { return floatBPMoveParamX; }   
            
set { floatBPMoveParamX = value; }   
        }   
  
        
internal float floatBPMoveParamY;   
        
public float FloatBPMoveParamY   
        {   
            
get { return floatBPMoveParamY; }   
            
set { floatBPMoveParamY = value; }   
        }   
  
        
internal float floatBPMinSize;   
        
public float FloatBPMinSize   
        {   
            
get { return floatBPMinSize; }   
            
set { floatBPMinSize = value; }   
        }   
  
        
internal float floatBPMaxSize;   
        
public float FloatBPMaxSize   
        {   
            
get { return floatBPMaxSize; }   
            
set { floatBPMaxSize = value; }   
        }   
  
        
internal Vector2[] vector2BPStartPos;   
        
public Vector2[] Vector2BPStartPos   
        {   
            
get { return vector2BPStartPos; }   
            
set { vector2BPStartPos = value; }   
        }   
        
/// <summary>   
        
/// 大粒子体积   
        
/// </summary>   
        internal Vector2[] vector2BPOrigin;   
        
public Vector2[] Vector2BPOrigin   
        {   
            
get { return vector2BPOrigin; }   
            
set { vector2BPOrigin = value; }   
        }   
        
/// <summary>   
        
/// 记录第一个粒子的初始位置   
        
/// </summary>   
        internal Vector2 vector2BPStartPosParam;   
        
public Vector2 Vector2BPStartPosParam   
        {   
            
get { return vector2BPStartPosParam; }   
            
set { vector2BPStartPosParam = value; }   
        }   
        
//小粒子颜色   
        internal Color colorSP;   
        
public Color ColorSP   
        {   
            
get { return colorSP; }   
            
set { colorSP = value; }   
        }   
        
//小粒子颜色   
        internal Color colorBP;   
        
public Color ColorBP   
        {   
            
get { return colorBP; }   
            
set { colorBP = value; }   
        }  
        
#endregion   
  
        
//构造函数   
        public StructParticle2D_Meteor(int intSPCount)   
        {   
            
//Small   
            this.intSPCount                 = 0;   
            
this.floatSmallParticleInterval = 0;   
            
this.intSPStartRotation         = 0;   
            
this.intSPEndRotation           = 0;   
            
this.floatSPMinSize             = 0;   
            
this.floatSPMaxSize             = 0;   
            
this.flaotSPOriginParam         = 0;   
            
this.floatSPGParam              = 0;   
            
this.floatSPMaxRandomPos        = 0;   
            
this.floatSPMinRandomPos        = 0;   
            vector2SPStartPos               
= null;   
            floatSPOrigin                   
= null;   
            intSPRandomRotation             
= null;   
            floatSPRandomSpeed              
= null;   
            vector2SPRandomPos              
= null;   
            floatSPG                        
= null;   
            floatSPRandomInertiaX           
= null;   
            colorSP                         
= Color.White;   
  
            
//Big   
            this.intBPCount                 = 0;   
            
this.floatBPMaxX                = 0;   
            
this.floatBPMinX                = 0;   
            
this.floatBPMaxY                = 0;   
            
this.floatBPMinY                = 0;   
            
this.floatBPMoveParamX          = 0;   
            
this.floatBPMoveParamY          = 0;   
            
this.floatBPMinSize             = 0;   
            
this.floatBPMaxSize             = 0;   
            vector2BPStartPos               
= null;   
            vector2BPOrigin                 
= null;   
            vector2BPOrigin                 
= null;   
            vector2BPStartPosParam          
= Vector2.Zero;   
            colorBP                         
= Color.White;   
        }   
  
        
internal void Update(GameTime gameTime)   
        {   
            
for (int i = 0; i < intBPCount; i++)   
            {   
                vector2BPStartPos[i].X 
+= Game3.MoveFactorPerSecond * floatBPMoveParamX;   
                vector2BPStartPos[i].Y 
+= Game3.MoveFactorPerSecond * floatBPMoveParamY;   
            }   
  
            
for (int i = 0; i < intSPCount; i++)   
                
if (vector2BPStartPos[0].X >= vector2BPStartPosParam.X + i * floatSmallParticleInterval)   
                {   
                    
if (vector2SPStartPos[i] == Vector2.Zero)   
                    {   
                        vector2SPStartPos[i].X 
= vector2BPStartPos[0].X + vector2SPRandomPos[i].X;   
                        vector2SPStartPos[i].Y 
= vector2BPStartPos[0].Y + vector2SPRandomPos[i].Y;   
                    }   
                    
else  
                    {   
                        
//发散   
                        vector2SPStartPos[i].X += Game3.MoveFactorPerSecond * Game3.bulletHelper.floatCirqueX360[intSPRandomRotation[i]] * floatSPRandomSpeed[i];   
                        vector2SPStartPos[i].Y 
+= Game3.MoveFactorPerSecond * Game3.bulletHelper.floatCirqueY360[intSPRandomRotation[i]] * floatSPRandomSpeed[i];   
                        floatSPG[i] 
+= Game3.MoveFactorPerSecond * floatBPMoveParamX * floatSPGParam;   
                        
//下坠   
                        vector2SPStartPos[i].Y += 0.5f * 9.8f * floatSPG[i] * floatSPG[i];   
                        
//惯性   
                        vector2SPStartPos[i].X += Game3.MoveFactorPerSecond * floatBPMoveParamX * floatSPRandomInertiaX[i];   
                        
//体积变小   
                        floatSPOrigin[i] -= Game3.MoveFactorPerSecond * flaotSPOriginParam;   
                    }   
                }   
        }   
  
        
internal void Draw()   
        {   
            
//小   
            for (int i = 0; i < intSPCount; i++)   
                
if (vector2SPStartPos[i] != Vector2.Zero)   
                    
if (floatSPOrigin[i] >= 0.02f)   
                        
for (int j = 0; j < 3; j++)   
                            drawBullet(vector2SPStartPos[i], colorSP, floatSPOrigin[i]);   
  
            updateBPCountLimit();   
  
            
//大   
            for (int i = 0; i < intBPCountLimit; i++)   
                drawBullet(vector2BPStartPos[i], colorBP, vector2BPOrigin[i]);   
        }   
  
        
void updateBPCountLimit()   
        {   
            
//if (vector2SPStartPos[1000 - 1] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 10;   
            
//else if (vector2SPStartPos[900] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 9;   
            
//else if (vector2SPStartPos[800] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 8;   
            
//else if (vector2SPStartPos[700] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 7;   
            
//else if (vector2SPStartPos[600] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 6;   
            
//else if (vector2SPStartPos[500] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 5;   
            
//else if (vector2SPStartPos[400] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 4;   
            
//else if (vector2SPStartPos[300] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 3;   
            
//else if (vector2SPStartPos[200] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 2;   
            
//else if (vector2SPStartPos[100] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 1;   
            
//else if (vector2SPStartPos[0] != Vector2.Zero)   
            
//    intBPCountLimit = intBPCount - 0;   
  
            
for (int i = intSPCount; i >= 0; i -= 100)   
                
if (i == intSPCount)   
                {   
                    
if (vector2SPStartPos[intSPCount - 1!= Vector2.Zero)   
                        intBPCountLimit 
= 0;   
                    
return;   
                }   
                
else  
                {   
                    
if (vector2SPStartPos[i] != Vector2.Zero)   
                        intBPCountLimit 
= intBPCount - Convert.ToInt32(i / 100);   
                    
return;   
                }   
        }   
  
        
void drawBullet(Vector2 vector2Pos, Color color, Vector2 vector2Origin)   
        {   
            Game3.spriteBatch2.Draw(   
                Game3.textureDark_Bullet,   
                vector2Pos,   
                Game3.bulletHelper.recDarkBullet,   
                color,   
                
0,   
                Game3.bulletHelper.vector2DarkBullet,   
                vector2Origin,   
                SpriteEffects.None,   
                
0);   
        }   
  
        
void drawBullet(Vector2 vector2Pos, Color color, float floatOrigin)   
        {   
            Game3.spriteBatch2.Draw(   
                Game3.textureDark_Bullet,   
                vector2Pos,   
                Game3.bulletHelper.recDarkBullet,   
                color,   
                
0,   
                Game3.bulletHelper.vector2DarkBullet,   
                floatOrigin,   
                SpriteEffects.None,   
                
0);   
        }   
    }   
}

 

 

 

第二步:在Game.cs中添加如下代码:

 

代码
//粒子类   
        StructParticle2D_Meteor[] structParticle2D_Meteor = new StructParticle2D_Meteor[5];   
internal static SpriteBatch             spriteBatch1;   
        
internal static SpriteBatch             spriteBatch2;   
        
internal static SpriteBatch             spriteBatch3;   
        
internal static SpriteBatch             spriteBatch4;  

 

 

第三步:在Game.cs中初始化粒子类:

 

代码
//构造函数   
        public Game3        {   
            
for (int i = 0; i < structParticle2D_Meteor.Length; i++)   
                ConfigMeteor(i);   
}   
  
void ConfigMeteor(int intGroup)   
        {   
            structParticle2D_Meteor[intGroup]                               
= new StructParticle2D_Meteor(0);   
            structParticle2D_Meteor[intGroup].FloatSmallParticleInterval    
= 0.2f;   
            structParticle2D_Meteor[intGroup].FlaotSPOriginParam            
= 0.01f;//体积变小参数   
            structParticle2D_Meteor[intGroup].FloatSPGParam                 = 0.0004f;   
            
//大粒子数量,小粒子数量 = 大粒子数量 * 100   
            structParticle2D_Meteor[intGroup].IntBPCount                    = 15;   
            structParticle2D_Meteor[intGroup].IntSPCount                    
= structParticle2D_Meteor[intGroup].intBPCount * 100;   
            structParticle2D_Meteor[intGroup].colorSP                       
= new Color(100100100150);   
            structParticle2D_Meteor[intGroup].colorBP                       
= new Color(255255255150);   
  
            
if (intGroup == 0)   
            {   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamX 
= 10;//X角度(速度)   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamY = 2;//Y角度(速度)   
            }   
            
else if (intGroup == 1)   
            {   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamX 
= 15;   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamY 
= 4;   
            }   
            
else if (intGroup == 2)   
            {   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamX 
= 13;   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamY 
= 5;   
            }   
            
else if (intGroup == 3)   
            {   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamX 
= 10;   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamY 
= 4.5f;   
            }   
            
else if (intGroup == 4)   
            {   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamX 
= 7;   
                structParticle2D_Meteor[intGroup].FloatBPMoveParamY 
= 6;   
            }   
            structParticle2D_Meteor[intGroup].FloatSPOrigin         
= new float[structParticle2D_Meteor[intGroup].IntSPCount];   
            structParticle2D_Meteor[intGroup].IntSPRandomRotation   
= new int[structParticle2D_Meteor[intGroup].IntSPCount];   
            structParticle2D_Meteor[intGroup].FloatSPRandomSpeed    
= new float[structParticle2D_Meteor[intGroup].IntSPCount];   
            structParticle2D_Meteor[intGroup].Vector2SPRandomPos    
= new Vector2[structParticle2D_Meteor[intGroup].IntSPCount];   
            structParticle2D_Meteor[intGroup].FloatSPRandomInertiaX 
= new float[structParticle2D_Meteor[intGroup].IntSPCount];   
            structParticle2D_Meteor[intGroup].Vector2SPStartPos     
= new Vector2[structParticle2D_Meteor[intGroup].IntSPCount];   
            structParticle2D_Meteor[intGroup].Vector2BPStartPos     
= new Vector2[structParticle2D_Meteor[intGroup].IntBPCount];   
            structParticle2D_Meteor[intGroup].Vector2BPOrigin       
= new Vector2[structParticle2D_Meteor[intGroup].IntBPCount];   
            structParticle2D_Meteor[intGroup].FloatSPG              
= new float[structParticle2D_Meteor[intGroup].IntSPCount];   
  
            
for (int i = 0; i < structParticle2D_Meteor[intGroup].IntSPCount; i++)   
            {   
  
                structParticle2D_Meteor[intGroup].FloatSPOrigin[i]          
= RandomHelper.GetRandomFloat(0.06f0.1f);   
                structParticle2D_Meteor[intGroup].IntSPRandomRotation[i]    
= RandomHelper.GetRandomInt(250290);   
                
//发散速度   
                structParticle2D_Meteor[intGroup].FloatSPRandomSpeed[i]     = RandomHelper.GetRandomFloat(1.0f3.0f);   
                structParticle2D_Meteor[intGroup].Vector2SPRandomPos[i]     
= new Vector2(   
                    RandomHelper.GetRandomFloat(
-3.0f3.0f),   
                    RandomHelper.GetRandomFloat(
-3.0f3.0f));   
                structParticle2D_Meteor[intGroup].FloatSPRandomInertiaX[i]  
= RandomHelper.GetRandomFloat(0.1f0.3f);   
            }   
  
            
for (int i = 0; i < structParticle2D_Meteor[intGroup].IntBPCount; i++)   
            {   
                
if (intGroup == 0)   
                {   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X 
= RandomHelper.GetRandomFloat(-0.5f0.5f- 5;//初始位置   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y = RandomHelper.GetRandomFloat(-0.5f0.5f+ 5;//初始位置   
                }   
                
else if (intGroup == 1)   
                {   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X 
= RandomHelper.GetRandomFloat(-0.5f0.5f- 5;   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y 
= RandomHelper.GetRandomFloat(-0.5f0.5f+ 15;   
                }   
                
else if (intGroup == 2)   
                {   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X 
= RandomHelper.GetRandomFloat(-0.5f0.5f- 5;   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y 
= RandomHelper.GetRandomFloat(-0.5f0.5f+ 30;   
                }   
                
else if (intGroup == 3)   
                {   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X 
= RandomHelper.GetRandomFloat(-0.5f0.5f- 6;   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y 
= RandomHelper.GetRandomFloat(-0.5f0.5f+ 40;   
                }   
                
else if (intGroup == 4)   
                {   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X 
= RandomHelper.GetRandomFloat(-0.5f0.5f- 7;   
                    structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y 
= RandomHelper.GetRandomFloat(-0.5f0.5f+ 50;   
                }   
  
                structParticle2D_Meteor[intGroup].Vector2BPOrigin[i] 
= new Vector2(   
                    RandomHelper.GetRandomFloat(
0.15f0.2f),   
                    RandomHelper.GetRandomFloat(
0.1f0.15f));   
            }   
  
            structParticle2D_Meteor[intGroup].Vector2BPStartPosParam 
= structParticle2D_Meteor[intGroup].Vector2BPStartPos[intGroup];   
        }

 

第四步:重写Update与Draw函数

 

代码
public override void Update(GameTime gameTime)   
{   
    
for (int i = 0; i < structParticle2D_Meteor.Length; i++)   
        structParticle2D_Meteor[i].Update(gameTime);   
  
    
base.Update(gameTime);   
}   
  
public override void Draw(GameTime gameTime)   
{   
    Game3.spriteBatch2.Begin(SpriteBlendMode.Additive, SpriteSortMode.FrontToBack, SaveStateMode.None);   
  
    
//1.粒子   
    for (int i = 0; i < structParticle2D_Meteor.Length; i++)   
        structParticle2D_Meteor[i].Draw();   
  
    Game3.spriteBatch2.End();   
    
base.Draw(gameTime);   
}

 

修改Update里的代码可以让粒子按曲线飞行,代码上肯定有待改善的地方,回来试试,待更新:-D