• Winform打砖块游戏制作step by step第5节---重构代码,利用继承多态


    一 引子

    为了让更多的编程初学者,轻松愉快地掌握面向对象的思考方法,对象继承和多态的妙用,故推出此系列随笔,还望大家多多支持。

    二 本节内容---重构代码,利用继承多态

    1. 主界面截图如下:

    2. 根据完成挡板和小球类的编写后,会发现挡板类和小球类代码中有非常类似的属性和方法,进一步思考,后续还需画砖块和子弹等图形,即要构建砖块和子弹类的同时还会有代码的重复,这样的现象是不好的程序编码,所以要重构代码。重构方法是:将挡板类和小球类的属性和方法提取成一个父类,挡板类和小球类都继承这一父类。

    父类的定义代码如下:

        public class GameObject
        {
            //坐标
            public int XPos { get; set; }
            public int YPos { get; set; }
    
            //速度和方向控制
            public int SpeedX { get; set; }
            public int SpeedY { get; set; }
    
            //对象载体
            public Rectangle Rect { get; set; }
            public bool m_bIsDel = false;
    
            public virtual void Draw(Graphics g)
            {
    
            }
    
            public virtual void Run()
            {
               
            }
        }

         对于GameObject基类来说,因为其为抽象的基类对象,无法提供Draw和Run方法的实现,故此将这两个方法定义为虚方法,由具体的派生对象进行改写,提供自身的实现。

    三 小球类代码改写

    变更后的小球类代码如下(挡板类的改写与小球类的改写相似):

        public class Ball : GameObject
        {
            /// <summary>
            /// 初始化小球位置和偏移值
            /// </summary>
            public Ball(int x, int y, int speedX, int speedY)
            {
                this.XPos = x;
                this.YPos = y;
                this.SpeedX = speedX;
                this.SpeedY = speedY;
            }
    
            public override void Draw(Graphics g)
            {
                using (SolidBrush sbrush = new SolidBrush(Color.Snow))
                {
                    Rect = new Rectangle(XPos, YPos, 20, 20);
                    g.DrawEllipse(new Pen(Color.Gray), Rect);
                    g.FillEllipse(sbrush, Rect);
                }
                g.Dispose();
            }
    
    
            public override void Run()
            {
                XPos = XPos + SpeedX;
                YPos = YPos - SpeedY;
                if (XPos <= 0)
                    SpeedX = (new Random().Next(3, 5));
                if (XPos >= 378)
                    SpeedX = -(new Random().Next(3, 5));
                if (YPos <= 100)
                    SpeedY = -(new Random().Next(3, 8));
                if (YPos >= 580)
                    SpeedY += (new Random().Next(3, 8));
            }
    
        }

    四 主界面代码---利用多态

    主界面修改如下:

    首先定义一个list泛型集合对象:  List<GameObject> m_lstGameObject = new List<GameObject>();

    将小球和挡板对象在BrickGame_Load事件中添加到m_lstGameObject中,m_lstGameObject.Add(m_Ball);    

                                      m_lstGameObject.Add(m_board);

    BrickGame_Paint事件处理函数中,遍历lstGameObject集合,对取出的每一个对象调用Draw方法,根据多态性,会调用到各个派生类对象的Draw方法,这种办法的优点是,无论以后再加入任何游戏对象,我们只需让该对象继承GameObject对象,然后实现其特有的Draw方法及Run方法,而这里的代码无需再做任何改动。代码如下:

            private void BrickGame_Paint(object sender, PaintEventArgs e)
            {
                Graphics g = e.Graphics;
    
                foreach (GameObject go in m_lstGameObject)
                {
                    go.Draw(g);
                }  
            }

    五 代码下载

    本节代码下载

    作者:不懒虫  指导老师:宋波
    老师博客:http://www.cnblogs.com/ice-river/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
    正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!
  • 相关阅读:
    卸载cuda,以及N卡驱动
    ubuntu 16.04 从gcc 5.4 安装gcc 5.3.0
    Check failed: status == CUBLAS_STATUS_SUCCESS (13 vs. 0) CUBLAS_STATUS_EXECUTION_FAILED
    ubuntu16.04 caffe cuda9.1 segnet nvidia gpu安装注意的点
    ubuntu16.04安装docker
    进程管理
    Dev TextEdit 只输入数字
    dev gridcontrol添加右键菜单
    WinForm rdlc 报表自定义datatable数据源
    DevExpress GridControl使用方法总结2 属性说明
  • 原文地址:https://www.cnblogs.com/poplanchong123/p/3595719.html
Copyright © 2020-2023  润新知