基于C#弹幕类射击游戏的实现——(八)敌机
2013-12-17 20:06
507 查看
有了弹幕,有了主角,敌人当然就该上场了。
其实敌人和主角类似,也是一架飞机,不同点在于敌人的飞机是AI控制的,而玩家的飞机是自己控制而已~
可以看出,和GamePlayer很类似,因为基本上都是一个东西。
唯一需要注意的是MoveLogic和ShootLogic。就是这两个虚函数实现了敌人的AI
要创建不同类型的敌人(包括BOSS),就是集成GameEnemy,然后重写这两个函数就行了
管理类也很简单,重点都不是这里。接下来实现几种敌机
第一种,出现后直接就飞走的,企图用身体撞玩家的愚蠢飞机,因为它更本不追踪玩家,只是蒙头飞
这一个要聪明点,懂得追着玩家跑,而且会发射子弹了。
这里也可以看出如果重写MoveLogic和ShootLogic来实现简单的AI
来个高端点的(AI其实很弱)
其实敌人的AI最好是用脚本来控制,但是为了简单,我们这里就这么做吧。
好了,游戏里有敌人了,而且分为不同的程度,有兴趣也可以自己添加新的,更聪明的敌机
其实敌人和主角类似,也是一架飞机,不同点在于敌人的飞机是AI控制的,而玩家的飞机是自己控制而已~
public class GameEnemy : GameObject { protected int Life; public bool IsLive; protected int Type; protected Vector2 Speed; protected Vector2 Accel; /// <summary> /// 敌机的位图大小盒子 /// </summary> public Box SourceBox { get { return new Box((int)Position.X, (int)Position.Y, EnemyWidth, EnemyHeight); } } /// <summary> /// 敌人发射子弹的类型 /// </summary> public enum ShootType { None, // 不发射子弹 Line, // 直线子弹 Trace, // 追踪子弹 Fan_3, // 成扇形发射3颗子弹 Fan_5 } protected ShootType mShootType; protected int EnemyWidth; protected int EnemyHeight; protected int HalfEnemyWidth; protected int HalfEnemyHeight; public GameEnemy(Vector2 position, int life, int type, ShootType shootType) { this.IsLive = true; base.Position = position; this.Speed = new Vector2(0, 0); this.Accel = new Vector2(0, 0); base.BoxCollider = new Box(0, 0, Data.EnemyBoxColliderRectangle[type].Width, Data.EnemyBoxColliderRectangle[type].Height); this.Life = life; this.Type = type; this.mShootType = shootType; this.EnemyWidth = Data.EnemySourceRectangle[type].Width; this.EnemyHeight = Data.EnemySourceRectangle[type].Height; this.HalfEnemyWidth = this.EnemyWidth / 2; this.HalfEnemyHeight = this.EnemyHeight / 2; } public void DecLife(int decLife) { Life -= decLife; if ( Life <= 0 ) { IsLive = false; GameBombManager.AddBomb(Position, false, 0.5f); } } protected virtual void MoveLogic(float elapsedTime) { Speed += Accel * elapsedTime; Position += Speed * elapsedTime; } protected virtual void ShootLogic(float elapsedTime) { } public override void Update(float elapsedTime) { MoveLogic(elapsedTime); ShootLogic(elapsedTime); base.BoxCollider.X = (int)(Position.X + Data.EnemyBoxColliderRectangle[Type].X); base.BoxCollider.Y = (int)(Position.Y + Data.EnemyBoxColliderRectangle[Type].Y); } public override void Render(Graphics g) { g.DrawImage(Data.EnemySource, new Rectangle((int)Position.X - HalfEnemyWidth, (int)Position.Y - HalfEnemyHeight, EnemyWidth, EnemyHeight), Data.EnemySourceRectangle[Type], GraphicsUnit.Pixel); if ( Config.IsDebug && Config.IsShowBox ) { g.DrawRectangle(Pens.Green, BoxCollider.ToRectangle()); } } }
可以看出,和GamePlayer很类似,因为基本上都是一个东西。
唯一需要注意的是MoveLogic和ShootLogic。就是这两个虚函数实现了敌人的AI
要创建不同类型的敌人(包括BOSS),就是集成GameEnemy,然后重写这两个函数就行了
public class GameEnemyManager { private List<GameEnemy> mEnemys; public GameEnemyManager() { this.mEnemys = new List<GameEnemy>(); } public void AddEnemy(GameEnemy enemy) { mEnemys.Add(enemy); } public bool Collide(Box box, int decLife) { for ( int i = 0; i < mEnemys.Count; i++ ) { if ( mEnemys[i].BoxCollider.Collide(box) == true ) { mEnemys[i].DecLife(decLife); return true; } } return false; } public void Update(float elapsedTime) { for ( int i = 0; i < mEnemys.Count; i++ ) { mEnemys[i].Update(elapsedTime); if ( mEnemys[i].IsLive == false ) { mEnemys.RemoveAt(i); i--; continue; } } } public void Render(Graphics g) { foreach ( GameEnemy enemy in mEnemys ) { enemy.Render(g); } if ( Config.IsDebug ) { g.DrawString("Enemys:" + mEnemys.Count.ToString(), Data.NormalFont, Brushes.Red, 300, 15); } } }
管理类也很简单,重点都不是这里。接下来实现几种敌机
第一种,出现后直接就飞走的,企图用身体撞玩家的愚蠢飞机,因为它更本不追踪玩家,只是蒙头飞
// 直接飞走 public class Enemy1 : GameEnemy { public Enemy1(Vector2 position) : base(position, 1, 0, ShootType.None) { } protected override void MoveLogic(float elapsedTime) { Position += new Vector2(0, 200 * elapsedTime); if ( GameScene.MainScene.InScreen(SourceBox) == false ) { IsLive = false; } } }
这一个要聪明点,懂得追着玩家跑,而且会发射子弹了。
这里也可以看出如果重写MoveLogic和ShootLogic来实现简单的AI
// 追踪,单个子弹 public class Enemy4 : GameEnemy { private Vector2 mDirection; private float ShootWaitTime; public Enemy4(Vector2 position) : base(position, 3, 3, ShootType.Trace) { this.Speed = new Vector2(225, 175); this.ShootWaitTime = 0.5f; } protected override void MoveLogic(float elapsedTime) { mDirection = GameScene.MainScene.Player1Position - Position; mDirection.Normalize(); mDirection.Y = 1; Position = Position + (mDirection * Speed * elapsedTime); if ( GameScene.MainScene.InScreen(SourceBox) == false ) { IsLive = false; } } protected override void ShootLogic(float elapsedTime) { if ( ShootWaitTime > 0 ) { ShootWaitTime -= elapsedTime; return; } if ( Helper.GetRandomBool() ) { GameScene.MainScene.AddBullet(new GameBullet(false, Position + new Vector2(0, HalfEnemyHeight + 3), new Vector2(0, 200), Vector2.Zero, 0, 0, 0)); ShootWaitTime = 2.0f; } } }
来个高端点的(AI其实很弱)
public class Enemy9 : GameEnemy { private float HorizonalMoveDistance; // 水平移动距离 private bool MoveLeft; // 移动方向是否为左 private float WaitTime; private float ShootWaitTime; public Enemy9(Vector2 position) : base(position, 20, 8, ShootType.Fan_5) { this.Speed = new Vector2(50, 150); this.HorizonalMoveDistance = 0; this.MoveLeft = true; this.WaitTime = 0; this.ShootWaitTime = 2.0f; } protected override void MoveLogic(float elapsedTime) { if ( Position.Y < 150 ) { Position.Y += Speed.Y * elapsedTime; return; } if ( WaitTime > 0 ) { WaitTime -= elapsedTime; return; } if ( HorizonalMoveDistance <= 0 ) { WaitTime = 2.0f; MoveLeft = (Position.X - GameScene.MainScene.Player1Position.X) < 0 ? false : true; HorizonalMoveDistance = Helper.GetRandomFloat(30, 80); if ( MoveLeft && Position.X - HorizonalMoveDistance < HalfEnemyWidth ) { MoveLeft = !MoveLeft; } if ( !MoveLeft && Position.X + HorizonalMoveDistance > Config.ScreenWidth - HalfEnemyWidth ) { MoveLeft = !MoveLeft; } } else { if ( MoveLeft ) { Position.X -= Speed.X * elapsedTime; } else { Position.X += Speed.X * elapsedTime; } HorizonalMoveDistance -= Speed.X * elapsedTime; } } protected override void ShootLogic(float elapsedTime) { if ( ShootWaitTime > 0 ) { ShootWaitTime -= elapsedTime; return; } if ( Helper.GetRandomInt(0, 100) < 30 ) { ShootWaitTime = 3.0f; GameScene.MainScene.AddBullet(new GameBullet(false, Position + new Vector2(-5, HalfEnemyHeight + 3), new Vector2(-50, 200), Vector2.Zero, 0, 0, 0)); GameScene.MainScene.AddBullet(new GameBullet(false, Position + new Vector2(-2.5f, HalfEnemyHeight + 3), new Vector2(-25, 200), Vector2.Zero, 0, 0, 0)); GameScene.MainScene.AddBullet(new GameBullet(false, Position + new Vector2(0, HalfEnemyHeight + 3), new Vector2(0, 200), Vector2.Zero, 0, 0, 0)); GameScene.MainScene.AddBullet(new GameBullet(false, Position + new Vector2(2.5f, HalfEnemyHeight + 3), new Vector2(25, 200), Vector2.Zero, 0, 0, 0)); GameScene.MainScene.AddBullet(new GameBullet(false, Position + new Vector2(5, HalfEnemyHeight + 3), new Vector2(50, 200), Vector2.Zero, 0, 0, 0)); } } }
其实敌人的AI最好是用脚本来控制,但是为了简单,我们这里就这么做吧。
好了,游戏里有敌人了,而且分为不同的程度,有兴趣也可以自己添加新的,更聪明的敌机
相关文章推荐
- 基于C#弹幕类射击游戏的实现——(九)BOSS
- 基于C#弹幕类射击游戏的实现——(四)玩家的战机
- 基于C#弹幕类射击游戏的实现——(一)概述
- 基于C#弹幕类射击游戏的实现——(二)渲染
- 基于C#弹幕类射击游戏的实现——(十)整合
- 基于C#弹幕类射击游戏的实现——(七)弹幕类实现
- 基于C#弹幕类射击游戏的实现——(三)子弹的实现
- 《游戏设计、原型与开发——基于Unity与C#从构思到实现》学习笔记一
- 基于C#实现俄罗斯方块游戏
- Java基于Swing实现的打猎射击游戏代码
- 基于Actor模式的c#网络游戏服务器的实现和Unity游戏客户端的连接
- 用C#实现基于TCP协议的网络通讯
- 《设计模式--基于C#的工程化实现及扩展》到货了
- 排块游戏 (c#实现)
- 《设计模式 基于C#的工程化实现及扩展》 - 书摘精要
- C#实现IVR(基于东进的语音卡)-3
- C#实现十五子游戏
- 转:高层游戏引擎——基于OGRE所实现的高层游戏引擎框架
- 基于.Net平台应用程序唯一运行实例C#代码实现
- C#实现基于XML配置MenuStrip菜单的方法