Xcode与C++之游戏开发: 游戏对象

上一篇:Xcode与C++之游戏开发:Pong游戏

游戏对象

在前面的 Pong 游戏中,没有用不同的类去代表墙,球拍和球,仅仅使用了一个 Game 类。像 Pong 这种简单游戏当然没问题,但它不是可扩展的解决方案。为了可扩展性,将墙、球拍、球分别用不同的类表示是更好的选择。

游戏对象(game object),指的是游戏中任何需要更新和绘制的事物。表示游戏对象存在不同的方法,有的采取层次结构,有的采用组合,也有更复杂的设计模式。但不管是哪种表示方法,游戏都需要某种方式来跟踪和更新这些游戏对象。

有时候,开发者会把在游戏中只绘制,不更新的对象称为静态对象。这些对象对玩家可视,但是从来不需要更新,比如关卡的背景、那些人畜无害的游戏建筑。相反,有的游戏对象只更新但不绘制,例如摄像机的视角,还有比如触发器。恐怖游戏可能希望在玩家接近门时出现僵尸。在这种情况下,关卡设计师会放置一个触发器对象,可以检测玩家何时接近并触发生成僵尸的动作。实现触发器的一种方法就是将其作为一个不可见的框,更新每一帧时检查与玩家的交集。

游戏对象模型

有很多的游戏对象模型,或者说有不止一种方式代表游戏对象。

类层次继承

一种游戏对象模型是在标准的面向对象的类层次结构中声明游戏对象,有时称为单一类层次结构,因为所有游戏对象都从一个基类继承。要用这种游戏模型,首先需要有一个基类。比如说,像这样的。

class Actor
{
   
public:
    virtual void Update(float deltaTime);
    virtual void Draw();
};

之后,就可以拥有不同的子类。

class PacMan : public Actor
{
   
public:
    void Update(float deltaTime) override;
    void Draw() override;
};

这种实现的一个缺点是每个游戏对象必须拥有基类的所有的属性和方法。但就像之前说的那样,在某些游戏对象上调用 Draw 是在浪费时间。
类层次继承

随着游戏功能的增加,问题可能会更为明显。例如游戏有两个角色是可以移动的,但是有的角色不能移动。如果把移动的代码放到基类 Actor 中,但又不是每个对象都可以移动。按照计算机界的环境法则,表达力不够,就加一层。那么可以在再编写 MovingActor,但这无疑会使得类继承上变得更加复杂。

更进一步地,当两个兄弟类稍后需要在它们之间共享特征时,一个庞大的类层次结构可能导致更大的困难。例如,侠盗猎车手的游戏可能会有一个 Vehicle 类。从这个类中,创建两个子类可能是有意义的:LandVehicle(用于穿越陆地的车辆)和 WaterVehicle(用于水上交通,如船)。

那么如果哪一天想不开,想要有水陆两栖车。由于 C++ 允许多继承,所以一种解决方法是定义一个 AmphibiousVehicle 同时继承 LandVehicleWaterVehicle。多继承也意味着 AmphibiousVehicle 沿着两条不同的路径从 Vehicle 继承。这种类型的层次结构(称为菱形继承)可能会导致问题,因为子类可能会继承虚函数的多个版本。因此,通常建议避免采用多继承

组件化

越来越多的游戏为了避免使用庞大的继承体系,采取了基于组件化(component-based)的游戏对象模型。这种模型越来越流行,一个很重要的原因是 Unity 游戏引擎使用了这种模型。这种实现方案中,有一个游戏对象类,但是没有子类。采取的是“有一个”(has-a)组件的集合对象来实现需要的功能。

继承是“is-a”(是一个)的关系。若遵循里氏替换原则,有父类出现的地方,就可以用子类替换(“子类”也是一个“父类”)。

举个例子,就上面那张 Pic-Man(吃豆人) 的类继承图而言,PinkyGhost 的子类,Ghost 又是 Actor 的子类。如果采取基于组件的模型,Pinky 是一个 GameObject,包含4个组件:PinkBehaviorCollisionComponentTransformComponentDrawComponent

如果可以用谷歌,搜索吃豆人,可以在线玩这个游戏(google官方出品)。

组件化

这些组件都可以拥有自己的特定的属性和方法。例如,DrawComponent 可以用于处理在屏幕上绘制对象的功能,而 TransformComponent 用来存储游戏世界中游戏对象的位置和变化。

class GameObject
{
   
public:
    void AddComponent(
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值