游戏开发与面向对象(OOP)

面向对象是符合人类思考方式的。

1、面向对象的“整理归类”特性

①、面向对象的一个重要特性是将程序中出现的属性和方法整理归类。 理想/极限情况下,程序中所有属性和方法都能找到其所属类。

②、继承是更进一步的整理和归类,它将各个子类的相同属性和方法抽象到父类中,以此大量减少重复代码。

(仅为了减少重复代码而定义一个全局的Util类存放各种杂乱的方法是不好的,不要这么干)

(继承在一定程度上带来了耦合度和复杂度,仅为了减少少量重复代码而继承,可能得不偿失)

2、利用面向对象思想快速搭建游戏demo。

在面对一个游戏设计时,可以先大胆将游戏设计内容对象化(可画出类图)。然后在处理具体游戏业务的时,按照实际需求逐步将必需的属性和行为加入到对象中。

如下:(一个曾经快速搭建但未完成的demo类图)

3、UI 对象化设计制作。

每个界面作为一个游戏对象。界面中,较为独立的部分/重复出现的部分,可以单作为游戏对象。

逐层嵌套,形成父子关系。 聚合/组合关系:1~1或1~N。

这样做的好处是:

1、可以针对各层对象写逻辑,使逻辑各归其所。
2、对象可以复用。界面干净整洁、统一性好,不会出现有两处相同的东西,却长得不太一样。
3、极大加快UI开发效率,设计界面、拼界面、写界面逻辑都是对 “对象化的零件” 进行拼凑组合。

比如:商店界面:商店界面 -> 货架 -> 货架的层 -> 货架层上的物体。
比如:编队界面:编队界面 -> 队伍槽位 -> 队伍中的英雄。
比如:英雄培养界面:英雄培养界面 -> 消耗材料槽(放材料图标和拥有/需求数量) -> 材料图标。

要求:策划和美术要按照对象化的思想进行设计。

4、利用面向对象思想快速阅读他人代码/官方源码

如何阅读源码?

5、游戏对象与数据结构与存档

简单来说,

游戏的初始化就是:将存档的数据包反序列化为数据结构,然后一层层还原为游戏对象。

游戏的进行就是:玩家通过操作改变游戏对象的属性。

游戏的存档就是:将游戏对象一层一层提纯为数据结构,然后序列化为数据包,然后存档。

6、面向对象与策划表

① 、 “在列首定义表头字段、按行填值” 的excel,本身就是对象化的。

表头字段可看作类的字段,每行的数据都是类的对象。只是这个类只有字段,没有方法(Excel中也定义不了方法)。

准确地说,策划表中每行数据形成的对象只是其对应的游戏对象的一部分(partial),因为它只是静态数据,实际的游戏对象应由静态数据和动态数据共同组成(但不是绝对的)。

②、按继承关系拆分策划表。

在实际开发中发现,一个复杂的表结构,很难平铺在一张表中(如,活动表)。

强行平铺可能导致大量字段冗余,填表的人在填写时会懵逼(???到底哪些列填了是生效的),也容易填错。(如,A类型活动需要MXYZEF字段,B类型活动需要MXYZGH字段(M为主键))

这种情况就应该拆分为父子表。不同类型的对象单独建立子表,子表的第一主键索指向父表。

父表只配公共部分的字段,子表中只配具体类型对象需要的字段。

(活动表拆分后:父表配 MXYZ字段,A类型活动子表配MEF字段、B类型活动子表配MGH字段)

③、按组合/聚合关系拆分策划表。

后来又发现,某活动除了有活动自身的配置(活动主图Spine、界面特效、关联某商店、整体奖励领取条件等),还拥有一个任务列表,而每个任务项都需要配置(任务序号索引、任务目标、跳转等)。很明显,该活动与任务项的关系是 聚合。

这种情况应该增加一个 “聚合子表”。

(假设该活动还是②中的A活动,增加后,父表配 MXYZ字段,A类型活动子表配MEF字段,A类型活动的任务表配MNJK字段(N是任务序号索引,为第二主键))。

(如果该活动只有任务列表的配置,则为组合关系,没有自身的配置,可直接省略A类型活动子表

---------------------------- NRatel割 ----------------------------

一般情况下,表拆三层足够满足大多数需求。

表拆得更细,逻辑会更清晰,但维护起来会变得麻烦,策划可能不会接受。

简单的需求,也可以适当允许字段冗余而不拆分表。

7、纯粹面向对象的问题

当对象行为复杂时,可能难以抽象表述为继承关系,因此也无法让代码复用。

如:

①,菱形继承的问题 类B、C继承自类A, 类D 又希望同时拥有类BC的行为。

,有类 A、B、C 和 行为 X、Y、Z,其中,

类 A 拥有行为 XY,

类 B 拥有行为 XYZ,

类 C 拥有行为 YZ,

这种情况下,虽然它们之间有公共方法,但却无法干净地抽象出公共父类。

8、面向接口

①、面向接口是对面向对象的补充,它从整体出发,定义了各系统/模块之间的交互规范。

②、可以通过实现一组接口,快速拓展出适用于设计体系的模块。

③、实现接口的模块,要完成接口定义的、对外提供的功能。

④、调用接口的模块,不关心接口实现者的内部实现。

⑤、面向接口可能造成重复代码,但这在整体架构面前可能微不足道。 (重复原因:原本属于各个子类的方法,变成了属于规范。没办法再通过“抽象出父类”的办法消除重复了)。

⑥、为了解决接口实现的代码重复问题,C#8.0中又允许接口定义默认方法。

⑦、定义一个接口帮助类,也可解决接口实现的代码重复问题。

public interface IProgress
{
    int GetCurCount();
    int GetMaxCount();
}

public static class IProgressHelper
{
    public static float GetProgress(this IProgress p)
    {
        return (float)p.GetCurCount() / p.GetMaxCount();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NRatel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值