zoukankan      html  css  js  c++  java
  • 设计模式(5)

    这篇日志我们来介绍设计模式的一大原则:单一职责原则

    单一职责原则(SRP):就一个类而言,应该仅有一个引起他变化的原因

    现在来设计俄罗斯方块游戏、要是我们完成这个小游戏,我们的思路是什么?我们一般会这样考虑,首先他方块下落的原理是画四个小方块,擦掉,然后再在下一行画四个方块。不断的绘出和擦掉就形成了动画,所以应该要有画和擦方块的代码,然后左右键实现左移和右移,下键实现加速,上键实现旋转,这其实都应该是函数,当然左右移动需要考虑碰撞问题,下移需要考虑堆积和消层问题。

    步骤如下:

    1、先建立一个窗体、

    2、加上一个用于游戏框架的控件,比如Panel或者picturebox,一个按钮button来控制“开始”

    3、在放一个timer控件用于分时动画的编程,实现绘出和擦出方块,并作出堆积和消层判断

    4、编写控件的键盘事件

    如果咱们的思路会是在这各种事件怎么编写,不会去考虑分类的事情。

    这样的话,我们面向过程开发已经根深蒂固了,咱会把所有的代码都写在form1.cs这个类中,这样的代码谈何耦合度、复用性。咱重新回顾这个程序,如果现在咱写的手机版的俄罗斯方块程序,然后在windowsCE上运行的程序,他们可以安装.NET框架的精简版,运行c#语言编写的应用程序,但PC上的普通的windowfrom界面的程序不能使用,那咱写的程序该怎么用?

    或许会通过copy过去,然后在做些改进吧。

    但是这里面有一些是始终没有变化的,像下落、旋转、碰撞判断、移动、堆积等游戏逻辑

    如果一个类承担的职责过多的话,就等于把这些职责耦合在一起了,一个职责的变化可能会削弱或者抑制这个类完成其他职责的功能。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。事实上,我们完全可以找出可以找出那些事界面,那些是游戏逻辑,然后进行分离。

    在游戏中,方块的可以动的是游戏区域,可以设计为一个二维整型数组用来表示坐标,宽 10、高 20,比如:int[,] arraysquare=new int[10,20];。那么整个方块的移动其实就是数组的下标变化,比如原方块在arraysquare[3,5]上,则下移时变成了arraysquare[3,6],若果下移同时还按了左键,则是arraySquare[2,6]。每个数组的值就是是否存在方块的标志,存在为1、不存在缺省为0。咱判断是否能左移,就是判断arrySquare[x,y]中的x-1是否小于0,否则就是撞墙了,或者arrySquare[x-1,y]是否等于1,否则就说明左侧有堆积的方块,所谓堆积,不过是判断arrySquare[x,y+1]是否等于1的过程,如果是,则将自己arrySquare[x,y]的值改1。那么消层,其实就是arrySquare[x,y]中循环x有0到9,判断arrySquare[x,y]是否等于1,是则此行数据清零,并将其上方的数组值遍历下移一位。

    所谓游戏逻辑,不过就是数组的每一项值的变化的问题,下落、旋转、碰撞判断,移动、堆积这些都是做数组具体项的值的变化,而界面表示逻辑,不过是根据数组的数据进行绘出和擦除、或者根据键盘命令调用数组相应方法的改变,因此,至少应该考虑经此程序分为两个类,一个游戏逻辑的类、一个是winform窗体的类,当有一天要改变界面,或者换界面时,不过是窗体类的变化,和游戏逻辑无关,以此达到复用的目的。

    当然、软件设计真正要做的许多内容,就是发现职责并把那些职责互相分离。其实要去判断是否应该分离出来类了,也不能,那就是如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责,就应该考虑类的职责分离,界面的变化是和游戏本身没有关系的,界面是很容易变化的,而游戏逻辑是不太容易变化的。

  • 相关阅读:
    防抖函数
    锁屏功能
    配置编译环境和线上环境之间的切换
    vue-router中的滚动行为
    axios的再次封装
    Anaconda 镜像配置
    Python 包管理工具 pip 与 conda
    Anaconda 安装与卸载
    VS Code 配置和使用
    解决 VS Code 无法使用Ctrl+C等快捷键
  • 原文地址:https://www.cnblogs.com/zhijianliutang/p/2250617.html
Copyright © 2011-2022 走看看