C#游戏《坦克大战》--坦克

1.坦克相关信息

这里的各种类型,使用struct而不是enum,避免后面强制转换。

    //子弹信息
    public struct t_bulletinfo
    {
        public int idx;//链表中的顺序号
        public int dir;//当前方向
        public t_bulletinfo(int i, int d)
        {
            this.idx = i;
            this.dir = d;
        }
    }
   //坦克类型
    public struct t_type
    {
        public const int PLAYER = 0;    //玩家车
        public const int COMMOM = 1;    //普通车
        public const int FAST = 2;      //快车
        public const int SLOW = 3;      //慢车
        public const int ARMORED = 4;   //装甲车
    }

    //坦克行动方向
    public struct t_dir
    {
        public const int DIR_UP = 0;
        public const int DIR_DOWN = 1;
        public const int DIR_LEFT = 2;
        public const int DIR_RIGHT = 3;
        public const int DIR_STAY = 4;//不动
    }
    //公共参数
    public struct t_commpar
    {
        public const int TANKALIVECNTMAX = 3;  //爆炸时间
        public const int TANKNUMMAX = 20;      //坦克最大数目
        public const int BULLETNUMMAX = 20;    //单量坦克的最大子弹显示子弹数
        public const int PIXMIN = 2;  //最小行动距离

        public const int TANKSIZEX = 64;//坦克长度
        public const int TANKSIZEY = 64;//坦克宽度
        public const int BULLETSIZEX = 32;//子弹长度
        public const int BULLETSIZEY = 32;//子弹宽度

        public static int MAPSIZEX = 896; //默认地图大小
        public static int MAPSIZEY = 896; //默认地图大小

        public static Point playerStartLocation ;//玩家坦克的开始位置
    }

2.坦克类

设计框架是,很纠结一点:碰撞检测函数,应该写在主程序类,还是写在坦克类,作为坦克的成员函数?后来“方便”打败其他一切,毕竟生成一个坦克实例,也就生成对应成员函数,然后直接加到委托里面,一次调用,太省事了,避免主程序一个个轮询。

车体:4个方向使用不同 的检测函数

        /// <summary>
        /// 检测是否顺通[分别4个方向]
        /// </summary>
        /// <returns>false:阻碍;true:顺通</returns>
        bool carDetectUP()
        {

            this.tankSpeed = this.tankSpeedbk;//恢复速度
            //检测与别的车是否碰撞
            foreach (var i in map.tkinfos)
            {
                if (i.uid != uuid)
                {
                    if (location.Y <= (i.Y + t_commpar.TANKSIZEY) && location.Y >= i.Y && location.X + t_commpar.TANKSIZEX > i.X && location.X < i.X + t_commpar.TANKSIZEX)
                    {
                        return false;
                    }
                }
            }
            //检测与地图元素是否碰撞
            int x1 = location.X + (t_commpar.PIXMIN * tankSpeed) / 2 + c_map.OFFET;
            int y1 = location.Y - (t_commpar.PIXMIN * tankSpeed) / 2 + c_map.OFFET;
            int x2 = location.X + t_commpar.TANKSIZEX - (t_commpar.PIXMIN * tankSpeed) / 2 + c_map.OFFET;
            int y2 = location.Y - (t_commpar.PIXMIN * tankSpeed) / 2 + c_map.OFFET;
            if (x1 < 0 + c_map.OFFET || x1 >= t_commpar.MAPSIZEX + c_map.OFFET || x2 < 0 + c_map.OFFET || x2 >= t_commpar.MAPSIZEX + c_map.OFFET || y1 < 0 + c_map.OFFET || y1 >= t_commpar.MAPSIZEY + c_map.OFFET || y2 < 0 + c_map.OFFET || y2 >= t_commpar.MAPSIZEY + c_map.OFFET)
            {
                return false;
            }
            else
            {

                byte t1 = map.mask[x1, y1];
                byte t2 = map.mask[x2, y2];
                //根据地图元素处理
                return docarForMap(t1, t2);
            }
        }

