Vico Bill< 刘 利 波 > 的个人网站

记录关于学习、工作中的技术点滴

C,C++,Rust,Ruby爱好者;热衷于游戏开发、任务自动化与跨平台;沉迷于游戏引擎与图形表现;深信'简单、多元'哲学的力量。


访问主页

游戏设计-设计与架构

设计与架构

  1. 分层:将庞大的系统,分割成功能独立的子系统。然后各个子系统进行协作,一起完成庞大的最终系统。

    1. 分层的细化:将每个层,进行细化,划分为更多的子层。
    2. 对层进行分区:区在层的内部,粒度比层小。
    3. 提取机制:预定义的能完成预期目标,基于抽象角色的协作方式。例如消息机制

    通常的分层为:展现层、业务层、数据层。

    通常的代码分层为:子系统、模块、类。

    分层是对职责进行分离;机制是通用单元的分离。

  2. 接口定义: 协作定义接口。

设计模式

设计模式存在的意义:

  • 在扩展功能时,产生的影响很小。
  • 在替换原有代码时,产生的影响很小。
  • 在移除旧代码时,产生的影响很小。

设计模式的准则:

  • 一个类,不需要知道所依赖类的具体实现,只需要知道其接口即可。
  • 优先使用组合,减少继承。
  • 不好解决时,添加中间类。

常用设计模式

Command: 把函数作为命令。命令可以Undo,Redo等。

装饰模式:1. 将接口进行转换成期望的接口 2. 给原有类添加新的功能

Flyweight:共享元。多个对象,可以共享同一个数据。(核心相同部分只有一份,通过引用,减少内存占用。)(如森林,基本上树都相同)

Observer:观察者。事件机制。当事件触发时,只管触发,并不关心谁来处理此事件。(Fire and Forget)

struct IEvent {};

struct IObserver {
    virtual void On(struct IEvent* ev) = 0;
};

template<typename TEvent>
class EventDispatcher<TEvent> {
	std::vector<struct IObserver*> observers;
public:
    void FireEvent(struct IEvent* ev){
        for(auto o : observers) {
            o.On(ev);
        }
    }
    void AddObserver(struct IObserver* o){}
}

Singleton: 单例。确保类有且只有一个实例。这在如C++里,不能确定全局变量的初始化时机时,用于替代全局变量。

State: 状态:对象状态改变时,同时改变其行为。

class StateMachine {
    struct IState* state;
public:
    void SetState(IState* state) ;
    void RunState();
};

迭代器:对聚集对象进行遍历。(针对易越界的情况)

如何接手大型游戏项目

快速适应大型已有项目非常具有挑战,通常会面临各种混乱的情况:代码风格混乱;文件结构混乱;各种模块代码耦合;设计文档缺失;文档不清等等。

  1. 面对混乱的局面,首先需要冷静,绝对冷静。
  2. 解耦合:化繁为简,便于可控。将游戏代码以功能划分模块。然后划分每个功能模块之间的桥接模块。
  3. 区分设计模式:MVC,事件机制,状态机等。对于一个成熟的游戏项目来说,通常会有游戏引擎和游戏模块组成。在游戏模块中,通常有UI、网络通信(RPC)、配置文件解析、SDK集成、关卡切换管理、特效、动画管理等。
  4. 程序由变量和函数组成,肯定有对应的引用。特别是类中的公有成员。
  5. 所有编写的代码,只是一份蓝图和布局,是编写者思想、解题思路的体现。代码只有在运行起来,才分配内存空间。计算机只在乎数据:要处理的数据存在还是不存在?如何对数据进行处理?
  6. 重构代码:不修改逻辑和数据布局的情况下,对代码以对阅读者更友好的方式进行修改。常见的往往在于修改名称(变量名称,是变量数据用途的注解),以及将揉合的庞大类,进行分拆。

名称是给人看的,机器只识别数据。代码质量高低,决定于人的主观意识。项目的理解快慢,取决于阅读者水平以及编写者对代码的处理能力。 编写者处理能力包括:

  • 代码命名是否一致,且清晰简单
  • 代码布局(分层,分目录)
  • 逻辑是否清晰,是否干净利落,不参杂
  • 是否有干净利落的文档

阅读者水平包括:

数据设计:

数据分为: - Table 数据: 从配置表直接读取的数据。Table数据往往是固定的数据,其数值只读 - Data 数据: 在游戏中,对此对象建模所需要的数据模型。

最近的文章

笔记集锦-Protobuf

proto网络数据只关心数据布局,不关心名称protobuf 整体发送数据通过Serializer进行序列化,只关心数据布局,不关心数据名称。即:protobuf的.proto文件,只要数据布局相同,名称(Message的名称和字段名称)是可以任意改动的。syntax="proto3";是必须的字段名称忽略大小写且忽略分隔符 proto的字段名称,是忽略大小写的!且忽略分隔符! enum EEnumTest { EET_None = 0; // 会生成为cs的EetNone ...…

继续阅读
更早的文章

游戏引擎-研究报告

游戏引擎研究报告@refer:Torque3,TombstoneEngine,CryEngine,Unreal4,Unity,Lumberyard,Source2,Panda3D,Leadwerks,Xenko,id Tech 4,Blender Game Engine,Love2D编程语言现今的3D游戏引擎通常使用OOP编程语言,特别是无垃圾回收的静态编程语言,因为游戏引擎需要的高性能(C++)。附以带垃圾回收、动态、简单上手、易扩展的脚本语言作为逻辑编写语言(如Lua,mruby,py...…

继续阅读