【Unity/QFramework】QFramework学习笔记

文章目录

    • 基础流程
    • 示例程序【PointGame】
      • Architecture
      • Storage
        • PlayerPrefsStorage : IStorage
      • Model
        • GameModel : AbstractModel, IGameModel
      • Controller
        • Game : MonoBehaviour, IController
        • Enemy : MonoBehaviour, IController
        • MissArea : MonoBehaviour, IController
      • Command
        • StartGameCommand : AbstractCommand
        • KillEnemyCommand : AbstractCommand
        • MissCommand : AbstractCommand
        • BuyLifeCommand : AbstractCommand
      • Event
      • System
        • ScoreSystem : AbstractSystem, IScoreSystem
        • CountDownSystem : AbstractSystem, ICountDownSystem
        • AchievementSystem : AbstractSystem, IAchievementSystem
      • UI

QFramework是一个轻量级的游戏框架,并且整合了许多有用工具。源码只有800行不到,这既意味着其源代码足够凝练,不会束手束脚,也意味着在制作自己的游戏的时候,需要扩展和增加一下框架的功能。

QFramework整体基于MVC架构,实现了数据,操作,视图的解耦分层。在中间穿插了Command,Event,Architecture ,System这样的类作为扩展。

基础流程

  1. 全局单例:Architecture类是一个抽象类,使用时使用泛型继承,并重载其Init方法,在里面进行各个模块的注册(System,Model,Utility等)。这里即体现了IOC的思想。
  2. 底层存储:负责进行具体存储的存储类继承自IStorage接口,这是为了方便后续扩展不同的存储类,即面向接口编程(依赖倒置原则)。IStorage接口继承了IUtility接口,这是因为注册和获取时都需要通过RegisterUtility和GetUtility函数。
  3. 上层存储(Model):实现IModel接口,这一层是MVC层中的Model层,Storage层就是从这一层中分离出来的,目的是能够应用各种不同的存储方式和策略。该层会被Command,Controller等层广泛获取,用于存储和修改全局变量。
  4. 控制器(Controller):实现IController接口,该层负责发送Command,触发即使用Monobehavior的函数,如玩家输入,鼠标事件,UI按钮等,具体执行的操作在Command中定义,Event也在Command中进行触发。除此之外该层还负责绑定Event事件到视图更新上。
  5. 视图(View):该层通过绑定Event事件来触发更新
  6. 命令(Command):该类是Controller层发出的,每个Command都继承自AbstractCommand,并重写OnExecute来执行业务逻辑,并按条件触发不同的事件。
  7. 事件(Event):事件是一个什么也不继承的纯结构体,使用扩展泛型方法RegisterEvent进行绑定,CancelEvent进行取消绑定,或者使用链式编程在绑定时即使用CancelOnDestroy(gameObject)简化这一过程。
  8. 系统(System):系统继承自具体的系统接口IxxxSystem和AbstractSystem,这些具体的系统接口继承自ISystem,系统层用于扩展不同的业务功能,比如输入,成就,任务,计时等等高级逻辑。系统层基本基于Event事件触发。

示例程序【PointGame】

该示例程序可以在QFramework的官方Github页面找到,链接如下
github.com/onehundredlines/FrameworkDesign

Architecture

PointGame : Architecture

该层负责注册模块:

  • AchievementSystem : AbstractSystem, IAchievementSystem
  • CountDownSystem : AbstractSystem, ICountDownSystem
  • ScoreSystem : AbstractSystem, IScoreSystem
  • GameModel : AbstractModel, IGameModel
  • PlayerPrefsStorage : IStorage

Storage

PlayerPrefsStorage : IStorage

该层负责具体的存储策略,Demo使用最简单的PlayerPrefs的方法存储数据,并且只提供了按Key读取和存储int类型的接口


Model

GameModel : AbstractModel, IGameModel

该层负责提供全局变量,负责在数据变化时将需要持久化存储的数据通过IStorage进行存储。

内部数据不需要存储的包括:KillCount,Score,HighScore

需要存储的包括:BestScore,Life,Gold


Controller

该层主要负责发送Command,接收Event。

Game : MonoBehaviour, IController

该类负责管理点击的方块的整体显隐和初始化每个方块的显隐状态,基本就相当于游戏场景的开始流程。控制显隐的时机通过注册对应的Event事件来触发。

Enemy : MonoBehaviour, IController

使用OnMouseDown,隐藏自身并发送一个KillEnemyCommand,很合理。

MissArea : MonoBehaviour, IController

使用OnMouseDown,隐藏自身并发送一个MissCommand,很合理。


Command

该层是从Controller层级中抽离出来的具体业务逻辑,其会对Model层进行更改,并发送Event事件供System,View,Controller层响应

StartGameCommand : AbstractCommand

清空GameModel中的KillCount和Score,发送OnGameStartEvent事件。

KillEnemyCommand : AbstractCommand

