C#坦克大战流程设计与源代码(1):基本对象类规划
小游戏坦克大战,看似是一个很小的程序。
但实际使用做起来,发现需要用到多种功能:
多线程并发与同步,事件触发,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
///
/// 【抽象类】矩形物体:所有的坦克,地图元素【墙、钢铁、草丛】,子弹,道具都是由一个填充图片的矩形构成
/// 该类是所有地图资源的基类,主要用于判断两个地图资源是否碰撞(相交)
///
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;
///
/// 图片资源,一般是位图资源Bitmap
///
public Image Image { get; set; }
///
/// 起始X坐标
///
public int X { get; set; }
///
/// 起始Y坐标
///
public int Y { get; set; }
///
/// 宽度
///
public int Width { get; set; }
///
/// 高度
///
public int Height { get; set; }
///
/// 判断两个物体是否是相交的,
/// 比如 子弹与敌方坦克是否碰撞,玩家坦克与道具是否碰撞快连快连,子弹与墙体进行碰撞等
///
///
///
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));
///
/// 判断当前物体与一个矩形区域是否相交
///
///
///
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
///
/// 地图元素
///
public class MapElement : RectangleObject
///
/// 实例化地图元素
///
///
位图资源
///
起始X坐标
///
起始Y坐标
///
元素类型
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;
///
/// 地图元素类型
///
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
///
/// 地图元素类型【枚举】
/// 主要有:墙体、水域、草丛、钢铁墙等
///
public enum MapElementCategory
///
/// 墙体:无法移动通过。被子弹攻击到将消失
///
Wall = 0,
///
/// 水域:无法移动通过,但子弹可以穿过去
///
Water = 1,
///
/// 草丛:可以移动通过,子弹可以穿过去
///
Grass = 2,
///
/// 钢铁墙:无法移动通过。可以抵挡所有敌方坦克的子弹。我方坦克达到3级【吃三个星星】后,击中钢铁将消失,我方坦克低于三级将抵挡子弹
///
Steel = 3,
///
/// 象征,符号。鹰快连,Boss。玩家需要守护鹰不被击中
/// 子弹与鹰碰撞后,将游戏结束
///
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
///
/// 分为玩家坦克 和 敌方坦克两种
/// 是玩家坦克、敌方坦克的基类
///
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;
///
/// 坦克唯一编号:主要用于区分是否是当前坦克
///
public int TankIndex { get; set; }
///
/// 生命值
///
public int Health { get; set; }
///
/// 移动速度:速度越快,同一时间内 坦克移动的位置就越远。也就是说:X坐标或者Y坐标偏移较大
///
public int Speed { get; set; }
///
/// 方向:上、下、左、右
///
public Direction Direction { get; set; }
///
/// 玩家坦克 和 敌方坦克 是否可以向前移动
/// 玩家坦克 是手动控制,敌方坦克是自动
///
///
///
///
///
///

