Last visited

About RabbitB

Thank you; I'll likely end up splitting responsibilities and create a state class that does the actual work, and keep BaseGame as just the constructor that essentially assembles the pieces to get it all running.

I'm looking to use Phaser to develop small embedded, interactive examples for game-dev articles I write on my website. I'm writing in Typescript, and so far I've gotten a basic program put together and running based on various online tutorials. I did however run into an issue that I managed to resolve myself, but being a traditional desktop developer that has minimal experience in either JS or Typescript†, I'm not sure exactly what's going on, and I'm hoping someone can give some insight on why this is happening, and if there's a better solution.
The issue I was running into, is that when calling methods from within my update callback, I kept getting `no method 'x' found` errors. The solution I found was adding the methods I wanted to call, to the `state` dictionary I was passing to the game engine. I'm sorry for the code dump, but I'm trying to demonstrate exactly what I ran into.
class BaseGame
{
game:Phaser.Game;
spaceKey:Phaser.Key;
mainState = {
preload: this.preload,
create: this.create,
update: this.update,
doStuff: this.doStuff, // These two required to be here if they're to be used
restartGame: this.restartGame // as callbacks or within other callbacks, like update()
};
constructor()
{
this.game = new Phaser.Game(400, 490, Phaser.AUTO, 'content');
this.game.state.add('main', this.mainState);
this.game.state.start('main');
}
preload(): void
{
// ... load assets here
}
create(): void
{
// ... do game setup here
// If this.doStuff isn't present in the mainState dictionary, then nothing ever happens, as the method can't be found by Phaser.
this.spaceKey = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
this.spaceKey.onDown.add(this.doStuff, this);
}
update(): void
{
if (...) // Conditions that require restarting
{
// If this.restartGame isn't present in the mainState dictionary, then we can't use it here; it'll return an error of `method not found`
this.restartGame();
}
}
doStuff(): void
{
// ... do whatever we need to do when SPACE is pressed.
}
restartGame(): void
{
this.game.state.restart();
}
}
window.onload = () => {
var game = new BaseGame();
}
As stated, the solution here was just to add the methods I want to call to the `state` dictionary I pass to the engine, but unfortunately I don't understand exactly what's going on here and why. Obviously the function references don't contain their full scope (the class they belong to), so when they are called, they're not found. Yet adding them to the `state` dictionary keeps that scope intact somehow, and allows me to continue to use instance variables like normal. I think that's where I'm really getting lost here.
Hopefully someone much more experienced with JS/Typescript can chime in and shed some light.
† Basically all my experience in JS and Typescript is from writing plugins for VS Code and doing minimal work for my website. Mostly either adapting 3rd party utilities to work with the CMS for my website (such as adding source-code highlighting through prism.js), or adding custom functionality myself, to say mimic extending the available markdown syntax. A good example is how embedded video (webm) has no markdown syntax in the CMS I use, so I wrote a function that runs on pageload, that looks for a custom string and a following url in the content of the page, and properly embeds the video found at the url, effectively extending the markdown syntax instead of requiring me to write the required html in every article I wish to embed something.