在Construct中学习JavaScript,第11部分:构造器API

83次阅读
没有评论

共计 6688 个字符,预计需要花费 17 分钟才能阅读完成。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

这是 在 Construct 中学习 JavaScript教程系列的第 11 部分。这部分从第 10 部分继续。因此,如果错过了,请查看 在 Construct 中学习 JavaScript,第 10 部分:标准库

在本指南中,我们已经涵盖了 JavaScript 编程语言的一些内置特性——也被称为 API——以及触及了一些浏览器 API。现在我们将介绍构造器提供的 API。这些部分是针对构造器的,因此在其他平台或工具中,即使它们使用 JavaScript,这些 API 可能不可用或工作方式不同。然而,了解如何使用构造器自己的 API 仍然很有用,因为我们正在使用构造器,这使我们能够编写使用构造器功能(如精灵)的代码。许多平台也提供它们自己的特定 API,这还展示了如何与另一套 API 进行交互。

移动精灵

我们可以通过在按钮被点击时移动精灵来使用 JavaScript 编码在构造器中执行的最简单任务之一。我们将回到在事件表中使用代码片段来实现这一功能。下载项目并使用构造器打开它。它提供了一个精灵和一个按钮,以及一个按钮被点击触发器。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API
Download now

打开事件表 1 标签,以便可以看到按钮:点击触发。在这里,我们将在动作位置添加一段 JavaScript 代码以移动精灵。但在那之前,让我们解释一下构造器 API 的一些细节。

运行时

通过事件表中的脚本,构造器自动提供两个内置变量。这些是:

  • runtime – 代表构造器运行时,即推动您的项目运行的整个游戏引擎。这通常是您在 JavaScript 中访问构造器功能的主要方式。

  • localVars – 代表事件表中任何在作用域内的局部变量。这允许您从 JavaScript 获取和设置这些变量的值,这对于在事件表之间传递值非常有用。

我们现在暂时不需要localVars – 我们将专注于runtime

我们可以查看浏览器控制台中 runtime 的外观。在点击事件中添加一个脚本,使用以下代码:

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

这将将内置的 runtime 变量记录到浏览器控制台。预览项目,点击按钮,并检查控制台。您应该能够展开它并看到各种属性和方法。

内置的 runtime 变量是一个名为 IRuntime 的类。它拥有的每个属性和方法都在 手册的脚本部分 进行了记录。您可以 在这里找到 IRuntime参考,它涵盖了您在控制台中看到的一切。在使用之前查阅此文档以检查可用的属性和方法及其用法是一个好主意。然而,查看控制台中的内容也是一种快速探索某物及其功能的方法。

对象和实例

项目中的所有对象——即项目栏中 Object 类型下的所有内容——在 runtime.objects 下表示。例如,runtime.objects.Sprite表示项目栏中的 Sprite 对象类型。

重要的是要注意 runtime.objects.Sprite 指的是对象类型。这与对象实例不同。如果您有 10 个 Sprite 实例,那么仍然只有一个 Sprite 对象类型,有 10 个实例。对象类型具有名称等属性,而实例具有位置和大小等属性。常见的错误是混淆它们并尝试访问对象类型的坐标。但对象类型没有位置——只有实例有。

因此,如果我们要获取或更改精灵实例的位置,我们必须首先获取已经在布局中的 Sprite 对象类型的实例。如果只有一个,最简单的方法是调用 object 类型上的getFirstInstance(),即runtime.objects.Sprite.getFirstInstance()。这将返回一个具有位置、大小等属性的实例。

更改事件表中的 JavaScript 代码,如下所示:

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

这将获取布局中已放置的 Sprite 对象类型的第一个实例,并将其存储在变量 inst 中。然后,它将实例的 X 坐标增加 10,这将使它向右移动。尝试预览项目并点击按钮 – 精灵实例向右移动!

# 请记住,像 **runtime.objects.Sprite.x += 10** 这样的代码不会起作用:对象类型没有位置,因此没有 **x** 或 **y** 属性。只有实例有,因此您必须首先获取实例,然后修改那个。

