效果圖,重力值設置的比較小不夠明顯,但是看得出來,注意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(100, 100, 100, 150);
structParticle2D_Meteor[intGroup].colorBP = new Color(255, 255, 255, 150);
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.06f, 0.1f);
structParticle2D_Meteor[intGroup].IntSPRandomRotation[i] = RandomHelper.GetRandomInt(250, 290);
//發散速度
structParticle2D_Meteor[intGroup].FloatSPRandomSpeed[i] = RandomHelper.GetRandomFloat(1.0f, 3.0f);
structParticle2D_Meteor[intGroup].Vector2SPRandomPos[i] = new Vector2(
RandomHelper.GetRandomFloat(-3.0f, 3.0f),
RandomHelper.GetRandomFloat(-3.0f, 3.0f));
structParticle2D_Meteor[intGroup].FloatSPRandomInertiaX[i] = RandomHelper.GetRandomFloat(0.1f, 0.3f);
}
for (int i = 0; i < structParticle2D_Meteor[intGroup].IntBPCount; i++)
{
if (intGroup == 0)
{
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X = RandomHelper.GetRandomFloat(-0.5f, 0.5f) - 5;//初始位置
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y = RandomHelper.GetRandomFloat(-0.5f, 0.5f) + 5;//初始位置
}
else if (intGroup == 1)
{
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X = RandomHelper.GetRandomFloat(-0.5f, 0.5f) - 5;
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y = RandomHelper.GetRandomFloat(-0.5f, 0.5f) + 15;
}
else if (intGroup == 2)
{
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X = RandomHelper.GetRandomFloat(-0.5f, 0.5f) - 5;
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y = RandomHelper.GetRandomFloat(-0.5f, 0.5f) + 30;
}
else if (intGroup == 3)
{
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X = RandomHelper.GetRandomFloat(-0.5f, 0.5f) - 6;
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y = RandomHelper.GetRandomFloat(-0.5f, 0.5f) + 40;
}
else if (intGroup == 4)
{
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].X = RandomHelper.GetRandomFloat(-0.5f, 0.5f) - 7;
structParticle2D_Meteor[intGroup].Vector2BPStartPos[i].Y = RandomHelper.GetRandomFloat(-0.5f, 0.5f) + 50;
}
structParticle2D_Meteor[intGroup].Vector2BPOrigin[i] = new Vector2(
RandomHelper.GetRandomFloat(0.15f, 0.2f),
RandomHelper.GetRandomFloat(0.1f, 0.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