设计模式与游戏完美开发(2)

更多内容可以浏览本人博客:https://azureblog.cn/ 😊
该文章主体内容来自《设计模式与游戏完美开发》—蔡升达

第二篇 基础系统

第四章 游戏主要类——外观模式(Facade)

一、游戏子功能的整合

一个游戏程序常常由内部数个不同的子系统构成(如事件系统,关卡系统,成就系统等等),这些系统支持着游戏基本功能和玩法。这些子系统需要按照一定的顺序进行初始化,某些条件达成时也需要按照一定的流程替他们释放资源。并且这些子系统会彼此使用对方的功能,即不同子系统之间会进行“通信”。

通常来说,我们认为这些子系统的通信及初始化过程应当发生在“内部”,因为当有其他的程序(或者我们自己)来添加一个游戏功能系统时,最好能不用去了解其他子系统之间的相关运行过程,而仅仅通过一些相对“高级”的接口来调用其他子系统的相关功能。

上一章所提到的"战斗状态类(BattleScene)"就是一个必须使用到的游戏系统功能的客户端,根据上一章的说明,战斗状态类(BattleState)主要负责游戏战斗的运行,而《P级阵地》在进行一场战斗时,需要大部分的子系统一起合作完成.在实现时,可以先把这些子系统及相关的执行流程全都放在BattleState类之中一起完成。

在战斗系统类中实现所有子系统相关操作:

public class BattleState: ISceneState {//声明所有需要的子系统private GameEventSystem m_GameEventSystem = null;private CampSystem m_CampSystem = null;private StageSystem m_StageSystem = null;private CharacterSystem m_CharacterSystem = null;private APSystem m_ApSystem = null;private AchivementSystem m_AchievementSystem =null;public GameState(SceneStateController Controller): base(Controller) {this.StateName = "GameState";InitGameSystem();}//初始化这些子系统private void InitGameSystem() {m_GameEventySystem = new GameEventSystem();...}//子系统的更新操作private void UpdateGameSystem() {m_GameEventSystem.Update();...}
}

虽然这样的实现方式很简单,但让战斗状态类(BattleState)整个客户端去负责调用所有与游戏玩法相关的系统功能是不好的实现方式,原因是:

  • 从让事情单一化(单一职责原则)这一点来看,BattleScene类负责的是游戏在"战斗状态"下的功能执行及状态切换,所以不应该负责游戏子系统的初始化,执行操作及相关的整合工作。

  • 以"可重用性"来看,这种设计方式会使得BattleState类不容易转换给其他项目使用,因为BattleState类与太多特定的子系统类产生关联,必须将它们删除才能转换给其他项目,因此丧失可重用性

综合上述两个原因,将这些子系统从BattleState类中移出,整合在单一类之下,会是比较好的做法.所以,在《P级阵地》中应用了外观模式(Facade)来整合这些子系统,使它们成为单一界面并提供外界使用。

二、外观模式(Facade)的定义

“为子系统定义一组统一的接口,这个高级的接口会让子系统更容易被使用”。—GoF

其实,外观模式(Facade)是在生活中最容易碰到的模式。当我们能够利用简单的行为来操作一个复杂的系统时,当下所使用的接口,就是以外观模式(Facade)来定义的高级接口。

外观模式(Facade)的重点在于,它能将系统内部的互动细节隐藏起来,并提供一个简单方便的接口.之后客户端只需要通过这个接口,就可以操作一个复杂系统并让它们顺利运行。

img

参与者的说明如下:

  • client(客户端,用户):

    从原本需要操作多个子系统的情况,改为只需要面对一个整合后的界面。

  • subSystem(子系统):

    原本会由不同的客户端(非同一系统相关)来操作,改为只会由内部系统之间交互使用。

  • Facade(统一对外的界面):

    整合所有子系统的接口及功能,并提供高级界面(或接口)供客户端使用。

    接收客户端的信息后,将信息传送给负责的子系统。

三、使用外观模式实现游戏主程序

PBaseGameDefenseGame类就是"整合所有子系统,并提供高级界面的外观模式类"。

img

具体实现:

//PBaseDefenseGame.cs
public class PBaeDefenseGame 
{//声明各个游戏子系统...private GameEventSystem m_GameEventSystem =null;...//初始化public void Initinal() {...m_GameEventSystem = new GameEventSystem(this);...}//更新操作public void Update() {...m_GameEventSystem.Update();...}//获取游戏状态、敌人数量等...
}//BattleState.cs
public class BattleState: ISceneState {public override void StateBegin() {PBaseDefenseGame.Instance.Initinal();//初始化,隐藏了其它子系统的细节}public override void StateEnd() {PBaseDefenseGame.Instance.Release();}public override void StateUpdate() {...PBaseDefenseGame.Instance.Update();...if (PBaseDefenseGame.Instance.ThisGameIsOver()) {m_Controller.SetState(new MainMenuState(m_Controller), "MainMenuState");}}
}

使用外观模式的优点:

