使用 XNA 4.0 實作 2D 粒子特效(流星雨樣式),對比 Debug 與 Release 建置 的幀率差異,驗證結構體陣列、預計算三角函數表、批次繪製等優化手段效果。測試環境:Windows 7、XNA 4.0、單一 SpriteBatch 批次提交。
定義 StructParticle2D_Meteor 結構體,包含大粒子與小粒子所有屬性陣列:
floatCirqueX360[360]/floatCirqueY360[360] 三角函數表,避免即時 Math.Sin/Cos。
internal void Update(GameTime gameTime)
{
// 大粒子位置更新
for (int i = 0; i < intBPCount; i++)
{
vector2BPStartPos[i].X += MoveFactorPerSecond * floatBPMoveParamX;
vector2BPStartPos[i].Y += 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 += MoveFactorPerSecond * floatCirqueX360[intSPRandomRotation[i]] * floatSPRandomSpeed[i];
vector2SPStartPos[i].Y += MoveFactorPerSecond * floatCirqueY360[intSPRandomRotation[i]] * floatSPRandomSpeed[i];
// 重力下墜
floatSPG[i] += MoveFactorPerSecond * floatBPMoveParamX * floatSPGParam;
vector2SPStartPos[i].Y += 0.5f * 9.8f * floatSPG[i] * floatSPG[i];
// 慣性
vector2SPStartPos[i].X += MoveFactorPerSecond * floatBPMoveParamX * floatSPRandomInertiaX[i];
// 體積遞減
floatSPOrigin[i] -= MoveFactorPerSecond * flaotSPOriginParam;
}
}
}
}
SpriteBatch (spriteBatch2) 使用 SpriteBlendMode.Additive 疊加模式。updateBPCountLimit() 根據最後一批小粒子是否發射,決定大粒子繪製數量,避免無效 DrawCall。| 建置模式 | 幀率 (FPS) | 粒子總數 | 備註 |
|---|---|---|---|
| Debug | 136 | 5 組 × (15 大 + 1500 小) = 7575 | 含完整偵錯符號、無優化 |
| Release | 176 | 同左 | 優化啟用,提升 40 幀 (29%) |
截圖對比:
StructParticle2D_Meteor.cs:粒子結構體與更新/繪製邏輯。Game3.cs:初始化 5 組粒子參數(不同速度、角度、顏色)、LoadContent 載入材質、Update/Draw 迴圈驅動。RandomHelper、BulletHelper (三角函數表) 等輔助類別。VertexBuffer + Geometry Shader / Compute Shader 完全卸載 CPU。Parallel.For 平行化粒子更新迴圈(需鎖自由資料結構)。完整專案原始碼:XnaStructure3.rar