有了彈幕,有了主角,敵人當(dāng)然就該上場了。
其實(shí)敵人和主角類似,也是一架飛機(jī),不同點(diǎn)在于敵人的飛機(jī)是AI控制的,而玩家的飛機(jī)是自己控制而已~
public class GameEnemy : GameObject
{
protected int Life;
public bool IsLive;
protected int Type;
protected Vector2 Speed;
protected Vector2 Accel;
/// <summary>
/// 敵機(jī)的位圖大小盒子
/// </summary>
public Box SourceBox
{
get
{
return new Box((int)Position.X, (int)Position.Y, EnemyWidth, EnemyHeight);
}
}
/// <summary>
/// 敵人發(fā)射子彈的類型
/// </summary>
public enum ShootType
{
None, // 不發(fā)射子彈
Line, // 直線子彈
Trace, // 追蹤子彈
Fan_3, // 成扇形發(fā)射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很類似,因?yàn)榛旧隙际且粋€東西。
唯一需要注意的是MoveLogic和ShootLogic。就是這兩個虛函數(shù)實(shí)現(xiàn)了敵人的AI
要創(chuàng)建不同類型的敵人(包括BOSS),就是集成GameEnemy,然后重寫這兩個函數(shù)就行了
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);
}
}
}
管理類也很簡單,重點(diǎn)都不是這里。接下來實(shí)現(xiàn)幾種敵機(jī)
第一種,出現(xiàn)后直接就飛走的,企圖用身體撞玩家的愚蠢飛機(jī),因?yàn)樗静蛔粉櫷婕遥皇敲深^飛
// 直接飛走
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;
}
}
}
這一個要聰明點(diǎn),懂得追著玩家跑,而且會發(fā)射子彈了。
這里也可以看出如果重寫MoveLogic和ShootLogic來實(shí)現(xiàn)簡單的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;
}
}
}
來個高端點(diǎn)的(AI其實(shí)很弱)
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));
}
}
}
其實(shí)敵人的AI最好是用腳本來控制,但是為了簡單,我們這里就這么做吧。
好了,游戲里有敵人了,而且分為不同的程度,有興趣也可以自己添加新的,更聰明的敵機(jī)