接下来就像填充积木一样,把GameScene里用到的东西一个个写完~~

先来个最简单的。GameBomb

一目了然

public class GameBomb : GameObject

{

public bool IsLive;

private int FrameIndex;

private int FrameMax;

private float FrameDelay;

private int FrameWidth;

private int FrameHeight;

private int FrameHalfWidth;

private int FrameHalfHeight;

private float time;

public GameBomb(Vector2 position, bool isBig, float duration)

{

this.Position = position;

this.FrameIndex = 0;

this.FrameMax = Config.BombSmallFrameMax;

this.FrameWidth = Config.BombSmallFrameWidth;

this.FrameHeight = Config.BombSmallFrameHeight;

this.FrameHalfWidth = this.FrameWidth / 2;

this.FrameHalfHeight = this.FrameHeight / 2;

this.FrameDelay = duration / (float)this.FrameMax;

this.IsLive = true;

}

public override void Update(float elapsedTime)

{

if ( IsLive == false )

{

return;

}

time += elapsedTime;

if ( time >= FrameDelay )

{

time -= FrameDelay;

FrameIndex++;

if ( FrameIndex >= FrameMax )

{

IsLive = false;

}

}

}

public override void Render(Graphics g)

{

if ( IsLive == false )

{

return;

}

g.DrawImage(Data.BombSource,

new Rectangle((int)Position.X - FrameHalfWidth, (int)Position.Y - FrameHalfHeight, FrameWidth, FrameHeight),

new Rectangle(FrameWidth * FrameIndex, 0, FrameWidth, FrameHeight),

GraphicsUnit.Pixel);

}

}

如果不熟悉的,估计是对2D类的精灵动画不太了解。。可以百度了解下。

或者简单讲解,就是按照时间,不断的绘制一样图片中不同位置的精灵~看起来就像动态的了。

接下来是它的管理类GameBombManager

public static class GameBombManager

{

private static List mBombs = new List();

public static void AddBomb(Vector2 position, bool isBig, float duration)

{

mBombs.Add(new GameBomb(position, isBig, duration));

}

public static void Update(float elapsedTime)

{

for ( int i = 0; i < mBombs.Count; i++ )

{

mBombs[i].Update(elapsedTime);

if ( mBombs[i].IsLive == false )

{

mBombs.RemoveAt(i);

i--;

continue;

}

}

}

public static void Render(Graphics g)

{

foreach ( GameBomb bomb in mBombs )

{

bomb.Render(g);

}

}

}

这个看起来就比我们之前见过的简单多了。

好,这章就这么结束了!!貌似有点少啊。。。

好吧,那接下来讲一个与本游戏无关的,粒子系统(其实粒子系统在游戏中很重要,只是这个游戏很简单,没有用到而已)

public struct GameParticle

{

///

/// 粒子位置

///

public Vector2 Position;

///

/// 粒子速度

///

public Vector2 Velocity;

///

/// 重力加速度

///

public float Gravity;

///

/// 直线加速度(运动方向上的加速度)

///

public float RadialAccel;

///

/// 切线上的加速度(角速度)

///

public float TangentialAccel;

///

/// 粒子旋转角度

///

public float Spin;

///

/// 粒子旋转速度增量

///

public float SpinDelta;

///

/// 粒子大小

///

public float Size;

///

/// 粒子大小增量

///

public float SizeDelta;

///

/// 粒子生存时间

///

public float Age;

///

/// 粒子死亡时间

///

public float TerminalAge;

}

///

/// 粒子配置信息

///

public struct GameParticleSystemInfo

{

///

/// 粒子贴图

///

public Bitmap Texture;

///

/// 每秒发射的粒子数量

///

public int Emission;

///

/// 生命周期

///

public float LifeTime;

///

/// 粒子生命周期范围

///

public Range ParticleLife;

///

/// 方向

///

public float Direction;

///

/// 偏移角度

///

public float Spread;

///

/// 是否为绝对值(计算生成粒子的初始速度)

///

public bool IsRelative;

///

/// 速度范围

///

public Range Speed;

///

/// 重力加速度范围

///

public Range Gravity;

///

/// 直线加速度范围

///

public Range RadialAccel;

///

/// 切线角加速度范围

///

public Range TangentialAccel;

///

/// 起始大小

///

public float SizeStart;

///

/// 最终大小

///

public float SizeEnd;

///

/// 大小变化量

///

public float SizeVar;

///

/// 起始旋转角度

///

public float SpinStart;

///

/// 最终旋转角度

///

public float SpinEnd;

///

/// 角度变化值

///

public float SpinVar;

}

///

/// 粒子系统

///

public class GameParticleSystem

