设计模式-大话设计模式总结->6大设计原则
点评
在6个设计模式中,我认为单一职责和合成复用,我认为是最基础的,但却是最有用的;同时也是程序设计初学者最容易出问题的设计的两个设计原则. 对此我的经验总结如下:
1.单一职责,告诉我们类的功能要单一,所以每个类存在自己的边界,必须分清楚各个类的功能划分,事件中可以一步一步来,化繁为简,逐步求精,当然也需要把握类的颗粒度。对此我的编程经验总结是:
a.对于某些实体类,根据现实世界映射到类,往往可以得到一个直观的类划分。 b.先划分一个初步的功能结构,讲究够用就行,等到需求要在拓展,再整理划分。 c.“奥卡姆剃刀”-当你发现以上两条经验得出的类不是那个简单,明了,是否是你的类不够简单,可以在划分。2.合成复用原则 ,我认为我们要成分的理解类之间的几种关系,从强到弱分别是:依赖关系,关联关系,聚集关系,组成关系。然而初学面向对象的同学可能总是在继承中不能自拔,一旦出现某种设计,首先使用继承,这是不对的。应该综合实际情况,而且组合要优先于继承,好拓展啊!
经验总结
a.认清事物之间的关系,可以画几个草图,问问自己他们是 is 关系,还是has关系。 b.当继承的子类越来越多,子类之间接近以乘数形式增加,可以想象类是否可分成两个或多个有关系的类,而不是继承。游戏优化基本性能指标以及说明
cpu:
通常对于游戏性能最直观的感受就是流畅性,表示流畅性最直接的指标就是帧率。不同种游戏类型对于帧率的要求并不一致,比如即时战斗的动作类游戏对于帧率更高的要求。为了打成对应的帧率,需要将CPU耗时控制住一定的数值范围内,对于30帧,总耗时需要控制在33ms以下,对应的模块也需要有对应的耗时范围,如下表所示,不过不同的游戏类型会有所差异。对于60帧或者更高帧率,依次换算对于数值即可。
内存:
在我们了解了内存相关的各项参数的含义之后,知道了避免游戏闪退的重点在于控制PSS内存峰值。而PSS内存的大头又在于Reserved Total中的资源内存和Mono堆内存。对于使用Lua的项目来说,还应关注Lua内存。
PSS内存峰值控制在硬件总内存的0.5-0.6倍以下的时候,闪退风险才较低。
而对于大多数项目而言,PSS内存大约高于Reserved Total 200MB-300MB左右,故2G设备的Reserved Total应控制在700MB以下、3G设备则控制在1G以下。
渲染:
随着游戏对画质效果的要求越来越高,越来越多的项目遇到的性能瓶颈会来自于GPU的压力,GPU的压力会受到帧率,分辨率,三角形面片数,后处理,Shader复杂度,Overdraw等多方面的影响,因此我们对于不同分档的机型需要做一些对应的调整,在不同档位的机型上要做较为细致的区分,从而达到越高端的机型画质表现越好,而在低端机型上又能保证一定的流畅性。下表中可以当做一个模板,对于不同的游戏类型的需求可以再进一步调整,其中绿色的数值如果能达到的话会更优。
算法-堆排序-最小堆
堆排序算法复杂度为【O(nlgn)】,分最大堆排序和最小堆排序:最大堆定义为所有父节点比左右子节点大。反之亦反,就是最小堆了!
这里我用最小堆来阐述算法。首先需要了解下完全二叉数结构,可以把一个数组看出一个完全二叉树。数组第1个元素看做为根节点,
可定义:
1、 左子树Left(i) = i * 2
2、 右子树Right(i) = i * 2 + 1
3、 父节点Parent(i) = i / 2
关键的子程序:
a、最小堆操作:堆下降,递归使得父节点小于自己的两个子节点
b、建堆操作(循环调用最小堆操作,获得数组a中n个数据的最小值)
算法思想主要分为2个步骤:
(1)构建堆,使得a[0](第一个数为最小值)
(2)交换a[0]<=>a[n-1](a[n-1] 不计入堆中,只有a[0]是不满足最小堆的,其他元素都不变)
(3)a[0]执行最小堆操作,回到(2)步骤直到数组长度为0
*C#的数组是从0开始的,二叉树映射数组是从1开始的。于是所有访问数组的时候都-1
1 | public static class SortingSupport |
算法-快速排序
关于排序算法,不得不说排序算法。排序算法被认为是冒泡算法的优化,以优异的平均算法复杂度【O(nlgn)】而著名。
算法思想主要分为2个步骤:
(1)划分数组a[p..r]为两个子数组a[p,i-1],a[i+1,r],使得a[p,i-1]中的数都小于等于a[i],a[i+1,r]中的数都大于等于a[i]
(2)递归对a[p,i-1],a[i+1,r]分别排序
*算法核心是如何分割为比基准数小的数组和比基准数大的数组,对应一下Partition方法
下面是代码部分:
1 | public static class SortingSupport |
UGUI事件系统精要(一)-事件处理流程
EventSystem作为控制类操作BaseInput,BaseRaycaster
BaseInput 相当于一个unity Input 和 UGUI BaseInputModule 的媒介类,BaseInputModule只跟BaseInput交互。
StandaloneInputModule->PointerInputModule,TouchInputModule->PointerInputModule,PointerInputModule->BaseInputModule
EventSystem 调用 BaseInputModule.Process() 处理来自unity的所有功能
RaycasterManager静态类管理所有的GraphicRaycaster,BaseRaycaster 激活是注册自己到RaycasterManager
GraphicRaycaster -> BaseRaycaster,Physics2DRaycaster->PhysicsRaycaster->BaseRaycaster
BaseRaycaster的关键,Raycast方法获得当前节点下Canvas的所有Graphic,并且进行检测触发排序(最终是Graphic.Raycast())。
最总EventSystem.RaycastComparer方法比较,排序获得第一个graphic作为pointerCurrentRaycast。