Learn JavaScript in Construct, part 11: Construct APIs

14

Index

Attached Files

The following files have been attached to this tutorial:

.c3p

move-sprite.c3p

Download now 62.55 KB
.c3p

using-script-file.c3p

Download now 62.64 KB
.c3p

keyboard-controls-template.c3p

Download now 62.62 KB
.c3p

modify-sprites-template.c3p

Download now 62.92 KB

Stats

9,274 visits, 22,903 views

Tools

Translations

This tutorial hasn't been translated.

License

This tutorial is licensed under CC BY-NC 4.0. Please refer to the license text if you wish to reuse, share or remix the content contained within this tutorial.

Published on 3 Dec, 2021. Last updated 16 Dec, 2021

Using a script file

The previous example relied on the fact runtime is provided automatically in scripts in event sheets. In script files, this variable is not provided automatically. Instead there's another way to access the runtime APIs. Let's rebuild the same thing with a script file instead to demonstrate the difference.

Download the project below and open it in Construct. This time it provides a sprite and a button, no events, and just a template main.js script.

.C3P

using-script-file.c3p

Download now 62.64 KB

The main.js script looks like this:

runOnStartup(runtime =>
{
	
});

runOnStartup is a special global function Construct provides to give your script access to the runtime interface. You pass it a function and it will call it as soon as the runtime interface is available, passing it as the first parameter.

Normally code in a script file runs as soon as the page loads - which can be before Construct has even started loading the project - so runtime cannot be accessed immediately. This method gives you a way to access it as soon as it's available.

However the project is still loading when runOnStartup runs its callback. So there's still not much you can do at that point. The best thing to do is wait for the "beforeprojectstart" event, which fires just before the "On start of layout" trigger in an event sheet - i.e. just before the first layout actually starts running.

Runtime events

Remember from previous parts we used the following pattern:

obj.addEventListener(event, func)

This means "when event happens on obj, call func". Construct's APIs also use this pattern, with events specific to Construct. The runtime provides several events which are also in the IRuntime documentation, including "beforeprojectstart". So we can have a function called when this event happens using:

runtime.addEventListener("beforeprojectstart", someFunction);

Use the following code for main.js to listen for this event.

runOnStartup(runtime =>
{
	runtime.addEventListener("beforeprojectstart", () => OnBeforeProjectStart(runtime));
});

function OnBeforeProjectStart(runtime)
{
	console.log("On before project start");
}

Preview the project and you should see the "On before project start" message appear in the console.

Notice how:

  • We have added a function named OnBeforeProjectStart which takes runtime as a parameter.
  • We use an arrow function for the function in addEventListener. This in turn just calls OnBeforeProjectStart(runtime), which passes along runtime.

In short this means our OnBeforeProjectStart function is called with runtime when the "beforeprojectstart" event happens. Also note how we now have a short sequence of events: when loading the page, runOnStartup will run its callback; that then waits for the "beforeprojectstart" event; when that fires it calls OnBeforeProjectStart. This kind of pattern is common when handling events in JavaScript, so it's worth getting familiar with it.

Button click event

In the OnBeforeProjectStart function, the runtime has finished loading, and now things like object types and instances can be accessed.

The first thing we want to do is detect when the button is clicked. As before we can get the first instance of the Button object in the layout with:

let buttonInst = runtime.objects.Button.getFirstInstance();

Once again instances use the addEventListener method for handling events. In the IButtonInstance documentation it notes the "click" event fires when the button is clicked. So we can listen for click events like this (showing all the code for main.js):

runOnStartup(runtime =>
{
	runtime.addEventListener("beforeprojectstart", () => OnBeforeProjectStart(runtime));
});

function OnBeforeProjectStart(runtime)
{
	let buttonInst = runtime.objects.Button.getFirstInstance();
	buttonInst.addEventListener("click", () => OnButtonClick(runtime));
}

function OnButtonClick(runtime)
{
	console.log("Button clicked!");
}

Preview this project and you should see the console message appear when you click the button. This time we've done everything with JavaScript code only - no event sheet is involved!

Moving the sprite instance

The last piece of the puzzle is to actually move the sprite instance in the layout. This can be done the same way as before, just with our code now in the OnButtonClick function:

function OnButtonClick(runtime)
{
	let inst = runtime.objects.Sprite.getFirstInstance();
	inst.x += 10;
}

Preview the project, and now the sprite will move to the right when you click the button. We've re-built what we had previously, but with pure code.

Next Tutorial In Course

Learn JavaScript in Construct, part 12: Modules 14:40

Learn how to organise code with JavaScript Modules, including how they are used in Construct.

  • 3 Comments

  • Order by
Want to leave a comment? Login or Register an account!
  • How can I pick an instance by an instance variable?

    • Just in case this is still relevant (for anyone with the same question): check out the fairly new example titled "Generator Function" for one way; but using generator functions is not required, you can just do that too:

      for (const inst of runtime.objects.SomeObjectType.instances())

      {

      if (inst.instVars.SomeInstanceVariable === 42) {...}

      }

  • does not help