{

///

/// 粒子最大数量

///

public const int MaxParticles = 512;

///

/// 粒子系统未启动

///

public const float Particle_System_Not_Start = -2.0f;

///

/// 粒子发射器的配置信息

///

public GameParticleSystemInfo Info;

private GameParticle[] mParticles; // 粒子集合

///

/// 剩余时间

///

private float Age;

///

/// 剩余未发射粒子

///

private float EmissionResidue;

private Vector2 PrevPosition; // 上一个位置

private Vector2 Position; // 当前位置

private Vector2 Offset; // 偏移量

private float Scale; // 整体缩放系数

///

/// 活动粒子个数

///

private int ParticlesAlive;

public GameParticleSystem(GameParticleSystemInfo info)

{

this.mParticles = new GameParticle[MaxParticles];

this.Info = info;

this.Position = new Vector2(0, 0);

this.PrevPosition = new Vector2(0, 0);

this.Offset = new Vector2(0, 0);

this.Scale = 1.0f;

this.EmissionResidue = 0;

this.ParticlesAlive = 0;

this.Age = Particle_System_Not_Start;

}

///

/// 移动粒子发射器到制动位置

///

/// 横坐标

/// 纵坐标

/// 是否移动活动粒子

public void MoveTo(float x, float y, bool moveParticles)

{

float dx = 0;

float dy = 0;

if ( moveParticles )

{

dx = x - Position.X;

dy = y - Position.Y;

for ( int i = 0; i < ParticlesAlive; i++ )

{

mParticles[i].Position.X += dx;

mParticles[i].Position.Y += dy;

}

PrevPosition.X = PrevPosition.X + dx;

PrevPosition.Y = PrevPosition.Y + dy;

}

else

{

if ( Age == Particle_System_Not_Start )

{

PrevPosition.X = x;

PrevPosition.Y = y;

}

else

{

PrevPosition.X = Position.X;

PrevPosition.Y = Position.Y;

}

}

Position.X = x;

Position.Y = y;

}

///

/// 启动粒子系统

///

public void Start()

{

if ( Info.LifeTime == -1.0f )

{

Age = -1.0f;

}

else

{

Age = 0;

}

}

///

/// 在指定位置启动粒子系统

///

/// 横坐标

/// 纵坐标

public void Start(float x, float y)

{

Stop(false);

MoveTo(x, y, false);

Start();

}

///

/// 停止粒子系统

///

/// 是否摧毁活动粒子

public void Stop(bool killParticles)

{

Age = Particle_System_Not_Start;

if ( killParticles )

{

ParticlesAlive = 0;

}

}

public float GetAge()

{

return Age;

}

public void Update(float elapsedTime)

{

float ang = 0;

Vector2 accel1;

Vector2 accel2;

if ( Age >= 0 )

{

Age += elapsedTime;

if ( Age >= Info.LifeTime )

{

Age = Particle_System_Not_Start;

}

}

for ( int i = 0; i < ParticlesAlive; i++ )

{

mParticles[i].Age += elapsedTime;

if ( mParticles[i].Age >= mParticles[i].TerminalAge )

{

ParticlesAlive--;

mParticles[i] = mParticles[ParticlesAlive];

i--;

continue;

}

// 计算粒子直线加速度

accel1 = mParticles[i].Position - Position;

accel1.Normalize();

accel2 = accel1;

accel1 = accel1 * mParticles[i].RadialAccel;

// 计算粒子切线加速度

ang = accel2.X;

accel2.X = -accel2.Y;

accel2.Y = ang;

accel2 = accel2 * mParticles[i].TangentialAccel;

// 计算粒子速度

mParticles[i].Velocity += (accel1 + accel2) * elapsedTime;

mParticles[i].Velocity.Y += mParticles[i].Gravity * elapsedTime;

mParticles[i].Position += mParticles[i].Velocity * elapsedTime;

mParticles[i].Spin += mParticles[i].SpinDelta;

mParticles[i].Size += mParticles[i].SizeDelta;

}

if ( Age != Particle_System_Not_Start )

{

// 计算需要生成的粒子数量

float ParticlesNeeded = Info.Emission * elapsedTime + EmissionResidue;

int ParticlesCreated = (int)((uint)ParticlesNeeded);

EmissionResidue = ParticlesNeeded - ParticlesCreated;

int n = ParticlesAlive;

for ( int i = n; i < n + ParticlesCreated; i++ )

{

if ( ParticlesAlive >= MaxParticles )

{

break;

}

mParticles[i].Age = 0;

mParticles[i].TerminalAge = Info.ParticleLife.Get();

mParticles[i].Position = PrevPosition + (Position - PrevPosition) * Helper.GetRandomFloat(0, 1);

mParticles[i].Position.X += Helper.GetRandomFloat(-2.0f, 2.0f);

mParticles[i].Position.Y += Helper.GetRandomFloat(-2.0f, 2.0f);

ang = Info.Direction - Data.TwoPI + Helper.GetRandomFloat(0, Info.Spread) - Info.Spread / 2.0f;

if ( Info.IsRelative )

{

ang += (PrevPosition - Position).Angle() + Data.TwoPI;

}

mParticles[i].Velocity.X = (float)Math.Cos(ang);

mParticles[i].Velocity.Y = (float)Math.Sin(ang);

mParticles[i].Velocity *= Info.Speed.Get();

mParticles[i].Gravity = Info.Gravity.Get();

mParticles[i].RadialAccel = Info.RadialAccel.Get();

mParticles[i].TangentialAccel = Info.TangentialAccel.Get();

mParticles[i].Size = Helper.GetRandomFloat(Info.SizeStart, Info.SizeStart + (Info.SizeEnd - Info.SizeStart) * Info.SizeVar);

mParticles[i].SizeDelta = (Info.SizeEnd - mParticles[i].Size) / mParticles[i].TerminalAge;

mParticles[i].Spin = Helper.GetRandomFloat(Info.SpinStart, Info.SpinStart + (Info.SpinEnd - Info.SpinStart) * Info.SpinVar);

mParticles[i].SpinDelta = (Info.SpinEnd - mParticles[i].Spin) / mParticles[i].TerminalAge;

ParticlesAlive++;

}

}

PrevPosition = Position;

}

public void Render(Graphics g)

{

for ( int i = 0; i < ParticlesAlive; i++ )

{

g.DrawImage(Data.BulletSource,

new Rectangle((int)(mParticles[i].Position.X * Scale + Offset.X),

(int)(mParticles[i].Position.Y * Scale + Offset.Y),

(int)(16.0f * Scale),

(int)(16.0f * Scale)),

new Rectangle(0, 0, 16, 16),

GraphicsUnit.Pixel);

}

}

}

