基于C#弹幕类射击游戏的实现——(三)子弹的实现
2013-12-17 18:44
549 查看
我写博客喜欢做完一个东西,一口气写很多章。。。貌似这样不太好啊~
到这里,我们似乎该让主角上场了,好就让我们来显示一颗子弹吧~
慢着,显示子弹之前,我们需要小小的抽象一下,把游戏中所有能显示的物体抽象成GameObject,好处是什么?好处是看起来很帅。。
当然不是,好处简单来说,整合公共部分、利于管理~~好吧我也不知道好处。。。。
封装了一些基础属性和方法~~特别说明下:HalfWidth和HalfHeight只是用于计算的时候少一个除法,可以不需要的,后面的代码会看到
对了,特别说明下:一般的坐标系是以左上角为(0,0)点,向右为X正方向,向下为Y正方向。
而这个游戏是以屏幕的中间为远点,绘制图片的时候也是,以图片的中间为绘制点。。。至于为什么这样。。我当时脑抽了,忘了为什么了
接下来就是主角
唯一要说明的是Update方法的这两句
通过速度和加速度来更新子弹的位置,并且在后面同步更新碰撞盒的位置
这里用简单的物理知识来模拟了一下粒子的运行~其实可以做的更复杂一点,比如线速度角速度。
我们这里学习用,就简单一点。东方系列就比较复杂了
子弹肯定不止一个,而且有自己的和敌人的
所以需要一个管理类,用于管理一堆子弹
这里面没有遇到的类暂且不管。
大体上就是用一个List来保存所有GameBullet~~更新和绘制也是一个循环
唯一要做的就是检测子弹和其余单位是否碰撞了,碰撞的话要添加爆炸效果,然后移除这个子弹
好,现在你可以添加几个子弹来玩玩了。
比如,创建一个直线上升的子弹
创建一个斜着飞的子弹
创建一个越飞越快的子弹
大概就是这样
到这里,我们似乎该让主角上场了,好就让我们来显示一颗子弹吧~
慢着,显示子弹之前,我们需要小小的抽象一下,把游戏中所有能显示的物体抽象成GameObject,好处是什么?好处是看起来很帅。。
当然不是,好处简单来说,整合公共部分、利于管理~~好吧我也不知道好处。。。。
/// <summary> /// Description of GameObject. /// </summary> public class GameObject { public Vector2 Position; public Box BoxCollider; protected int Width; protected int Height; protected int HalfWidth; protected int HalfHeight; public GameObject() { } public virtual void Update(float elapsedTime) { } public virtual void Render(Graphics g) { } }
封装了一些基础属性和方法~~特别说明下:HalfWidth和HalfHeight只是用于计算的时候少一个除法,可以不需要的,后面的代码会看到
对了,特别说明下:一般的坐标系是以左上角为(0,0)点,向右为X正方向,向下为Y正方向。
而这个游戏是以屏幕的中间为远点,绘制图片的时候也是,以图片的中间为绘制点。。。至于为什么这样。。我当时脑抽了,忘了为什么了
接下来就是主角
/// <summary> /// Description of GameBullet. /// </summary> public class GameBullet : GameObject { public bool IsOwn; // 是否为自己的子弹 public int Type; // 子弹样式 public int Color; // 子弹颜色(0-6) public float ActiveDelay; // 延迟多久激活 public Vector2 Speed; public Vector2 Accel; public bool IsLive; // 是否存活 public GameBullet(bool isOwn, Vector2 position, Vector2 speed, Vector2 accel, int type, int color, float activeDelay) { this.IsOwn = isOwn; this.Type = type; this.Color = color; this.ActiveDelay = activeDelay; this.Position = position; this.Speed = speed; this.Accel = accel; this.IsLive = true; this.Width = Data.BulletsSize[type].Width; this.Height = Data.BulletsSize[type].Height; this.HalfWidth = this.Width / 2; this.HalfHeight = this.Height / 2; this.BoxCollider = new Box((int)position.X, (int)position.Y, this.Width, this.Height); } public override void Update(float elaspedTime) { if ( IsLive == false ) { return; } if (ActiveDelay > 0) { ActiveDelay -= elaspedTime; return; } Speed += (Accel * elaspedTime); Position += (Speed * elaspedTime); BoxCollider.X = (int)Position.X; BoxCollider.Y = (int)Position.Y; if ( Position.X < 0 || Position.Y < 0 || Position.X > Config.ScreenWidth || Position.Y > Config.ScreenHeight ) { IsLive = false; } } public override void Render(Graphics g) { if ( IsLive == false || ActiveDelay > 0) { return; } g.DrawImage(Data.BulletsSource[this.Type], new Rectangle((int)Position.X - HalfWidth, (int)Position.Y - HalfHeight, Width, Height), new Rectangle(this.Color * Width, 0, Width, Height), GraphicsUnit.Pixel); if ( Config.IsDebug && Config.IsShowBox ) { g.DrawRectangle(Pens.Green, BoxCollider.ToRectangle()); } } }
唯一要说明的是Update方法的这两句
Speed += (Accel * elaspedTime); Position += (Speed * elaspedTime);
通过速度和加速度来更新子弹的位置,并且在后面同步更新碰撞盒的位置
这里用简单的物理知识来模拟了一下粒子的运行~其实可以做的更复杂一点,比如线速度角速度。
我们这里学习用,就简单一点。东方系列就比较复杂了
子弹肯定不止一个,而且有自己的和敌人的
所以需要一个管理类,用于管理一堆子弹
public class GameBulletManager { private GameScene mScene; private List<GameBullet> mBullets; public GameBulletManager(GameScene scene) { this.mScene = scene; this.mBullets = new List<GameBullet>(); } public void AddBullet(GameBullet bullet) { mBullets.Add(bullet); } public void Update(float elapsedTime) { // 检测子弹的碰撞 for (int i = 0; i < mBullets.Count; i++) { mBullets[i].Update(elapsedTime); if (mBullets[i].IsLive == false) { mBullets.RemoveAt(i); i--; continue; } if ( mBullets[i].IsOwn == false ) // 不是自己的子弹 { if ( mScene.Player1.Collide(mBullets[i].BoxCollider, 1) == true ) { GameBombManager.AddBomb(mBullets[i].Position, false, 0.5f); mBullets.RemoveAt(i); i--; continue; } } else { if ( mScene.EnemyManager.Collide(mBullets[i].BoxCollider, 1) == true ) { GameBombManager.AddBomb(mBullets[i].Position, false, 0.5f); mBullets.RemoveAt(i); i--; continue; } if ( mScene.BossManager.Collide(mBullets[i].BoxCollider, 1) == true ) { GameBombManager.AddBomb(mBullets[i].Position, false, 0.5f); mBullets.RemoveAt(i); i--; continue; } } } } public void Render(Graphics g) { foreach (GameBullet bullet in mBullets) { bullet.Render(g); } if ( Config.IsDebug ) { g.DrawString("Bullets:" + mBullets.Count.ToString(), Data.NormalFont, Brushes.Red, 300, 0); } } }
这里面没有遇到的类暂且不管。
大体上就是用一个List来保存所有GameBullet~~更新和绘制也是一个循环
唯一要做的就是检测子弹和其余单位是否碰撞了,碰撞的话要添加爆炸效果,然后移除这个子弹
好,现在你可以添加几个子弹来玩玩了。
比如,创建一个直线上升的子弹
AddBullet(new Bullet(false, new Vector2(0, 0), new Vector2(0, -300), Vector2.Zero, 0, 0, 0);
创建一个斜着飞的子弹
AddBullet(new Bullet(false, new Vector2(0, 0), new Vector2(300, -300), Vector2.Zero, 0, 0, 0);
创建一个越飞越快的子弹
AddBullet(new Bullet(false, new Vector2(0, 0), new Vector2(0, -300), new Vector2(0, -100), 0, 0, 0);
大概就是这样
相关文章推荐
- 基于C#弹幕类射击游戏的实现——(七)弹幕类实现
- 基于C#弹幕类射击游戏的实现——(八)敌机
- 基于C#弹幕类射击游戏的实现——(四)玩家的战机
- 基于C#弹幕类射击游戏的实现——(九)BOSS
- 基于C#弹幕类射击游戏的实现——(一)概述
- 基于C#弹幕类射击游戏的实现——(二)渲染
- 基于C#弹幕类射击游戏的实现——(十)整合
- 基于Actor模式的c#网络游戏服务器的实现和Unity游戏客户端的连接
- Java基于Swing实现的打猎射击游戏代码
- 飞行射击的最基本算法实现 躲子弹的游戏
- 《游戏设计、原型与开发——基于Unity与C#从构思到实现》学习笔记一
- 基于C#实现俄罗斯方块游戏
- C#基于.net CF 2.0实现手机抓屏幕
- 基于MYSQL的 网络游戏 多线程 数据库 服务器 设计与实现
- 用C#实现基于用C#实现基于TCP协议的网络通讯
- 《设计模式——基于C#的工程化实现及扩展》封面火热出炉
- C#实现IVR(基于东进的语音卡)-2
- 用C#实现基于TCP协议的网络通讯
- C#实现modbus基于ASCII的LRC校验
- c#中异步基于消息通信的完成端口的TCP/IP协议的组件实现(客户端-源代码)