c++中类似gamemaker的功能

GameMaker-like functionality in C++

本文关键字:功能 gamemaker c++      更新时间:2023-10-16

当我年轻的时候,我经常使用一个叫做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拥有可以从任何地方访问的系统变量和功能。时期。任何地方。我在考虑全局,但我知道那是糟糕的设计。我想有一个全局类,并有变量/函数作为静态的,但他们不能改变。我该怎么做呢?

  • var

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

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

使用模板

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

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

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

您最适合使用脚本语言,例如Lua,并且只在c++中编写必要的高性能组件。

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++来建模。