【问题标题】:GameMaker-like functionality in C++C++ 中的类似 GameMaker 的功能
【发布时间】:2011-12-17 13:01:55
【问题描述】:

在我年轻的时候,我经常使用一个叫做 Game Maker 的工具。我开始学习编程。我现在远远超出了这个范围,但回头看,它的一些功能和设计非常有趣。我想知道 - 我将如何使用 C++ 实现类似于此工具的功能? 我想知道:

  • 对象/类

Game Maker 有一个您将创建的“对象”列表,它们本质上只是从同一个基类派生的不同类(我现在称之为 GameObject)和一个名为“instance_create”的系统函数,它需要对象类型作为参数。 在 c++ 中,这看起来像这样(虽然语法上非常不正确):

class MyGameObject : GameObject
{
    //...
}
GameObject instance_create(class objecttype)
{
    objecttype newinstance = new objecttype();
    return newinstance
}
GameObject* gameobjectinstance = instance_create(MyGameObject);

我将如何实施?

  • 系统变量/函数

Game Maker 拥有可以从任何地方访问的系统变量和函数。时期。任何地方。我在考虑全局变量,但我知道这是糟糕的设计。我在想拥有一个全局类,并将变量/函数设为静态,但是它们不能被改变。我该怎么做?

  • 变量

Game Maker 只有一种数据类型 - var。它可以是一个字符串、一个整数、一个小数,任何东西。并且有系统函数可以在它们之间进行转换。

最后,如何在某种脚本中定义对象类型?比如,如果我想添加一种新类型的对象,创建一个新脚本?我不认为 C++ 可以在运行时创建对象类型,那我该怎么做呢?

【问题讨论】:

  • 必须是 C++ 吗? Lua 可能更合适。

标签: c++ object types game-maker


【解决方案1】:

使用模板。

template<typename T> GameObject* instance_create()
{
    return new T;
}
GameObject* gameobjectinstance = instance_create<MyGameObject>();

但是,您指定的设计非常有问题(充其量)并且绝对不适合 C++。您应该努力实现一个设计良好且适合该语言的系统,而不是从过去重新创建一个系统。

我特别认为,既然您提到了脚本的运行时解释,那么实际上 GameMaker 类和 C++ 类彼此无关。而且您绝对不能在运行时创建 C++ 类,也不能在运行时传递类型,也不能在运行时实例化模板。

您最适合简单地编写一种脚本语言,例如 Lua,并只用 C++ 编写必要的高性能组件。

【讨论】:

  • 谢谢,是的,我知道那个设计是“有问题的”。我可能不清楚,但我实际上不会使用这种设计,我只是想知道它。但是使用脚本创建对象类型实际上是我将来可能会做的事情。
  • @Keelx:只要您将“类型”定义为 C++ 类以外的内容,就没有什么能阻止您通过脚本创建类型。您只需要使用由另一种语言提供或自己编写的机制。
【解决方案2】:

Game Maker 使我们能够通过“对象”控制游戏功能,每个对象都由“事件”组成,这些“事件”在游戏中的特定时间被触发。在事件中是“动作”。首先,值得注意的是,将 Game Maker 开发与 C++ 进行比较就像比较粉笔和奶酪。但是,从理论上讲,我想您可以在 C++ 中镜像 GM 功能(尽管效率很低),如下所示:

基础对象类可能如下所示:

class CObjectBase
{
public:
    CGameSprite* sprite;
    int          x, y;
    ...

    virtual void onEventCreate( void ) {};
    virtual void onEventDestroy( void ) {};
    ...
    virtual void onEventKeyPressedUp( void ) {};
    virtual void onEventKeyPressed...
    ...
    ... (there are lots of these)

    // The draw event in GM (from memory) had in-built functionality:
    virtual void onEventDraw( void ) 
    {
        CGameEngine::getSingleton()->DrawSpriteAtLocation( sprite, x, y );
    }
};

您将从此类派生并覆盖与您的对象相关的函数(“事件”)(构成这些函数的语句是您的“动作”)。然后会有某种对象实例管理器单例类,它保存当前“房间”中所有对象实例的列表,并循环遍历每一帧(并处理实例化),通过调用它们各自的函数来触发相关事件。

有趣的是,这实际上大致说明了为什么像 Game Maker 这样的系统缺乏一定程度的效率。为了保持对开发人员开放的选项,存在额外的、不必要的开销。所有对象派生自的臃肿基础对象在特定情况下通常是多余的。例如,假设一个对象在 50 个事件中只使用了两个事件——即使它们没有被使用,对象管理器仍然盲目地检查所有这些其他事件。显然可以进行优化,但总体而言,引擎的广度最终会导致性能下降。

至于与单个“var”类型相关的查询,正如已经说过的,这更多是脚本的特征,而不是 C++。这证明了 Game Maker 不能简单地由 C++ 单独建模。

【讨论】:

  • 已经很久了,Singleton 还是-1。
  • 对不起,但这还不足以成为 -1 IMO 的理由。答案是否有错误,除了你对单身概念的反感吗? (我可能会补充一点,这实际上只是为了说明目的)
  • 似乎提倡有史以来设计的最永久残废的“模式”之一对于-1来说当然足够了。
猜你喜欢
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2014-11-27
  • 2011-01-25
  • 2013-04-23
相关资源
最近更新 更多