  • 使用外观模式(Facade)可将战斗状态类BattleState单一化,让该类只负责游戏在"战斗状态"下的功能执行及状态切换,不用负责串接各个游戏系统的初始化和功能调用。

  • 使用外观模式(Facade)使得战斗状态类BattleScene减少了不必要的类引用及功能整合,因此增加了BattleState类被重复使用的机会。

  • 节省时间

Unity3D本身提供了不少系统的Facade接口,例如物理引擎,渲染系统,动作系统,粒子系统等。

  • 易于分工开发

对于一个既庞大又复杂的子系统而言,若应用外观模式(Facade),即可成为另一个Facade接口.所以,在工作 的分工配合上,开发者只需要了解对方负责系统的Facade接口类,不必深入了解其中的运行方式。

  • 增加系统的安全性

隔离客户端对子系统的接触,除了能减少耦合度之外,安全性也是重点之一。

注意事项:

由于将所有子系统集中在Facade接口类中,最终会导致Facade接口类过于庞大且难以维护,当发生这种情况时,可以重构Facade接口类,将功能相近的子系统进行整合,以减少内部系统的依赖性,或是整合其他设计模式来减少Facade接口类过度膨胀。

Facade面对变化时:

随着开发需求的变更,任何游戏子系统的修改及更换,都被限制在PBaseDefenseGame这个Facade接口类内。所以,,当有新的系统需要增加时,也只会影响PBaseDefenseGame类的定义及增加对外开放的方法,这样就能使项目的变动范围减到最小。
以减少内部系统的依赖性,或是整合其他设计模式来减少Facade接口类过度膨胀。

Facade面对变化时:

随着开发需求的变更,任何游戏子系统的修改及更换,都被限制在PBaseDefenseGame这个Facade接口类内。所以,,当有新的系统需要增加时,也只会影响PBaseDefenseGame类的定义及增加对外开放的方法,这样就能使项目的变动范围减到最小。

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

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

相关文章

linux自动化批量分发SSH密钥同时批量测试SSH连接教程(包含自动化脚本代码)

1、检查端口 检查分发对象22端口是否打开 nmap -p22 ip地址如果要批量检查端口可以参考我写的这篇文章:linux自动化一键批量检查主机端口 2、命令行分发密钥原理 Linux分发密钥原理主要涉及SSH(Secure Shell)协议,该协议用于…

OpenHarmony源码编译后烧录镜像教程,RK3566鸿蒙开发板演示

本文介绍瑞芯微主板/开发板编译OpenHarmony源码后烧录镜像的教程,触觉智能Purple Pi OH鸿蒙开发板演示。搭载了瑞芯微RK3566四核处理器,树莓派卡片电脑设计,支持开源鸿蒙OpenHarmony3.2-5.0系统,适合鸿蒙开发入门学习。 编译源码…

【GO基础学习】gin框架路由详解

文章目录 gin框架路由详解(1)go mod tidy(2)r : gin.Default()(3)r.GET()路由注册 (4)r.Run()路由匹配 总结 gin框架路由详解 先创建一个项目,编写一个简单的demo&#…

vue之axios基本使用

文章目录 1. axios 网络请求库2. axiosvue 1. axios 网络请求库 <body> <input type"button" value"get请求" class"get"> <input type"button" value"post请求" class"post"> <!-- 官网提供…

ubuntu快速入门

1.进入某个文件夹 cd workspace/2.tab自动补全 3.列出当前文件夹所有文件 ls列出所有文件包括隐藏文件 ls -a 4.创建文件夹 mkdir linuxLearn 5.创建文件 gedit command.sh在commmand.sh键入 echo hello echo hi? echo how are you? PS:touch hello.txt(也可以创建新…

优化 invite_codes 表的 SQL 创建语句

-- auto-generated definition create table invite_codes (id int auto_incrementprimary key,invite_code varchar(6) not null comment 邀请码&#xff0c;6位整数&#xff0c;确保在有效期内…

FATE-LLM简介;FATE-LLM集成了多种参数高效微调方法

FATE-LLM简介 FATE-LLM是一个支持联邦大语言模型训练的框架,其架构及核心技术原理如下: 架构概述 FATE-LLM主要由模型层、参数高效微调层、隐私保护与安全机制、通信与聚合模块等组成,致力于在保护数据隐私的前提下,利用联邦学习技术整合各方数据与算力资源,提升大语言模…

小程序租赁系统构建指南与市场机会分析

内容概要 在当今竞争激烈的市场环境中&#xff0c;小程序租赁系统正崭露头角&#xff0c;成为企业转型与创新的重要工具。通过这个系统&#xff0c;商户能够快速推出自己的小程序&#xff0c;无需从头开发&#xff0c;节省了大量时间和资金。让我们来看看这个系统的核心功能吧…

数据库系列之分布式数据库下误删表怎么恢复?

数据的完整性是数据库可用性的基本功能&#xff0c;在实际应用数据库变更操作过程中可能因为误操作导致误删表或者truncate操作影响业务的正常访问。本文介绍了分布式数据库中在误删表场景下的数据恢复方案&#xff0c;并进行了对比。 1、数据库误删表恢复方案 应用数据的完整…

论文阅读:Towards Faster Deep Graph Clustering via Efficient Graph Auto-Encoder

论文地址&#xff1a;Towards Faster Deep Graph Clustering via Efficient Graph Auto-Encoder | ACM Transactions on Knowledge Discovery from Data 代码地址&#xff1a; https://github.com/Marigoldwu/FastDGC 摘要 深度图聚类&#xff08;Deep Graph Clustering, DGC…

Python爬虫教程——7个爬虫小案例(附源码)_爬虫实例

本文介绍了7个Python爬虫小案例&#xff0c;包括爬取豆瓣电影Top250、猫眼电影Top100、全国高校名单、中国天气网、当当网图书、糗事百科段子和新浪微博信息&#xff0c;帮助读者理解并实践Python爬虫基础知识。 包含编程资料、学习路线图、源代码、软件安装包等&#xff01;【…

BMS存储模块的设计

目的 电池管理系统中存在着数据本地存储的要求&#xff0c;保证控制器重新上电后能够根据存储器中的一些参数恢复控制状态&#xff0c;和信息的下电存储1.继电器故障信息的存储。2. 系统性故障的存储。3.SOC、SOH相关信息的存储。4.均衡参数的存储。5.系统时间信息。6.出厂信息…

Python爬取城市天气信息,并存储到csv文件中

1.爬取的网址为&#xff1a;天气网 (weather.com.cn) 2.需要建立Weather.txt文件&#xff0c;并在里面加入如下形式的字段&#xff1a; 101120701济宁 101010100北京 3.代码运行后&#xff0c;在命令行输入Weather.txt文件中添加过的城市&#xff0c;如&#xff1a;济宁。 …

MySQL线上事故:使用`WHERE`条件`!=xxx`无法查询到NULL数据

前言 在一次 MySQL 的线上查询操作中&#xff0c;因为 ! 的特性导致未能正确查询到为 NULL 的数据&#xff0c;险些引发严重后果。本文将详细解析 NULL 在 SQL 中的行为&#xff0c;如何避免类似问题&#xff0c;并提供实际操作建议。 1. 为什么NULL会查询不到&#xff1f; 在…

Solidworks打开无法获得许可,提示(-15,10,10061)错误解决办法

参考文章&#xff1a; https://blog.csdn.net/2301_81263647/article/details/140904773

【电路理论四】正弦电流电路

正弦电流 正弦量是随时间按正弦规律变动的电路变量。 随时间按正弦规律变动的电流称为正弦电流。 正弦电流的瞬时值表达式&#xff1a; 称为正弦电流的三要素。 分别为振幅/幅值&#xff0c;角频率&#xff0c;初相。 幅值为正弦电流的最大值&#xff0c;恒为正。 为正弦电…

解决Windows无法同时使用有线网和无线网WIFI的问题

参考资料 电脑无线网wifi和有线网同时使用&#xff08;内网外网同时使用&#xff09;用route命令解决Wifi和网卡不能同时上内外网问题 解决方法 对于Windows系统同时连接有线网和无线网Wifi时&#xff0c;只会有一个网关生效&#xff0c;因此我们需要手动通过route命令设置网…

FOC控制原理-ADC采样时机

0、文章推荐 SimpleFOC移植STM32&#xff08;五&#xff09;—— 电流采样及其变换_极对数对电流采样的影响-CSDN博客 FOC 电流采样方案对比&#xff08;单电阻/双电阻/三电阻&#xff09; - 知乎 (zhihu.com) FOC中的三种电流采样方式&#xff0c;你真的会选择吗&#xff1f;…

uniapp:编译微信、h5都正常的,编译钉钉小程序无法找到页面

我们在做uniapp的开发的时候遇到很多莫名其妙的问题&#xff0c;其中就有个很奇葩的问题&#xff0c;我们开发的过程中使用微信小程序/h5调试都是正常编译正常跳转&#xff0c;然后在要上架的时候&#xff0c;编译钉钉小程序成功&#xff0c;但是访问页面无法访问&#xff0c; …

zentao ubuntu上安装

#下载ZenTaoPMS-21.2-zbox_amd64.tar.gz&#xff08;https://www.zentao.net/downloads.html&#xff09; https://dl.zentao.net/zentao/21.2/ZenTaoPMS-21.2-zbox_amd64.tar.gzcd /opt tar -zxvf ZenTaoPMS-21.2-zbox_amd64.tar.gz#启动 /opt/zbox/zbox start /opt/zbox/zbox…