///

/// 粒子管理器

///

public class GameParticleManager

{

///

/// 粒子系统最大个数

///

public const int MaxParticleSystem = 10;

private GameParticleSystem[] mPSList;

private int mPSCount;

private Vector2 mOffset;

public Vector2 Offset

{

get

{

return mOffset;

}

set

{

mOffset = value;

for ( int i = 0; i < mPSCount; i++ )

{

mPSList[i].MoveTo(mOffset.X, mOffset.Y, false);

}

}

}

public GameParticleManager()

{

mPSList = new GameParticleSystem[MaxParticleSystem];

mOffset = new Vector2(0, 0);

mPSCount = 0;

}

public void Spwan(float x, float y, GameParticleSystemInfo info)

{

if ( mPSCount >= MaxParticleSystem )

{

return;

}

mPSList[mPSCount] = new GameParticleSystem(info);

mPSList[mPSCount].Start(x, y);

mPSCount++;

}

public bool IsAlive(GameParticleSystem psi)

{

for ( int i = 0; i < mPSCount; i++ )

{

if ( mPSList[i] == psi )

{

return true;

}

}

return false;

}

public void Kill(GameParticleSystem psi)

{

for ( int i = 0; i < mPSCount; i++ )

{

if ( mPSList[i] == psi )

{

mPSList[i] = mPSList[mPSCount - 1];

mPSCount--;

return;

}

}

}

public void KillAll()

{

mPSCount = 0;

}

public void Update(float elapsedTime)

{

for ( int i = 0; i < mPSCount; i++ )

{

mPSList[i].Update(elapsedTime);

if ( mPSList[i].GetAge() == GameParticleSystem.Particle_System_Not_Start )

{

mPSList[i] = mPSList[mPSCount - 1];

mPSCount--;

i--;

}

}

}

public void Render(Graphics g)

{

for ( int i = 0; i < mPSCount; i++ )

{

mPSList[i].Render(g);

}

}

}

