zoukankan      html  css  js  c++  java
  • 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/poplanchong123/p/3595719.html
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
    正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!
  • 相关阅读:
    基于PHP的正则表达式
    学习笔记---C/C++语法
    Stack的c实现
    回忆过去的两年
    学习笔记---计算机组成
    The shortest path---hdu2224 && Tour---poj2677(旅行商问题)
    Ubantu Linux 环境下编译c++程序
    Quoit Design---hdu1007(最近点对问题 分治法)
    Wrestling Match---hdu5971(2016CCPC大连 染色法判断是否是二分图)
    异或密码---hdu5968(CCPC合肥,二分)
  • 原文地址:https://www.cnblogs.com/ice-river/p/3614085.html
Copyright © 2011-2022 走看看