文档

再次查阅文档非常有用,看看我们使用了什么。

runtime.objects.Sprite是一个名为 IObjectClass 的类(因为它也用于家族,即“对象类”意味着“对象类型或家族”)。在链接的文档中,您可以找到 getFirstInstance() 方法被列出和记录,以及各种其他属性和方法。

返回的实例包括 IWorldInstance 的属性和方法(因此命名为对象在布局中出现时是游戏“世界”的一部分,而像字典或数组这样的对象不是)。在链接的文档中,您可以找到 xy被列出和记录,以及各种其他属性和方法。

# 实际上,Sprite 实例具体是名为 **ISpriteInstance** 的类,它同时包括 **IWorldInstance** 和 **IInstance** 的属性和方法。这是使用 JavaScript 中的一个称为继承的特性完成的。然而,我们尚未在本指南中覆盖这一主题。目前,您可以将其视为将几个类的属性和方法组合到一个类中。这是共享不同类的功能的一种有用方式 - 例如,所有出现在游戏世界中的内容都是 **IWorldInstance**,因此具有位置。

我们强调文档,因为它是一个重要的参考,用于查找您可以从 JavaScript 使用构造器功能。编辑器通常会尝试在您键入时自动补全名称,但由于 JavaScript 是一种动态语言,它通常无法确定实际可用的属性和方法是什么,因此它倾向于建议所有内容。要了解真正可用的内容以及您可以实际使用的,您需要查阅文档。在常规使用后,您将开始记住常见的属性和方法,不需要一直查找它们。

使用脚本文件

在之前的示例中,运行时 在事件表中提供自动提供。在脚本文件中,这个变量不会自动提供。相反,有另一种方式访问运行时 API。让我们通过使用脚本文件重新构建相同的示例,以展示这种差异。

下载并打开项目,如下所示,并在 Construct 中打开它。这次它提供了一个精灵和一个按钮,没有事件,而只是一个模板 main.js 脚本。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API
Download now

main.js 脚本看起来像这样:

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

runOnStartup 是 Construct 提供的一个特殊全局函数,允许您的脚本访问 运行时 接口。您传递一个函数,它将在 运行时 接口可用时调用它,将它作为第一个参数传递。

通常,脚本文件中的代码在页面加载时运行 – 这可能是在 Construct 开始加载项目之前 – 所以无法立即访问 运行时。这种方法为您提供了一种在可用时访问它的方法。

然而,当 运行时 运行其回调时,项目仍在加载中。因此,在这一点上,你仍然没有什么可以做的。最好的做法是在“beforeprojectstart”事件之前等待,该事件在事件表中的“On start of layout”触发器之前触发 – 即在实际运行第一个布局之前。

运行时事件

请记住,从之前的部分我们使用了以下模式:

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

这意味着“当 obj 上的事件发生时,调用 func”。Construct 的 API 也使用此模式,具有特定于 Construct 的事件。运行时提供了多个事件,也出现在 IRuntime 文档 中,包括“beforeprojectstart”。因此,我们可以在事件发生时调用函数:

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

使用以下代码为 main.js 来监听此事件。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

预览项目,您应该在控制台中看到“On before project start”消息。

注意:

  • 我们添加了一个名为 OnBeforeProjectStart 的函数,该函数接受 runtime 作为参数。
  • 我们为 addEventListener 中的函数使用箭头函数。这反过来调用 OnBeforeProjectStart(runtime),将runtime 传递给它。

简而言之,这意味着在“beforeprojectstart”事件发生时,我们的 OnBeforeProjectStart 函数与 runtime 一起被调用。同时注意我们现在有了一个简短的事件序列:当加载页面时,runOnStartup的回调将运行;然后等待“beforeprojectstart”事件;当它触发时,它调用OnBeforeProjectStart。这种处理 JavaScript 事件的方式很常见,因此值得熟悉它。

按钮点击事件

OnBeforeProjectStart 函数中,运行时已经加载完成,现在可以访问诸如对象类型和实例等事物。