c#控件弹幕效果_基于C#弹幕类射击游戏的实现——(六)爆炸效果相关推荐

  1. global 仪表控件 无人机地面站_基于GL Studio的无人机地面站天线控件设计与实现...

    基于 GL Studio 的无人机地面站天线控件设计与实现 李兴岷 ; 陈怀民 ; 喻戈 ; 任伟 [期刊名称] <测控技术> [年 ( 卷 ), 期] 2011(030)009 [摘要] ...

  2. c#控件弹幕效果_基于C#弹幕类射击游戏的实现——(十)整合

    先看实现的效果 剩下部分代码,首先是入口,MainForm public partial class MainForm : Form { public MainForm() { // // The I ...

  3. c#控件弹幕效果_基于C#弹幕类射击游戏的实现——(二)渲染

    这个游戏打算是用C#+GDI做~所以渲染效率上还是要进行一些考虑的 public interface IRenderHandler { void Clear(Color backgroundColor ...

  4. HTML5游戏_基于DOM平台跳跃小游戏开发_9.按键监听

    HTML5游戏_基于DOM平台跳跃小游戏开发 按键监听 视频讲解 HTML5游戏 效果图 本章知识点: 对象自定义名称属性,可以用变量来命名属性名称 //这段代码把多个属性(品牌, 型号, 排量)赋给 ...

  5. 太空射击第13课: 爆炸效果

    太空射击第13课: 爆炸效果 在本课中,我们将在玩家射击流星时进行一些动画爆炸. 视频 您可以在此处观看本课程的视频: 自动开火 首先,让我们对玩家的射击方式进行一些小的改变.现在,我们必须为每次射击 ...

  6. vs mfc数据与控件绑定错了_如何进行数据趋势分析?VS扩展工具——C1迷你图控件了解一下...

    点击"了解更多"获取ComponentOne 2020 v1正式版下载 迷你图 -- Sparklines是迷你的轻量级图表,有助于快速可视化数据. 它们是由数据可视化传奇人物Ed ...

  7. dev里timeedit控件如何赋值_抽奖程序里的字节跳动模式和时长控制,让抽奖更有仪式感!...

    用excel的随机函数配合index函数可以很方便的实现从一组数据中随机抽取单个数据,常用于抽奖小程序.但若想让抽奖时数据跳动一段时间再出现最终的结果,就好像真正的抽奖一样,只用函数就不好实现了.今天 ...

  8. 控件尺寸规范_微信小程序设计规范你了解多少

    正好最近我也要开发小程序,所以今天我就从设计方面聊一聊微信小程序设计规范,埋上设计中可能会出现的坑,让你能更好的完成你的小程序- 一.宏观角度 微信小程序设计的基本原则是微信设计中心针对在微信类上线的 ...

  9. gtk 控件内存回收_咱们从头到尾说一次 Java 垃圾回收

    作者:聂晓龙(花名:率鸽) 来源:微信公众号,阿里巴巴中间件 之前上学的时候有这个一个梗,说在食堂里吃饭,吃完把餐盘端走清理的,是 C++ 程序员,吃完直接就走的,是 Java 程序员. 确实,在 J ...

最新文章

  1. 码农技术炒股之路——数据库管理器、正则表达式管理器
  2. js / jquery 零散收集
  3. 笑抽了!这个程序员正在坐电梯,被HR逮到偷偷出去面试!
  4. Vue Iview Tree插件的无限层
  5. Qracle学习:排序
  6. 思科模拟器,计算机网络实验三之:静态路由配置
  7. SAP Fiori Elements - bindComponent - binding property in XML view will trigger odata request
  8. python删除列表中的偶数_Python:从列表中删除奇数
  9. Java中的事务——JDBC事务和JTA事务
  10. String.getBytes(Unicode)的疑问 以及 SHIFT-JIS编码范围
  11. php 获取 js json数据类型,JS基础-JS的数据类型和访问/流程控制/JSON格式字符串和js对象相互转换...
  12. 在计算机领域提到的假说,量子力学中假说的发展及相关影响
  13. linux越狱时手机怎么进入dfu,通过软件恢复进入DFU刷机模式教程
  14. python 运行另一个py_如何在python中执行另一个py文件
  15. python计算微分方程组_如何使用python计算常微分方程?
  16. 二维码获取WIFI配置
  17. 虚拟机Oracle VM VirtualBox 共享文件夹放的文件打不开,找不到指定路径问题
  18. 数码相机图像处理原理
  19. oracle归档日志百分比,oracle归档日志过满清理
  20. 【经验分享】BMPR文件及其打开软件Balsamiq Wireframes的下载和安装

热门文章

  1. 电子货架标签多种固定方式
  2. 神器!这个Python神器竟能把图片视频无损清晰放大N倍!
  3. 对于一个字符串,找到第一次重复出现的字符
  4. 王道计算机网络课代表 - 考研计算机 第四章 网络层 究极精华总结笔记
  5. Vue3+Element-Plus 项目概述一
  6. TS中类的继承和类的重写
  7. Python标准库笔记(9) — functools模块
  8. 机器视觉中的前景和背景是什么意思
  9. 线上问题定位------网络瓶颈
  10. 一站式终端解决方案 —— MobaXterm使用宝典