Skip to content

Interacting with game objects

Thomas Cashman edited this page Jul 9, 2016 · 1 revision

To prevent slowing down your game's frame rate, all scripts are invoked on a separate thread pool of script executors.

GameScriptingEngine

However, in more complex scripts you'll want to interact with objects on the game's thread, e.g. move a character. To support this, miniscript provides the GameFuture class that be extended to implement interactions with the game. In the following example we'll move a character using a script.

First let's implement our character class.

public class GameCharacter {
	public int x, y;
	public int speed = 4;

	public GameFuture moveTo(float x, float y) {
		return new MoveFuture(this, x, y);
	}
}

Next we'll implement our game future for moving the character. We'll call this MoveFuture. The most important method is the update(delta) method. This is called on the game thread and must return true when the future has been completed.

public class MoveFuture extends GameFuture {
	private final GameCharacter gameCharacter;
	private final float targetX, targetY;

	public MoveFuture(GameCharacter gameCharacter, float targetX, float targetY) {
		super();
		this.gameCharacter = gameCharacter;
		this.targetX = targetX;
		this.targetY = targetY;
	}

	@Override
	protected boolean update(float delta) {
		if(gameCharacter.x < targetX) {
			gameCharacter.x += speed;				
		} else if(gameCharacter.x > targetX) {
			gameCharacter.x -= speed;
		}
		if(gameCharacter.y < targetY) {
			gameCharacter.y += speed;				
		} else if(gameCharacter.y > targetY) {
			gameCharacter.y -= speed;
		}
		return gameCharacter.x == targetX && gameCharacter.y == targetY;
	}

	@Override
	protected void onFutureSkipped() {}

	@Override
	protected void onScriptSkipped() {}
}

Now let's run a script (in Groovy) that moves the character.

GameCharacter gameCharacter = new GameCharacter();

//Bind the variable 'player' to the GameCharacter instance we want to move
ScriptBindings scriptBindings = new ScriptBindings();
scriptBindings.put("player", gameCharacter);

scriptingEngine.invokeScript("player.moveTo(50, 50);", scriptBindings);

However, since the movement is occurring on the game thread. The script will finish immediately. To prevent this from happening, GameFuture has a method called waitForCompletion() that can be called in the script to block the script's execution until the future on the game thread has finished (update returned true).

scriptingEngine.invokeScript("player.moveTo(50, 50).waitForCompletion();", scriptBindings);

The following diagram explains the flow of what is occurring on the scripting and game threads.

waitForCompletion()