【问题标题】:calling script_execute with a variable使用变量调用 script_execute
【发布时间】:2012-11-24 21:14:58
【问题描述】:

我正在使用 GameMaker:Studio Pro 并尝试执行存储在变量中的脚本,如下所示:

script = close_dialog;
script_execute(script);

它不起作用。它显然是在寻找一个名为“脚本”的脚本。有谁知道我怎么能做到这一点?

【问题讨论】:

标签: gml game-maker


【解决方案1】:

这个问题现在已经很老了,但万一其他人最终通过谷歌来到这里(就像我一样),我发现这里的东西效果很好,并且不需要任何额外的数据结构作为参考:

scriptToCall = asset_get_index(scr_scriptName);
script_execute(scriptToCall);

此处的第一行创建变量 scriptToCall,然后为它分配 Game Maker 的内部 ID 号,用于您要调用的脚本。这允许 script_execute 正确地从 ID 中找到脚本,如果您尝试将包含脚本名称的字符串传递给它,这将不起作用。

我使用它来定义在特定情况下应从包含的 txt 文件中调用哪些脚本,因此需要将字符串转换为可寻址的脚本 ID!

【讨论】:

    【解决方案2】:

    您似乎对 Game Maker 的工作方式有些困惑,所以我会在解决实际问题之前尝试解决这个问题。

    GML 是一个头脑简单的野兽,它只知道两种数据类型:字符串和数字。其他所有内容(对象、精灵、脚本、数据结构、实例等)在您的 GML 代码中都用数字表示。

    例如,您可能有一个名为“Player”的对象,其中包含各种花哨的事件,但对代码而言,Player 只是一个常数,您可以(例如)使用show_message(string(Player)); 打印出来

    现在,函数script_execute(script) 将应该执行的脚本的ID 作为参数。那个ID只是一个普通的号码。 script_execute 将在某个内部表中找到具有该 ID 的脚本,然后运行该脚本。

    换句话说,如果您碰巧知道close_dialog 的 ID 是 14,那么您也可以调用 script_execute(14),而不是调用 script_execute(close_dialog)(尽管这是不好的做法,因为它使代码难以了解并应对 ID 更改)。

    现在应该很明显,首先将close_dialog 的数值分配给一个变量,然后在该变量上调用script_execute 是完全可以的。最后,script_execute 只关心传递的数字,而不关心这个数字来自的变量的名称。

    如果您想得有点远,您可能想知道当时是否需要script_execute,或者您是否可以这样做:

    script = close_dialog;
    script();
    

    在我看来,在语言中允许这样做是非常好的,但它不起作用 - 函数调用运算符实际上确实关心你尝试调用的东西的名称。

    现在,有了这个背景,我们来回答您的实际问题。如果close_dialog 实际上是一个脚本,那么您建议的代码将可以正常工作。如果它是扩展函数(或内置函数——我不拥有 Studio,所以我知道什么),那么它实际上没有 ID,你不能用 script_execute 调用它。事实上,你甚至不能将close_dialog 分配给一个变量,因为它在 GML 中没有任何值——你所能做的就是调用它。不过,要解决这个问题,您可以创建一个脚本(例如,close_dialog_script,它只调用close_dialog,然后您可以像上面一样使用它。

    编辑:由于它似乎无论如何都不起作用,请检查您是否有名称为 close_dialog 的其他资源(可能是按钮精灵)。这种冲突可能意味着close_dialog 为您提供了精灵的 ID,而不是脚本的 ID,而直接调用脚本仍然可以工作。

    【讨论】:

    • 感谢您的深思熟虑的帖子,但除了直接使用 id 之外,唯一有效的是我刚刚发布的答案。
    • 那可能是我糊涂了?我必须弄清楚为什么这不起作用。 :P
    • 我试了一下(在 GM 8.1 中),得到了我所期望的结果。如果我的游戏中有一个脚本 close_dialog,那么您在问题中编写的确切代码将调用该脚本。 show_message(string(close_dialog)) 在我的例子中显示 2,即脚本的 ID。如果这真的不适合你,那一定是因为 GM 8.1 和 GM Studio 之间发生了奇怪的变化。编辑:在这种情况下,编写一个按名称调用脚本而不是返回其ID的函数不是更好吗?
    • 它在 GMS 中绝对行不通。但是您编写一个按名称调用脚本的函数的想法可能确实更有意义:) 谢谢。
    【解决方案3】:

    在论坛上讨论了很多之后,我最终选择了这种方法。

    我写了一个脚本叫 script_id()

    var sid;
    sid = 6; //6 = scriptnotfound script :)
    
    switch (argument0) {
        case "load_room":
            sid = 0;
            break;
        case "show_dialog":
            sid = 1;
            break;
        case "close_dialog":
            sid = 3;
            break;
        case "scrExample":
            sid = 4;
            break;
    }
    
    return sid;
    

    所以现在我可以调用 script_execute(script_id("close_dialog"));

    我讨厌它,但在我看来,这比保留电子表格要好......

    【讨论】:

    • 至少使用脚本名称而不是数字.. 最重要的是,您需要使用字符串吗? - 如果您希望实际解析用户输入,则此方法很难扩展,最好在游戏开始时创建一个 ds_map() ,它将字符串作为键,数字作为值。然后可以通过(并执行脚本)获得该值:script_excecute(ds_map_find_value(SCRIPTMAP, "close dialog"))
    【解决方案4】:

    还有另一种方法,execute_string(); 应该是这样的:

    execute_string(string(scriptName) + "();");
    

    【讨论】:

    • execute_string 在 GameMaker: Studio 中不存在。它在 GameMaker 8.1 之后被删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 2019-04-26
    • 2013-08-11
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多