序章:

  这是"游戏设计进阶技巧篇"内容,游戏中不使用如下技巧也可以正常运行,但是有了它以后可以增加项目的可读性,使功能”模块化“,”可视化“,”装逼化“(慢慢的恶意>,>)。

  游戏设计进阶技巧篇内容整体包含:

  1. PureMvc框架
  2. 设计模式
  3. 数据结构 & 算法

  框架:这部分当然就是我下面要讲的PureMVC框架(C#)了,它总体来说是一种消息传递机制思想,通过反射形式实现的。

  设计模式:抽象工厂 AB对象池(详情见“对象池篇”)

  数据结构与算法:最大堆,顺序表,链表,循环队列

  简而言之:框架是大智慧,用来对软件设计进行分工;设计模式是小技巧,对具体问题提出解决方案,提高代码复用度,降低耦合;数据结构和算法是工具,无形中支撑起整个游戏。

  学了这些内容你就不能算是一个小白了!咋个也可以算个初级程序员了吧!!

正文:


MVC:

  全名“Model View Controller” 模型_视图_控制器 的缩写,一种软件的典范,将逻辑数据界面分离的代码组织方法。好!反正很牛B就对了!

优点:

  1.耦合低,模块化

  2.代码复用度高 (这个我倒没觉得有啥特别感想!)

  3.部署快

  4.利于多人项目合作

  5.可维护度,可读性高

缺点:

  1.理解耗时 反射方面虽然用的不多,但是我也不怎么用反射所以能看懂但不推荐大量使用反射。

  2.不利于中小项目?这尼玛我就更不同意了,我一个人写项目都喜欢MVC!

  3. 由于其设计的关系,在添加一个消息时,需要“注册”“删除”“关心”“处理”,使用起来会比较麻烦,没有传统模式来的简单直接。

PureMVC 官网结构图:

  

这张图,我能看出来的仅仅是下列几点

  1. Facade 外观模式 ,与“游戏业务逻辑”所有交互都通过它走,它包含了Proxy(M),Mediator(V),Controller(C)3个实例(单例)。

  2. 所有视图UI都被一个叫“Mediator”的类所管理,它负责接收Command消息并通知其UI做对应相应。

  3. 所有的Command 被 Controller管理,然而controller其实没啥重要的事可以做,除了收到消息时 执行一下 对应command的Execute方法。

  4. 上图数据可以是local也可以是Remote数据这块我理解的不是很清楚,但是我数据这部分不会用它的Proxy。

个人见解:

  我使用PureMVC的目的是在于断开耦合,而它的Proxy数据部分就是一个“字典(Dictionary)”没啥特别的,所以玩家数据部分我还是习惯写单例获取,UI数据就存在自己身上,仅仅使用其“消息传递机制部分”。什么叫消息传递机制呢,如果按照传统的类关联形式,类A要调用类B的函数,在没有中间者出现的时候,A类中必然会出现B类的名称~,而PureMVC就是通过“装箱”“开箱”操作提供了这样的一个中间者(第三者)类似于邮递员,A类可以通过这个邮递员在完全不与B类接触的情况下调用B类的函数,而当A类是“一对多”或”多对多”形式时,这种设计模式就更是讨喜,某个类的消失并不会大量影响代码逻辑,让代码的健壮度大大提升!

使用篇:

  1. 当然是导入对应代码了!!我这里保留一份下载地址 链接:https://pan.baidu.com/s/1RMrmN9y6yxUP3co2Hklsyw 密码:xu96
  2. 将 修改“AppFacade”“Const_GameTest”代码,修改AppFacade的类型名,使之与其他游戏区分开(如果大厅中包含2个使用同一框架的游戏,名字相同会导致BUG);Const_XXX中添加开始游戏和关闭游戏的消息。
  3. 编写GameStartCommand类的Execute方法,注册其他Command、注册Mediator、删除开始游戏命令代码如下
/***************************************
Author: Tason
Version: v1.0
Last Updata: 2018-6-7
Tel: 159285XXXX
Method of Use: 启动命令
1.注册基础的用户数据
***************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PureMVC.Patterns;
using PureMVC.Interfaces; public class StartUpCommand : SimpleCommand
{
public override void Execute(INotification notification)
{
base.Execute(notification); //提示
Debug.Log("Command Excute ----- GameStart"); //注册Model - 这里不用模型
//Facade.RegisterProxy(new UserProxy()); //注册Command 这里要先注册Command 这关系掉调用顺序
Facade.RegisterCommand(Const_GameTest.GAMEOVER, typeof(GameOverCommand));
Facade.RegisterCommand(Const_GameTest.PREPIC, typeof(PrePicCommand));
Facade.RegisterCommand(Const_GameTest.AFTERPIC, typeof(AfterPicCommand));
Facade.RegisterCommand(Const_GameTest.DELPIC, typeof(DelPicCommand)); //注册View
Facade.RegisterMediator(new MiddleShowMediator(GameManager_GameTest.Instance.m_middleShowManager)); //删除启动命令
Facade.RemoveCommand(Const_GameTest.GAMESTART);
}
}

  4. 编写Mediator用于接收消息(包括它关心什么,它如何响应2部分)

/***************************************
Editor: Tason
Version: v1.0
Last Edit Date: 2018-XX-XX
Tel: 328791554@qq.com
Function Doc: ***************************************/ using UnityEngine;
using PureMVC.Patterns;
using PureMVC.Interfaces;
using System.Collections.Generic; public class MiddleShowMediator : Mediator
{
//名字
public new const string NAME = "MiddleShowMediator"; //关联到的类
private MiddleShowManager View
{
get { return (MiddleShowManager)ViewComponent; }
} //构造
public MiddleShowMediator(object _viewComponent)
: base(NAME, _viewComponent){} //添加关心的事件
public override IList<string> ListNotificationInterests()
{
IList<string> list = new List<string>();
list.Add(Const_GameTest.PREPIC);
list.Add(Const_GameTest.AFTERPIC);
return list;
} //处理事件
public override void HandleNotification(PureMVC.Interfaces.INotification notification)
{
switch (notification.Name)
{
case Const_GameTest.PREPIC:
Debug.Log("!!!");
View.ChangeDisplay(DataManager.Instance.GetCurrentSpriteName());
break;
case Const_GameTest.AFTERPIC:
View.ChangeDisplay(DataManager.Instance.GetCurrentSpriteName());
break;
}
}
}

  5.编写GameManager用于启动MVC框架

   AppFacadeGT.Instance.StartUp();

  6.发送消息都是通过单例发送

//带参消息
AppFacadeGT.Instance.SendNotification(Const_GameTest.PREPIC, "上一张?");
//不带参消息
AppFacadeGT.Instance.SendNotification(Const_GameTest.PREPIC);
//带参Command解析
public class AfterPicCommand : SimpleCommand
{
public override void Execute(INotification notification)
{ string a = notification.Body as string;
Debug.Log(a);
}
}

注意:

  1.消息部分请注意编写时尽量带上游戏名称简写,好与其他游戏进行区分。

  2.GameStartCommand 注册了的东西 在 GameOverCommand时一定要删除。

  3. 发送消息时Command的Execute运行顺序优先于,Mediator的HandleNotification。我觉得这样是正确的,如果要修改顺序,在注册时先注册Command后注册Mediator即可。反之就一定要先注册Command。

项目链接:

  简单做了个demo,版本是Unity5.4.3f1 链接:https://pan.baidu.com/s/17chym5cYKqb2v5-kkGdjIw 密码:9uwz

原理解析:

  1. GameManager中 AppFacadeGT.Instance.StartUp()时,AppFacade创建自身、Model、View、Controller单例,并注册了GameStart消息。

  2.GameCommand中 注册其他command & Mediator、但是逻辑写哪呢?是写在Command的Execute中还是Mediator的HandleNotification中执行逻辑?貌似都可以?

  当然不是!比如玩家扣钱,你在主页面要显示这个金钱,在背包界面也要现实金钱的时候,那么就会有2个物品存在扣钱的消息监听,如果你在2个Mediator中都执行扣钱逻辑,那玩家不就GG了!所以逻辑应该放在Command中而Mediator中只放自己的显示逻辑!

  3.注册部分,这里不管Proxy,View是核心部分,它管理了2个Dictionary数据结构,第一个IDictionary<string, IList<IObserver>> m_observerMap 存放 消息与监听者List,在注册Mediator或Command时,它会生成对应的监听者,存放在这个List中。第二个IDictionary<string, IMediator> m_mediatorMap 存放 mediator名称与mediator实例,这里面最重要的就是第一个表,它的反射代码如下:

  

            Type t = context.GetType();
BindingFlags f = BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase;
MethodInfo mi = t.GetMethod(method, f);
mi.Invoke(context, new object[] { notification });

  说实在的,这个pureMVC不太好讲,需要的知识点很多:

  1. 观察者模式  
  2. 外观模式
  3. 代理模式(Proxy中,没太在意)
  4. 命令模式
  5. 单例模式

  等,所以啊 我这只能提供代码,理解的话还是要自己去读代码!!!!!!!哈哈哈哈!!!

提供一篇别人的PureMVC解析资料,感觉写的比我详细:https://blog.csdn.net/qq_29579137/article/details/73692842

“PurMVC”在Unity中的应用的更多相关文章

  1. Unity中使用Attribute

    Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...

  2. 在Unity中使用UGUI修改Mesh绘制几何图形

    在商店看到这样一个例子,表示很有兴趣,他们说是用UGUI做的.我想,像这种可以随便变形的图形,我第一个就想到了网格变形. 做法1: 细心的朋友应该会发现,每个UGUI可见元素,都有一个‘Canvas ...

  3. Unity中使用WebView

    Unity中使用WebView @(设计) 需求,最近游戏中需要引入H5直播页面和更新比较频繁的赛事页面,需求包括:加密传参数.和Unity交互,在Unity框架下其实有几种方案: 内置函数Appli ...

  4. Unity中创建二维码

    在网络上发现了一个可以把字符串转换成二维码的dll,但是我们要怎么使用他呢.不废话,直接进入主题. 用到的引用 using UnityEngine;using ZXing;using ZXing.Qr ...

  5. 在Unity中创建可远程加载的.unity3d包

    在一个Unity项目中,发布包本身不一定要包括所有的Asset(译为资产或组件),其它的部分可以单独发布为.unity3d,再由程序从本地/远程加载执行,这部分不在本文讨论范围.虽然Unity并没有直 ...

  6. 【原创翻译】初识Unity中的Compute Shader

    一直以来都想试着自己翻译一些东西,现在发现翻译真的很不容易,如果你直接把作者的原文按照英文的思维翻译过来,你会发现中国人读起来很是别扭,但是如果你想完全利用中国人的语言方式来翻译,又怕自己理解的不到位 ...

  7. 【unity shaders】:Unity中的Shader及其基本框架

    shader和Material的基本关系 Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出.绘图单元可以依据这个输出来将图 ...

  8. Unity中各个平台的预编译的运用方式

    1,unity中官方文档的一个操纵关键词   Platform Dependent Compilation 2,常用的预编译关键词    UNITY_EDITOR    编辑器调用.UNITY_STA ...

  9. 解读Unity中的CG编写Shader系列七(不透明度与混合)

    转自http://www.itnose.net/detail/6098539.html 1.不透明度 当我们要将两个半透的纹理贴图到一个材质球上的时候就遇到混合的问题,由于前面的知识我们已经知道了片段 ...

随机推荐

  1. 第四周博客作业 <西北师范大学| 周安伟>

    一,助教博客链接https://home.cnblogs.com/u/zaw-315/ 二,本周点评作业量点评23份,对提交的优秀作业代码进行运行一份博客问题无法点评问题博客链接:https://ww ...

  2. java数据结构分析

    java数据结构分析 此文章内容参考于:http://www.cnblogs.com/ysocean/ 一.数据结构总览图 1.数组 2.链表 3.栈 4.队列 5.二叉树 6.堆 7.散列 8.红黑 ...

  3. wpf 给listview的数据源转换为集合

    目的是点击某个按钮把一条数据从 itemssource中移除 private void delete_Click_1(object sender, RoutedEventArgs e) { DtsIn ...

  4. adduser与useradd的区别

    问题:使用 useradd 创建用户,发现 /home 目录下没有自动创建关于用户的目录.所以做了一番调查研究 useradd是一个linux命令,但是它提供了很多参数在用户使用的时候根据自己的需要进 ...

  5. 使用python画一只佩奇

    打开界面: 打开python shell界面. 建立脚本: 单击"file"——"new file"来建立脚本. 编写代码: 具体的代码如下. import t ...

  6. JavaSE基础知识(5)—面向对象(5.7 final关键字)

    一.说明 final属于一种修饰符,可以用于修饰类和属性.方法.局部变量 二.特点 1.修饰类 该类不能被继承,如String.Integer等 2.修饰方法 该方法不能被重写 3.修饰变量(属性和局 ...

  7. JS判断图片是否加载完成 背景图404 快到碗里来

    面对这个问题 我最多做到表面笑嘻嘻 …… 真不知道测试怎么那么…… 啥都能给你测出来 有的没的都能给你测出来 算了算了  谁让本仙女本精灵本可爱温柔大方善解人意呢 …呵呵呵 ————————————正 ...

  8. 堆&栈的理解(转)

    (摘自:http://www.cnblogs.com/likwo/archive/2010/12/20/1911026.html) C++中堆和栈的理解 内存分配方面: 堆: 操作系统有一个记录空闲内 ...

  9. hid.dll

    hid.dll是USB的HID相关动态链接库文件,缺少它可能会造成usb设备无法正常使用.当你的电脑弹出提示“计算机缺少hid.dll”或“无法找到hid.dll Hkapi.dll HKComman ...

  10. 调用Excel宏批量处理文件

    '1.用户可以任意选择文件夹进行遍历 '2.限定遍历时仅搜索EXCEL文件(你可以改变文件类型) '这个程序要先在“引用”下选择"microsoft scripting runtime&qu ...