小游戏坦克大战,看似是一个很小的程序。
但实际使用做起来,发现需要用到多种功能:
多线程并发与同步,事件触发,GDI绘图。
可以采用事件订阅 与事件触发的观察者模式。
从网络上下载声音文件 以及 各种坦克图片等素材。
实体分类如下:
1.有静止的地图元素【MapElement】:如墙体、水域、草丛、钢铁墙、老鹰等,为了区分不同的元素,同时加入地图元素类型枚举【MapElementCategory】。
2.有坦克【Tank】,又细分为玩家坦克【PlayerTank】和敌方坦克【EnemyTank】两种。玩家坦克可以升星,增加坦克等级枚举【PlayerTankLevel】。敌方坦克也有不同的种类【EnemyTankCategory】。
3.坦克可以攻击,产生子弹【Bullet】,子弹分玩家子弹和敌方子弹。这里用子弹类型枚举【BulletCategory】表示。
4.玩家子弹击中发光的敌方坦克【会掉落道具的】会产生道具【Prop】,每种道具都有不同的效果,因此增加道具枚举【PropCategory】。
5.子弹和坦克的移动需要有方向,增加方向枚举Direction.
6.以上的地图元素、坦克、子弹、道具都可以认为是一个矩形,需要考虑两个矩形的碰撞。因此建立抽象类矩形对象【RectangleObject】,所有对象都继承该抽象类。
整体类的属性源程序如下:
一、RectangleObject.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 【抽象类】矩形物体:所有的坦克,地图元素【墙、钢铁、草丛】,子弹,道具都是由一个填充图片的矩形构成
/// 该类是所有地图资源的基类,主要用于判断两个地图资源是否碰撞(相交)
/// </summary>
public abstract class RectangleObject
{
public RectangleObject(Image image, int x, int y, int width, int height)
{
this.Image = image;
this.X = x;
this.Y = y;
this.Width = width == 0 ? image.Width : width;
this.Height = height == 0 ? image.Height : height;
}
/// <summary>
/// 图片资源,一般是位图资源Bitmap
/// </summary>
public Image Image { get; set; }
/// <summary>
/// 起始X坐标
/// </summary>
public int X { get; set; }
/// <summary>
/// 起始Y坐标
/// </summary>
public int Y { get; set; }
/// <summary>
/// 宽度
/// </summary>
public int Width { get; set; }
/// <summary>
/// 高度
/// </summary>
public int Height { get; set; }
/// <summary>
/// 判断两个物体是否是相交的,
/// 比如 子弹与敌方坦克是否碰撞,玩家坦克与道具是否碰撞,子弹与墙体进行碰撞等
/// </summary>
/// <param name="rectangleObject"></param>
/// <returns></returns>
public virtual bool IsIntersected(RectangleObject rectangleObject)
{
Rectangle rect = new Rectangle(X, Y, Width, Height);
return rect.IntersectsWith(new Rectangle(rectangleObject.X, rectangleObject.Y, rectangleObject.Width, rectangleObject.Height));
}
/// <summary>
/// 判断当前物体与一个矩形区域是否相交
/// </summary>
/// <param name="rect"></param>
/// <returns></returns>
public virtual bool IsIntersected(Rectangle rectangle)
{
Rectangle rect = new Rectangle(X, Y, Width, Height);
return rect.IntersectsWith(rectangle);
}
}
}
二、MapElement.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace SuperTankDemo
{
/// <summary>
/// 地图元素
/// </summary>
public class MapElement : RectangleObject
{
/// <summary>
/// 实例化地图元素
/// </summary>
/// <param name="image">位图资源</param>
/// <param name="x">起始X坐标</param>
/// <param name="y">起始Y坐标</param>
/// <param name="elementCategory">元素类型</param>
public MapElement(Image image, int x, int y, MapElementCategory elementCategory, int width = 0, int height = 0)
: base(image, x, y, width, height)
{
this.ElementCategory = elementCategory;
}
/// <summary>
/// 地图元素类型
/// </summary>
public MapElementCategory ElementCategory { get; set; }
}
}
三、MapElementCategory.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 地图元素类型【枚举】
/// 主要有:墙体、水域、草丛、钢铁墙等
/// </summary>
public enum MapElementCategory
{
/// <summary>
/// 墙体:无法移动通过。被子弹攻击到将消失
/// </summary>
Wall = 0,
/// <summary>
/// 水域:无法移动通过,但子弹可以穿过去
/// </summary>
Water = 1,
/// <summary>
/// 草丛:可以移动通过,子弹可以穿过去
/// </summary>
Grass = 2,
/// <summary>
/// 钢铁墙:无法移动通过。可以抵挡所有敌方坦克的子弹。我方坦克达到3级【吃三个星星】后,击中钢铁将消失,我方坦克低于三级将抵挡子弹
/// </summary>
Steel = 3,
/// <summary>
/// 象征,符号。鹰,Boss。玩家需要守护鹰不被击中
/// 子弹与鹰碰撞后,将游戏结束
/// </summary>
Symbol = 4
}
}
四、Tank.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 分为玩家坦克 和 敌方坦克两种
/// 是玩家坦克、敌方坦克的基类
/// </summary>
public class Tank : RectangleObject
{
public Tank(Image image, int tankIndex, int x, int y, int width = 60, int height = 60, int health = 1, int speed = 15, Direction direction = Direction.Up)
: base(image, x, y, width, height)
{
this.TankIndex = tankIndex;
this.Health = health;
this.Speed = speed;
this.Direction = direction;
}
/// <summary>
/// 坦克唯一编号:主要用于区分是否是当前坦克
/// </summary>
public int TankIndex { get; set; }
/// <summary>
/// 生命值
/// </summary>
public int Health { get; set; }
/// <summary>
/// 移动速度:速度越快,同一时间内 坦克移动的位置就越远。也就是说:X坐标或者Y坐标偏移较大
/// </summary>
public int Speed { get; set; }
/// <summary>
/// 方向:上、下、左、右
/// </summary>
public Direction Direction { get; set; }
/// <summary>
/// 玩家坦克 和 敌方坦克 是否可以向前移动
/// 玩家坦克 是手动控制,敌方坦克是自动
/// </summary>
/// <param name="MapWidth"></param>
/// <param name="MapHeight"></param>
/// <param name="mapElements"></param>
/// <param name="tanks"></param>
/// <returns></returns>
public bool IsAllowMove(int MapWidth, int MapHeight, List<MapElement> mapElements, List<Tank> tanks)
{
bool allowMove = true;
Rectangle rect = new Rectangle(0, 0, 0, 0);
switch (this.Direction)
{
//如果到达边界,直接返回false
case Direction.Up:
if (this.Y - this.Speed < 0)
{
return false;
}
rect = new Rectangle(this.X, this.Y - this.Speed, this.Width, this.Height);
break;
case Direction.Down:
if (this.Y + this.Speed > MapHeight - this.Height)
{
return false;
}
rect = new Rectangle(this.X, this.Y + this.Speed, this.Width, this.Height);
break;
case Direction.Left:
if (this.X - this.Speed < 0)
{
return false;
}
rect = new Rectangle(this.X - this.Speed, this.Y, this.Width, this.Height);
break;
case Direction.Right:
if (this.X + this.Speed > MapWidth - this.Width)
{
return false;
}
rect = new Rectangle(this.X + this.Speed, this.Y, this.Width, this.Height);
break;
}
//如果与墙体、钢铁、老鹰、水域碰撞【可以穿过草丛】
for (int i = 0; i < mapElements.Count; i++)
{
Rectangle rectElement = new Rectangle(mapElements[i].X, mapElements[i].Y, mapElements[i].Width, mapElements[i].Height);
if (mapElements[i].ElementCategory == MapElementCategory.Steel || mapElements[i].ElementCategory == MapElementCategory.Symbol
|| mapElements[i].ElementCategory == MapElementCategory.Wall || mapElements[i].ElementCategory == MapElementCategory.Water)
{
if (rect.IntersectsWith(rectElement))
{
return false;
}
}
}
//如果与坦克碰撞
for (int i = 0; i < tanks.Count; i++)
{
Rectangle rectElement = new Rectangle(tanks[i].X, tanks[i].Y, tanks[i].Width, tanks[i].Height);
if (this != tanks[i] && rect.IntersectsWith(rectElement))
{
return false;
}
}
return allowMove;
}
public override bool Equals(object obj)
{
if (!(obj is Tank))
return false;
return this.TankIndex == ((Tank)obj).TankIndex;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
/// <summary>
/// 操作符重载,比较两个坦克是否是同一个,即TankIndex相同
/// </summary>
/// <param name="tank1"></param>
/// <param name="tank2"></param>
/// <returns></returns>
public static bool operator ==(Tank tank1, Tank tank2)
{
if ((tank1 as object) == null)
return (tank2 as object) == null;//引用基类object的比较操作符
return tank1.TankIndex == tank2.TankIndex;
//return tank1.Equals(tank2);
}
/// <summary>
/// 操作符重载,比较两个坦克是否不是同一个,即TankIndex不同
/// </summary>
/// <param name="tank1"></param>
/// <param name="tank2"></param>
/// <returns></returns>
public static bool operator !=(Tank tank1, Tank tank2)
{
return !(tank1 == tank2);
}
}
}
五、PlayerTank.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 玩家坦克
/// </summary>
public class PlayerTank : Tank
{
public PlayerTank(Image image, int tankIndex, int x, int y, int width = 60, int height = 60, int health = 1, int speed = 15, Direction direction = Direction.Up, PlayerTankLevel tankLevel = PlayerTankLevel.Initial)
: base(image, tankIndex, x, y, width, height, health, speed, direction)
{
this.TankLevel = tankLevel;
}
/// <summary>
/// 玩家坦克等级
/// </summary>
public PlayerTankLevel TankLevel { get; set; }
/// <summary>
/// 当前道具:玩家坦克 有定时道具 或者 无敌状态 或者 为鹰增加钢铁墙道具等
/// </summary>
public Prop CurrentProp { get; set; }
/// <summary>
/// 玩家坦克移动
/// </summary>
public void Move(int MapWidth, int MapHeight, List<MapElement> mapElements, List<Tank> tanks, Prop prop = null)
{
//坦克是否可以向前移动,如果不能向前移动,尝试转换方向
//我方坦克在移动中是否碰撞道具,如果碰撞道具,道具将消失,我方坦克增加相应持续状态【生命值加强、火力加强、无敌等】
if (IsAllowMove(MapWidth, MapHeight, mapElements, tanks))
{
switch (this.Direction)
{
case Direction.Up:
this.Y = this.Y - this.Speed;
break;
case Direction.Down:
this.Y = this.Y + this.Speed;
break;
case Direction.Left:
this.X = this.X - this.Speed;
break;
case Direction.Right:
this.X = this.X + this.Speed;
break;
}
if (prop != null && this.IsIntersected(prop))
{
Prop propTemp = prop;
System.Windows.Forms.MessageBox.Show($"玩家坦克与道具【{prop.PropCategory}】碰撞,将产生相应的事件");
this.CurrentProp = propTemp;
prop = null;
}
}
else
{
System.Media.SystemSounds.Asterisk.Play();
}
}
/// <summary>
/// 坦克攻击:向玩家子弹列表增加数据
/// </summary>
public void Fire()
{
}
}
}
六、EnemyTank.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 敌方坦克
/// </summary>
public class EnemyTank : Tank
{
public EnemyTank(Image image, int tankIndex, int x, int y, int width = 60, int height = 60, int health = 1, int speed = 15, Direction direction = Direction.Down, EnemyTankCategory tankCategory = EnemyTankCategory.Normal, bool isDropProps = false)
: base(image, tankIndex, x, y, width, height, health, speed, direction)
{
this.TankCategory = tankCategory;
this.IsDropProps = isDropProps;
}
/// <summary>
/// 敌方坦克类型:快、慢、装甲
/// </summary>
public EnemyTankCategory TankCategory { get; set; }
/// <summary>
/// 是否掉落物品:当为true时,敌方坦克被玩家坦克的子弹击中,将随机产生一个道具。然后将该属性置为false
/// </summary>
public bool IsDropProps { get; set; }
}
}
七、PlayerTankLevel.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 我方【玩家】坦克等级:攻击速度和子弹个数
/// </summary>
public enum PlayerTankLevel
{
/// <summary>
/// 初始:攻击速度1.5秒发射一发子弹
/// </summary>
Initial = 0,
/// <summary>
/// 一星:攻击速度0.75秒发射一发子弹
/// </summary>
OneStar = 1,
/// <summary>
/// 二星:攻击速度0.75秒发射两发子弹
/// </summary>
TwoStar = 2,
/// <summary>
/// 三星:攻击速度0.75秒发射两发子弹,击中钢铁墙,钢铁墙将消失
/// </summary>
ThreeStar = 3
}
}
八、EnemyTankCategory.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 敌方坦克类型:普通、快速、装甲
/// </summary>
public enum EnemyTankCategory
{
/// <summary>
/// 普通坦克
/// </summary>
Normal = 1,
/// <summary>
/// 快速坦克:移动速度较快
/// </summary>
Quick = 2,
/// <summary>
/// 装甲坦克:生命值较多
/// </summary>
Armor = 3
}
}
九、Direction.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 方向:坦克的移动方向 以及 子弹的前进方向
/// </summary>
public enum Direction
{
/// <summary>
/// 上
/// </summary>
Up,
/// <summary>
/// 下
/// </summary>
Down,
/// <summary>
/// 左
/// </summary>
Left,
/// <summary>
/// 右
/// </summary>
Right
}
}
十、Bullet.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SuperTankDemo
{
/// <summary>
/// 子弹:有方向,分玩家子弹、敌方子弹
/// 以及是否可以消除墙体
/// </summary>
public class Bullet : RectangleObject
{
/// <summary>
/// 初始化子弹
/// </summary>
/// <param name="image"></param>
/// <param name="direction"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="speed"></param>
/// <param name="width"></param>
/// <param name="height"></param>
public Bullet(Image image, int bulletIndex, Direction direction, int x, int y, int speed, int width = 60, int height = 60, BulletCategory bulletCategory = BulletCategory.PlayerBullet, bool canEliminateSteel = false)
: base(image, x, y, width, height)
{
this.BulletIndex = bulletIndex;
this.Direction = direction;
this.Speed = speed;
this.BulletCategory = bulletCategory;
this.CanEliminateSteel = canEliminateSteel;
}
/// <summary>
/// 子弹的唯一索引
/// </summary>
public int BulletIndex { get; }
/// <summary>
/// 子弹的方向
/// </summary>
public Direction Direction { get; }
/// <summary>
/// 子弹的速度,可以认为是 坦克的攻击速度。速度越快,同一时间内 子弹移动的位置就越远。
/// 子弹的移动速度逻辑:因速度越大,相同时间内移动的距离越远。因此我们可以使用位移(距离、坐标)的大小来模拟表示
/// 比如每隔50ms,坐标的变化来表示速度的快慢即可。
/// </summary>
public int Speed { get; set; }
/// <summary>
/// 子弹类型:玩家子弹还是敌方子弹
/// </summary>
public BulletCategory BulletCategory { get; set; }
/// <summary>
/// 子弹是否可以消除钢铁墙:玩家坦克等级3星时可以击穿钢铁
/// </summary>
public bool CanEliminateSteel { get; set; }
/// <summary>
/// 所有子弹【玩家子弹 和敌方子弹的合集】与其他物体的碰撞
/// 注意,子弹与子弹的碰撞要递减处理
/// </summary>
/// <param name="mapElements"></param>
/// <param name="bullets">玩家子弹 和 敌方子弹</param>
/// <param name="enemyTanks"></param>
public static void BulletHit(List<MapElement> mapElements, List<Bullet> bullets, List<EnemyTank> enemyTanks, int MapWidth, int MapHeight, Form form)
{
/*
* 子弹在移动过程中一定会触发碰撞事件。子弹在移动过程中没有和其他物体碰撞,则最终会和地图边界碰撞
* 玩家子弹碰撞事件:子弹与地图元素【墙体、钢铁】的碰撞,子弹与敌方子弹的碰撞,子弹与敌方坦克碰撞
* 玩家子弹与【掉落道具的敌方坦克 碰撞时,将随机产生一个道具】
*
* 敌方子弹碰撞事件:子弹与地图元素【墙体、钢铁】的碰撞,子弹与玩家子弹的碰撞,子弹与玩家坦克碰撞
*/
for (int bulletIndex = 0; bulletIndex < bullets.Count; bulletIndex++)
{
Bullet bulletPlayer = bullets[bulletIndex];
switch (bulletPlayer.Direction)
{
case Direction.Up:
bulletPlayer.Y = bulletPlayer.Y - bulletPlayer.Speed;
break;
case Direction.Down:
bulletPlayer.Y = bulletPlayer.Y + bulletPlayer.Speed;
break;
case Direction.Left:
bulletPlayer.X = bulletPlayer.X - bulletPlayer.Speed;
break;
case Direction.Right:
bulletPlayer.X = bulletPlayer.X + bulletPlayer.Speed;
break;
}
if (bulletPlayer.X <= 0 || bulletPlayer.X >= MapWidth || bulletPlayer.Y <= 0 || bulletPlayer.Y >= MapHeight)
{
//子弹到达边界 或者 触发碰撞事件,子弹从集合中清除。播放爆炸音效。显示爆炸图片");
Blast(form, bulletPlayer);
//赋值为null,用于清除集合中值为null的元素
bulletIndex--;
bullets.RemoveAt(bulletIndex);
}
List<MapElement> listRemoves = new List<MapElement>();
//子弹与墙体、钢铁碰撞
for (int wallIndex = 0; wallIndex < mapElements.Count; wallIndex++)
{
MapElement mapElement = mapElements[wallIndex];
if (mapElement.ElementCategory == MapElementCategory.Wall && bulletPlayer.IsIntersected(mapElement))
{
//如果子弹与墙体的矩形 相交。则认为触发 碰撞。子弹可以消失 多个窗体
listRemoves.Add(mapElement);
}
else if (mapElement.ElementCategory == MapElementCategory.Steel && bulletPlayer.IsIntersected(mapElement))
{
if (bulletPlayer.CanEliminateSteel)
{
//如果当前子弹可以 清除钢铁墙
listRemoves.Add(mapElement);
}
Blast(form, bulletPlayer);
}
else if (mapElement.ElementCategory == MapElementCategory.Symbol && bulletPlayer.IsIntersected(mapElement))
{
//子弹与 老鹰碰撞,则游戏结束
MessageBox.Show("游戏结束Game Over");
Blast(form, bulletPlayer);
}
}
//清除相交的所有墙体
for (int removeIndex = 0; removeIndex < listRemoves.Count; removeIndex++)
{
//如果子弹与墙体的矩形 相交。则认为触发 碰撞。子弹可以消失 多个窗体
mapElements.Remove(listRemoves[removeIndex]);
if (removeIndex == 0)
{
//只清除一个 子弹
Blast(form, bulletPlayer);
//bulletPlayer = null;
}
}
//移除临时变量
listRemoves.Clear();
//子弹与敌方坦克的碰撞
for (int tankIndex = 0; tankIndex < enemyTanks.Count; tankIndex++)
{
if (bulletPlayer.IsIntersected(enemyTanks[tankIndex]))
{
if (enemyTanks[tankIndex].IsDropProps)
{
//如果掉落物品
Prop prop = new Prop(Properties.Resources.GEMSTAR, new Random().Next(0, MapWidth - 30), new Random().Next(0, MapHeight - 30), PropCategory.Star, 30, 30);
MessageBox.Show($"随机生成一个道具【{prop.PropCategory}】");
}
Blast(form, bulletPlayer);
//敌方坦克和子弹都消失:这里应该考虑敌方坦克的生命值减少1.变成0时爆炸死亡
//如果敌方坦克可以掉落道具
enemyTanks.RemoveAt(tankIndex);
//bulletPlayer = null;
break;
}
}
//子弹与敌方子弹的碰撞
for (int i = bulletIndex + 1; i < bullets.Count; i++)
{
if (((bullets[i].BulletCategory == BulletCategory.EnemyBullet && bulletPlayer.BulletCategory == BulletCategory.PlayerBullet)
|| (bullets[i].BulletCategory == BulletCategory.PlayerBullet && bulletPlayer.BulletCategory == BulletCategory.EnemyBullet))
&& bulletPlayer.IsIntersected(bullets[i]))
{
bullets.RemoveAt(i);
bulletIndex--;
break;
}
}
bullets.RemoveAt(bulletIndex);
bulletIndex--;
}
}
public static void EnemyBulletHit(Bullet bulletEnemy, List<MapElement> mapElements, List<Bullet> playerBullets, List<PlayerTank> playerTanks)
{
/*
* 敌方子弹碰撞事件:子弹与地图元素【墙体、钢铁】的碰撞,子弹与玩家子弹的碰撞,子弹与玩家坦克碰撞
*/
}
/// <summary>
/// 爆炸效果:子弹碰撞到坦克、墙体、钢铁墙、老鹰【子弹分我方子弹 和 敌方子弹】
/// </summary>
public static void Blast(Form form, Bullet bullet)
{
//爆炸音效
System.Media.SoundPlayer sp = new System.Media.SoundPlayer(Properties.Resources.blast);
sp.Play();
//爆炸动画
Task taskBlast = Task.Run(() =>
{
for (int index = 0; index < 25; index++)
{
Image image = Properties.Resources.EXP1;
if (index >= 5)
{
image = Properties.Resources.EXP2;
}
else if (index >= 10)
{
image = Properties.Resources.EXP3;
}
else if (index >= 15)
{
image = Properties.Resources.EXP4;
}
else if (index >= 20)
{
image = Properties.Resources.EXP5;
}
form.CreateGraphics().DrawImage(image, bullet.X, bullet.Y);
}
});
Task.WaitAll(taskBlast);
}
}
}
十一、BulletCategory.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 子弹类型:我方【玩家】子弹、敌方子弹
/// </summary>
public enum BulletCategory
{
/// <summary>
/// 我方【玩家】子弹
/// </summary>
PlayerBullet,
/// <summary>
/// 敌方子弹
/// </summary>
EnemyBullet
}
}
十二、Prop.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 道具:主要有 定时、炸弹、无敌、钢铁、升级星星等。
/// 玩家子弹 击中 可以掉落道具的敌方坦克,可以产生一个道具。
/// 为了减少bug,同一时刻地图上最多允许只有一个道具【上次的道具消失 或者 被新的道具覆盖】。
/// 我方坦克移动时,碰撞到道具时,道具消失,同时将触发相应的事件
/// </summary>
public class Prop : RectangleObject
{
public Prop(Image image, int x, int y, PropCategory propCategory, int width = 0, int height = 0)
: base(image, x, y, width, height)
{
this.PropCategory = propCategory;
}
/// <summary>
/// 道具类别
/// </summary>
public PropCategory PropCategory { get; }
}
}
十三、PropCategory.cs 源程序如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SuperTankDemo
{
/// <summary>
/// 道具类别,不同的道具将触发不同的事件。主要有:星星,定时器,炸弹,箭头等
/// </summary>
public enum PropCategory
{
/// <summary>
/// 升星:一级星增加攻击速度【子弹的移动速度轨迹变快】 二级将攻击两次、三级可以击穿钢铁墙
/// </summary>
Star = 1,
/// <summary>
/// 定时器。所有敌方坦克将静止,无法移动和攻击。持续15秒
/// </summary>
Timer = 2,
/// <summary>
/// 炸弹。当前所有敌方坦克 将爆炸消失
/// </summary>
Bomb = 3,
/// <summary>
/// 箭头,我方坦克碰撞后,老鹰四方将产生钢铁墙,也就是说无敌状态。持续15秒
/// </summary>
Arrow = 4,
/// <summary>
/// 帽子:我方坦克碰撞后 将无敌,持续15秒
/// </summary>
Hat = 5,
/// <summary>
/// 坦克礼物,复活次数加1
/// </summary>
TankGift = 6,
/// <summary>
/// 我方生命值增加1,可以抵挡一次攻击伤害
/// </summary>
Apple = 7,
/// <summary>
/// 我方坦克直接到最高级3级,相当于3个星星【Super Weapon:超级武器】
/// </summary>
Blow = 8
}
}