我们首先要做的是检测按钮是否被点击。与之前一样,我们可以使用以下方式获取布局中的第一个 Button 对象实例:

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

再次,实例使用 addEventListener 方法处理事件。在 IButtonInstance 文档 中指出,“click”事件在按钮被点击时触发。因此,我们可以像这样监听点击事件(显示 main.js 中的所有代码):

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

预览此项目,您应该在单击按钮时在控制台中看到消息出现。这一次,我们只使用了 JavaScript 代码 – 没有涉及事件表!

移动精灵实例

拼图的最后一块是实际上移动布局中的精灵实例。这可以与我们在 OnButtonClick 函数中以相同方式完成,只是我们的代码现在在 OnButtonClick 函数中:

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

预览项目,现在当您单击按钮时,精灵将向右移动。我们以纯代码的方式重建了之前的内容,而没有使用事件表!

键盘控制

让我们使用 JavaScript 代码实现简单的四个方向移动,使用箭头键。下载并打开以下项目在 Construct 中。这次它只提供了一个精灵实例(没有按钮),键盘对象已添加到项目中,并且 main.js 有足够的代码来调用OnBeforeProjectStart

在 Construct 中学习 JavaScript,第 11 部分:构造器 API
Download now

实现键盘控制意味着检查四个箭头键是否按下,并根据相应的方向移动精灵。这需要在每一帧重复进行以保持移动。在 Construct 事件表中,可以使用“每帧”系统条件运行动作 – 也称为像时钟一样滴答作响 – 来持续每一帧。在 JavaScript 代码中,这由“tick”运行时事件处理。可以像这样处理它(显示 main.js 中的完整代码):

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

请注意,我们正在使用与之前相同的方式来处理另一种类型的事件 – 这次“tick”事件调用 OnTick,并再次将runtime 作为参数传递。

现在,我们可以在 OnTick 中添加的任何代码都会在每帧运行。我们可以在这里添加一些代码来检查哪些箭头键被按下,并相应地移动精灵。

处理键盘输入

注意已将键盘对象添加到项目中。这用于接收键盘输入。

键盘对象的属性和方法可以通过 runtime.objects.Keyboard 访问,但由于键盘输入通常被使用,runtime.keyboard也作为快捷方式提供。

键盘对象是全局的,没有实例。这意味着其属性和方法直接在 runtime.keyboard 上访问。无需调用getFirstInstance()

键盘脚本接口 提供了一个方法 isKeyDown(),我们可以使用它来检测在调用时当前按下的键。键由字符串指定。完整的列表可以 在这个 MDN 页面上 找到,但我们需要的是箭头键,它们由字符串 “ArrowLeft”“ArrowRight”“ArrowUp”“ArrowDown”表示。

因此,调用 runtime.keyboard.isKeyDown("ArrowLeft") 将返回一个布尔值,指示左箭头键当前是否被按下。如果情况如此,那么我们可以将精灵向左移动。

OnTick 函数中添加以下代码。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

请注意,有四个“if”语句检查四个箭头键是否按下。如果键被按下,精灵实例的位置会在那个方向上移动。预览项目并尝试按下箭头键。精灵会四处移动!

帧率无关性

通过每次滴答移动固定数量的像素来移动对象的一个问题是速度依赖于帧率。例如,在 120Hz 显示系统上,精灵的移动速度将比在 60Hz 显示系统上快一倍,因为 120Hz 显示系统的滴答次数比 60Hz 显示系统快一倍。这个问题是教程中详细解释的 delta-time 和帧率无关性 的内容。

解决方法是通过每次滴答移动位置,而不是 delta-time(这个帧的时间秒)乘以每秒像素数。在 JavaScript 中,runtime.dt返回当前的 delta-time,这与 Construct 事件表中的 dt 表达式相同。尝试以下代码进行OnTick

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

现在,无论帧率如何,精灵以每秒 400 像素的恒定速度移动,因为它是通过距离 400 * runtime.dt 移动的。

