Giter VIP home page Giter VIP logo

secret-island's Introduction

Haydn's Phaser3/TypeScript Starter Template

Overview

A starter template that adds TypeScript, dependency injection, events, a components system, and other useful utilities to Phaser 3.

Prerequisites

This project uses the following dependencies:

  • Node/Npm
  • Yarn

Installation

To install it you'll need to clone the repo and compile the assets:

git clone https://github.com/BadMojoVeryBad/phaser3-typescript-starter-template.git
cd phaser3-typescript-starter-template
yarn
yarn prod

You will then be able to serve the /dist directory with a web server and view the game!

Documentation

Underneath it's just Phaser 3, so you can use it how you would usually would as per the Phaser docs, examples, and Rex notes. However, there's a few design/architecture concepts that are used in this template that are worth looking at:

Linting

To lint your code, run the yarn command:

yarn lint

To automatically fix code errors:

yarn fix

Debugging/Developing

You can watch the codebase for changes with thw watch command:

yarn watch

Tests

This template has jest built in. You can run unit tests:

yarn test

Bootstrapping the Game

A Phaser3 game is a bunch of scenes, and in our case components as well (I'll get to that!). We tell the framework about our scenes and components in src/game/bootstrap.ts:

public bootstrap(): void {
    // Add scenes to the game here.
    this.addScene('init', Init);

    // Add components to the game here.
    this.addComponent('robot', Robot);
    this.addComponent('ground', Ground);

    // Add other dependency injection bindings here.
    this.bind<LoggerInterface>('LoggerInterface', Logger);
}

As you can see, you can add scenes and components, as well as other services using the bind() method.

Configuring the Game

Phaser 3 has it's own game config. There also some other config to set with this framework. You can find these in the src/config directory.

Components

The biggest addition to Phaser 3 in this template/framework is the concept of components. Components are small sections of a scene. They have access to the scene and therefore all of the Phaser 3 API, so anything you can do in a scene, you can do in a component. They also can be nested in a tree structure.

Create compomenents in src/game/components. They will look like:

import Component from '../../framework/component';

@injectable()
export default class ChildComponent extends Component {

    ...

Then register it in the src/game/bootstrap.ts:

import ChildComponent from './components/childComponent';

public bootstrap(): void {
    ...

    this.addComponent('childComponent', ChildComponent);

    ...

Now you can add it to scenes. Make sure if your scene has components, to call this.createComponents() and this.updateComponents(time, delta):

import { Scene } from '../../framework/scene';

export default class Init extends Scene {

    constructor() {
        super('init');
    }

    public init(): void {
        this.addComponent('childComponent');
    }

    public create(): void {
        this.createComponents();
    }

    public update(time: number, delta: number): void {
        this.updateComponents(time, delta);
    }

Now when that scene is run, everything in the component's create() method will run with the scene's create() method, and the component's update() method will run in the update() method.

Components also have before and after methods:

public beforeCreate(): void {
    // To be overridden.
}

public create(): void {
    // To be overridden.
}

public afterCreate(): void {
    // To be overridden.
}

public beforeUpdate(): void {
    // To be overridden.
}

public update(): void {
    // To be overridden.
}

public afterUpdate(): void {
    // To be overridden.
}

Finally, components can be nested. call addComponent() in a component's init() method:

import Component from '../../framework/component';

@injectable()
export default class ChildComponent extends Component {

    public init(): void {
        this.addComponent('anotherComponent');
    }

Dependency Injection

We use InversifyJS to do dependency injection (DI). To use it, create an injectable() service:

import { injectable } from 'inversify';

@injectable()
export default class Logger implements LoggerInterface {

    ...

Next, bind the service to the DI Container in src/game/bootstrap.ts:

public bootstrap(): void {
    ...

    this.bind<LoggerInterface>('LoggerInterface', Logger);

    ...
}

Then you can inject that dependency into components, and any other class created using dependency injection:

@injectable()
export default class ChildComponent extends Component {
    private ground: Phaser.GameObjects.Rectangle;
    private logger: LoggerInterface;
    private events: EventsInterface;

    constructor(@inject('LoggerInterface') logger: LoggerInterface) {
        super();

        // use 'logger' however you like.
    }

    ...

Logging

This template has logging. To use it, inject the logger into your components:

@injectable()
export default class ChildComponent extends Component {
    private logger: LoggerInterface;

    constructor(@inject('LoggerInterface') logger: LoggerInterface) {
        super();

        this.logger = logger;
    }

    public create(): void {
        // Log stuff!
        this.logger.info('Running "create()" for "ChildComponent".');

        ...

Events

This template has a custom events interface. This means you can use events, even when the Phaser 3 scene is inaccessible.

To use it, inject the service into your components (or wherever you want!).

@injectable()
export default class ChildComponent extends Component {
    private logger: EventsInterface;

    constructor(@inject('EventsInterface') events: EventsInterface) {
        super();

        this.events = events;
    }

    public create(): void {
        // Fire events!
        this.events.fire('child_created', 'some data');

        ...

You can then listen to events elsewhere:

@injectable()
export default class OtherComponent extends Component {
    private logger: EventsInterface;

    constructor(@inject('EventsInterface') events: EventsInterface) {
        super();

        this.events = events;
    }

    public create(): void {
        // Listen to events.
        this.events.on('child_created', (data) => {
            console.log(data); // 'some data'
        });

        ...

secret-island's People

Contributors

haydn-smith avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.