子弹:4个方向使用不同 的检测函数

        /// <summary>
        /// 子弹检测
        /// </summary>
        /// <param name="pt">子弹位置</param>
        /// <param name="xrt">需要消灭的位置</param>
        /// <param name="fill">消灭方式(弃用)</param>
        /// <returns>本子弹是否需要销毁</returns>
        bool bulletDetectUP(Point pt, ref Rectangle xrt, ref byte fill)
        {
            this.bulletSpeed = this.bulletSpeedbk;//恢复子弹速度
            //检测是否击中坦克车子
            foreach (var i in map.tkinfos)
            {
                if (i.uid != uuid)
                    if (new Rectangle(pt, new Size(t_commpar.BULLETSIZEX, t_commpar.BULLETSIZEY)).IntersectsWith(new Rectangle(i.X, i.Y, t_commpar.TANKSIZEX, t_commpar.TANKSIZEY)))
                    {
                        bingo = i.uid;   //记录击中的目标
                        return false;
                    }
            }
            //检测地图元素
            {
                int x1 = pt.X + c_map.OFFET;
                int y1 = pt.Y + c_map.OFFET;
                int x2 = pt.X + t_commpar.BULLETSIZEX + c_map.OFFET;
                int y2 = pt.Y + c_map.OFFET;
                if (x1 < 0 + c_map.OFFET || x1 >= t_commpar.MAPSIZEX + c_map.OFFET || x2 < 0 + c_map.OFFET || x2 >= t_commpar.MAPSIZEX + c_map.OFFET || y1 < 0 + c_map.OFFET || y1 >= t_commpar.MAPSIZEY + c_map.OFFET || y2 < 0 + c_map.OFFET || y2 >= t_commpar.MAPSIZEY + c_map.OFFET)
                {
                    return false;
                }
                //获取地图元素号
                byte t1 = map.mask[x1, y1];
                byte t2 = map.mask[x2, y2];

                if (t1 == 0 && t2 == 0) return true;
                //获取地图元素生命值
                int hp1 = map.mapHps[pt.X / t_commpar.TANKSIZEX, pt.Y / t_commpar.TANKSIZEY];
                int hp2 = map.mapHps[(pt.X + t_commpar.BULLETSIZEX) / t_commpar.TANKSIZEX, pt.Y / t_commpar.TANKSIZEY];
                //获取地图元素类型
                tlandformType lft1 = map.tlandforms[t1];
                tlandformType lft2 = map.tlandforms[t2];
                //处理不同地图元素
                if (lft1.bulletpass && lft2.bulletpass)
                {
                    this.bulletSpeed = this.bulletSpeedbk + (int)(this.bulletSpeedbk * (lft1.bulletspeed + lft2.bulletspeed) / 200.0);
                    if (this.bulletSpeed < 4) this.bulletSpeed = 4;
                }
                else
                {
                    if (!lft1.bulletpass && lft1.hp > 0)
                    {
                        if (hp1 > 1) { map.mapHps[pt.X / t_commpar.TANKSIZEX, pt.Y / t_commpar.TANKSIZEY]--; }
                        else
                        {
                            xrt = new Rectangle(pt.X - pt.X % t_commpar.TANKSIZEX, pt.Y - pt.Y % t_commpar.TANKSIZEY, t_commpar.TANKSIZEX, t_commpar.TANKSIZEY);
                            clearmask(xrt);
                            fill = 1;
                        }
                    }
                    else
                        if (!lft2.bulletpass && lft2.hp > 0)
                        {
                            if (hp2 > 1) { map.mapHps[(pt.X + t_commpar.BULLETSIZEX) / t_commpar.TANKSIZEX, pt.Y / t_commpar.TANKSIZEY]--; }
                            else
                            {
                                xrt = new Rectangle(pt.X - pt.X % t_commpar.TANKSIZEX + t_commpar.TANKSIZEX, pt.Y - pt.Y % t_commpar.TANKSIZEY, t_commpar.TANKSIZEX, t_commpar.TANKSIZEY);
                                clearmask(xrt);  //
                                fill = 1;
                            }
                        }
                    return false;
                }
            }


            return true;
        }

代码太长,需要的朋友可以下载。

4.效果

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值