ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#坦克大战流程设计与源代码(1):基本对象类规划

2020-12-05 17:57:41  阅读:161  来源: 互联网

标签:坦克 C# 流程 子弹 System int using 源代码 public


小游戏坦克大战,看似是一个很小的程序。

但实际使用做起来,发现需要用到多种功能:

多线程并发与同步,事件触发,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
    }
}
 

PS:目前只定义和相关的类与属性,下一步将完善订阅事件。比如子弹与窗体的碰撞,玩家子弹与敌方坦克的碰撞,玩家坦克与道具的碰撞事件等。

标签:坦克,C#,流程,子弹,System,int,using,源代码,public
来源: https://blog.csdn.net/ylq1045/article/details/109452959

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有