增加GameModel中的KillCount。并有30%概率为GameModel中的Gold随机增加1~3

发送OnKillEnemyEvent事件,并在KillCount大于等于9时发生OnGamePassEvent事件。

MissCommand : AbstractCommand

减少Gamemodel中的Life值,若该值小于等于0,发送OnMissEvent。

BuyLifeCommand : AbstractCommand

减少Gold值,增加Life值,汇率1:1


Event

该层可被Controller,View,System层进行监听,该Demo所有Event都为struct并且都没有参数,仅做触发使用,并都在上述Command中提及。


System

该层负责较为高级的业务逻辑,具体到该Demo中,包括得分系统,计时系统,成就系统。

ScoreSystem : AbstractSystem, IScoreSystem

重写OnInit(),监听OnKillEnemyEvent和OnMissEvent,增加和减少GameModel的Score值。

监听OnGamePassEvent,更新GameModel的BestScore

CountDownSystem : AbstractSystem, ICountDownSystem

重写OnInit(),监听OnGameStartEvent和OnGamePassEvent,用于设置mStarted这个Flag值以及记录开始游戏时的时间。

成员函数Update,内部在mStarted为true的情况下循环判断游戏时长是否超过十秒,超过则发送OnCountDownEndEvent事件并将mStarted设为false。该Update依赖于Monobehavior的生命周期函数,Demo里直接在UI部分的GamePanel中的Update中调用此函数,有那么一丝丝的简单粗暴。

AchievementSystem : AbstractSystem, IAchievementSystem

这个成就系统是以局为单位的,每局都会重置,也没有持久化存储。就是通过定义了一个AchievementItem类,内部有名称,是否解锁,检查是否完成的函数委托(Func)。

在Init时动态添加到成就列表中,成就条件基本就是把Model中的值掏出来判断一下是否达到,或者绑定事件记录一些flag辅助检查成就。

监听OnGamePassEvent,异步等待0.1f秒,然后遍历成就列表确认哪些满足条件且未解锁过,将其设置为解锁并打印出来


UI

这部分的类都是Monobehavior类,因为需要对UI进行初始化,找到某些按钮组件等,需要借助transform,并且没有使用框架,因此写的有点抽象,但是it just works。

总的来说这一块和Controller没什么不同,寻找按钮然后绑定发送Command,然后监听Event寻找文本进行更新(Demo里有的通过Event有的通过BindableProperty的方式来监听更新,都行)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59351.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内网安全-代理技术-socket协议