如之前链接的教程中所指出的,Construct 的内置行为如 8 方向会自动处理 delta-time。但是,当使用 JavaScript 代码或事件块进行移动时,您需要考虑 delta-time 以确保在不同设备上移动工作一致。使用 delta-time 还可以实现有用的时间相关效果,如暂停或慢动作,因为这些通过修改 dt 的值来工作。

您还可以查看 与 Construct 一起提供的简单键盘移动示例,该示例还处理更改精灵角度。

更多示例

让我们简要介绍一下如何使用 Construct 的 API 进行更多操作。下载以下项目并在 Construct 中打开它。这提供了一个使用 JavaScript 代码修改精灵的模板 – 有 12 个精灵,包含鼠标对象,main.js 预填充了代码以处理页面任意位置的点击,但在点击发生时还没有做任何事情。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

注意这个项目使用 文档 的“click”事件来检测页面任意位置的点击。

让我们尝试在 OnClick 函数中输入一些不同的代码。

设置随机角度

IObjectClass方法的 instances() 可以用来迭代对象类型的所有实例。简而言之,这意味着你可以使用它配合 ’for-of’ 循环对每个实例重复执行。

# 这个方法是一个生成器函数。我们在这个指南中没有介绍这些,但请注意,这些类型的方法在文档中用标记 *****,例如 ***instances()**。这本质上意味着这个方法可以与 'for-of' 循环一起使用,或者与扩展 **...** 语法一起使用。

将每个实例的 angleDegrees 设置为 0 -360 之间的随机数将使每个实例指向随机方向。尝试在 OnClick 函数中使用以下代码:

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

# ** 角 ** 度属性使用弧度。**angleDegrees** 属性使用度数,有时更方便,我们在这里使用它。

预览项目。现在每次点击时,所有的小猪都会变成随机角度!

值得注意的是,扩展 ... 操作符也可以用来获取 ’for-of’ 迭代的所有内容的数组。下面的示例展示了获取所有 12 个精灵实例的数组并将其打印到控制台。然后它还将最后一个精灵设置为随机角度,演示了如何访问数组。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

对齐精灵

以下代码为每个实例的位置增加 30,将它们的 X 和 Y 坐标设置为当前值,使它们排成对角线。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

随机偏移

以下代码将每个精灵实例的位置随机偏移 -10 到 10,如果你反复点击,它们会四处晃动。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

将随机实例移动到鼠标位置

以下代码将在点击时随机选择一个实例并将其移动到鼠标位置。

在 Construct 中学习 JavaScript,第 11 部分:构造器 API

在这个示例中:

  • 使用扩展 ... 操作符获取所有实例的数组
  • Math.random() * arr.length获取一个随机数,直到数组的长度,但这个数包括小数。我们想要一个整数,所以我们使用 Math.floor(Math.random() * arr.length) 来获取一个随机的数组索引并选择一个随机实例。
  • 与使用键盘类似,runtime.mouse访问 Mouse 脚本接口,前提是项目中添加了 Mouse 对象。这提供了getMouseXgetMouseY方法来获取某个层上的鼠标位置。在这个例子中,层作为索引给出,因此传递 0 作为第一个(也是唯一的)层。

尝试自己想出改变精灵实例的方法!

结论

在这部分,我们介绍了:

  • 在事件表中的脚本中使用内置的 runtime 变量
  • 通过 runtime.objects 访问对象类型和实例
  • 参考 Construct 的文档以获取可用的 API
  • 在脚本文件中使用 runOnStartup 来获取 runtime 的访问权限
  • 使用 addEventListener 处理运行时事件,包括 "beforeprojectstart" 和 "tick" 事件
  • 处理实例事件,如按钮点击
  • 使用键盘输入控制精灵
  • 使用 JavaScript 代码修改多个精灵的各种示例

深入学习

如果你想要深入了解,你可以在 Construct 手册的脚本部分学习更多关于 Construct API 的知识:

第 12 部分

当你准备好继续时,请转到下一部分:在 Construct 中学习 JavaScript,第 12 部分:模块!

正文完
 0
评论(没有评论)