小迪安全网络架构图: 背景:当前获取window7 出网主机的shell。 1.使用msf上线,查看路由 run autoroute -p 添加路由: run post/multi/manage/autoroute 使用socks模块开启节点,作为流量跳板 msf6 exploit(multi/ha…

GaussDB部署架构

GaussDB部署架构 云数据库GaussDB管理平台(TPOPS)基于B/S架构开发,由Web、管控Service、管控Agent三部分组成,软件结构如图1所示。 图1 各节点部署架构 Web:作为用户接入子系统,用于将用户在Web下发的操作…

如何使用.bat实现电脑自动重启?

1、在电脑桌面新建一个记事本文档,将如下内容写进去: echo off shutdown /r /t 02、然后,保存一下,再把桌面此文件重命名为电脑重启.bat 3、双击此程序,可以立刻重启电脑。 PS:① 此程序会不保存任何当前…

YOLOv11融合CVPR[2024]自适应扩张卷积FADC模块及相关改进思路|YOLO改进最简教程

YOLOv11v10v8使用教程: YOLOv11入门到入土使用教程 YOLOv11改进汇总贴:YOLOv11及自研模型更新汇总 《Frequency-Adaptive Dilated Convolution for Semantic Segmentation》 一、 模块介绍 论文链接:https://arxiv.org/abs/2403.05369 代码…

简单叙述 Spring Boot 启动过程

文章目录 1. 准备阶段:应用启动的入口2. 创建 SpringApplication 对象:开始启动工作3. 配置环境(Environment):识别开发环境与生产环境4. 启动监听器和初始化器:感知启动的关键事件5. 创建 ApplicationCont…

[算法初阶]埃氏筛法与欧拉筛

素数的定义&#xff1a; 首先我们明白&#xff1a;素数的定义是只能整除1和本身&#xff08;1不是素数&#xff09;。 我们判断一个数n是不是素数时&#xff0c;可以采用试除法&#xff0c;即从i2开始&#xff0c;一直让n去%i&#xff0c;直到i*i<n c语言: #include<…

Python 数据文件读写教程

Python 数据文件读写教程 在数据科学和软件开发中&#xff0c;文件的读写操作是至关重要的。Python 作为一门功能强大的编程语言&#xff0c;提供了多种方式来处理文件&#xff0c;包括文本文件、CSV 文件、JSON 文件等。在本教程中&#xff0c;我们将深入探讨 Python 中的数据…

CSS多列布局:打破传统布局的束缚

你是否曾为如何让页面中的文字内容更加美观、易读而烦恼&#xff1f;传统的单列布局虽然简单&#xff0c;但有时并不能满足我们对页面布局的多样化需求。别担心&#xff0c;CSS 多列布局能轻松帮你解决这个问题&#xff01; 一、什么是 CSS 多列布局&#xff1f; 多列布局&am…

在uniapp当中隐藏掉默认tabbar并且使用自己的tabbar

1. 修改配置 "tabBar": {"custom": true,"selectedColor": "#ffdead","list": [{"pagePath": "pages/index/index","text": "首页"}] },//在引入自定义Tabbar组件的时候在载入的时…

新手小白学习docker第九弹-----高级篇start-Dockerfile

docker目录 1 Dockerfile是什么2 Dockerfile能干嘛3 如何书写Dockerfile3.1 Dockerfile构建过程解析3.2 小总结3.3 Dockerfile的基本知识3.5 保留字FROMMAINTAINERRUN 有两种方式EXPOSEWORKDIRENVUSERVOLUMEADDCMDENTRYPOINT 4 后记 1 Dockerfile是什么 Dockerfile顾名思义就是…

模拟实现优先级队列

目录 定义 特点 构造函数 常用方法 关于扩容的问题 关于建堆的问题 向上调整和向下调整的比较 &#xff08;向上调整&#xff09;代码 &#xff08;向下调整&#xff09;代码 关于入队列和出队列问题 模拟实现优先级队列代码 关于堆排序的问题 堆排序代码 关于对…

Autosar CP DDS规范导读

Autosar CP DDS 主要用途 数据通信 中间件协议&#xff1a;作为一种中间件协议&#xff0c;DDS实现了应用程序之间的高效数据通信&#xff0c;能够在不同的软件组件和ECU之间传输数据&#xff0c;确保数据的实时性和可靠性。跨平台通信&#xff1a;支持在AUTOSAR CP平台上的不同…

数字IC实践项目(10)—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证(付费项目)

数字IC实践项目&#xff08;10&#xff09;—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证&#xff08;付费项目&#xff09; 前言项目框图1&#xff09;DDR4 Verification IP2&#xff09;DDR4 JEDEC Model & Tb 项目文件1&#xff09;DDR4 Veri…

Jmeter中的监听器(三)

9--断言结果 功能特点 显示断言结果&#xff1a;列出所有断言的结果&#xff0c;包括通过和失败的断言。详细信息&#xff1a;显示每个断言的详细信息&#xff0c;如断言类型、实际结果和期望结果。错误信息&#xff1a;显示断言失败时的错误信息&#xff0c;帮助调试。颜色编…

Elasticsearch 实战应用:高效搜索与数据分析

在大数据和实时数据分析的背景下&#xff0c;Elasticsearch 作为一个开源的分布式搜索引擎&#xff0c;凭借其强大的查询能力、实时性能以及高可扩展性&#xff0c;成为了各种应用场景中不可或缺的工具。从网站搜索到日志分析&#xff0c;Elasticsearch 在搜索、日志聚合、数据…

人工智能大比拼(3)

已知x-,y-6&#xff0c;且下述表达式的值与x的取值无关&#xff0c;求y -10x2y7xy 上述这个很简单的数学题&#xff0c;可是在各家AI之间出现了争议&#xff0c;本期我使用了四个AI&#xff1a;kimi&#xff0c;商量&#xff0c;文心一言&#xff0c;chatyy 先来看一下kimi的表…

Xilinx Aurora 8B/10B IP介绍以及下板验证

文章目录 一、什么是Aurora协议&#xff1f;二、Aurora 8B/10B IP核的结构原理三、Aurora 8B/10B IP核 延迟开销四、用户数据接口格式4.1 AXI4-Stream 位排序4.2 帧传输用户端口说明4.3 帧传输数据流程4.4 Aurora 8B/10B 帧格式4.5 帧格式数据传输时序4.5.1 简单数据传输4.5.2 …

QT中的字符器类型

一、QT中的字符串类型 在 Qt 中&#xff0c;字符串处理是非常常见且重要的任务。Qt 提供了几种不同的字符串类型&#xff0c;每种类型都有其特定的用途和优势。以下是 Qt 中主要的字符串类型及其特点&#xff1a; 1. QString QString 是 Qt 中最常用的字符串类&#xff0c;用…

Redis8:商户查询缓存2

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

Windows下使用adb实现在模拟器中ping

文章目录 前言安装adb执行adb命令查找模拟器设备链接模拟器命令行执行ping命令 总结 前言 有时在模拟器中测试应用不像在Windows这种开发环境中那么方便&#xff0c;毕竟Windows或者Linux下的工具五花八门&#xff0c;可以满足各种测试需求&#xff0c;比如应用在模拟器中无法…