Skip to content

Latest commit

 

History

History
144 lines (86 loc) · 6.79 KB

View.md

File metadata and controls

144 lines (86 loc) · 6.79 KB

View

The View class is a container that represents an area of the game. Things such as the title screen, settings screen, levels, and similar things should be a View.

By default, FrostFlake manages a single View at a time, which is the root node of the scene graph. Views contain a collection of children Positionable objects and the tree of view children is crawled recursively for both the update and the drawing cycle.

The current view is available on the static game instance as follows:

FrostFlake.Game.view

To start a custom view, you create a custom class that extends the View class and set the current view instance to your new class as follows:

FrostFlake.Game.view = new Level1View();

NOTE: Views are intended to load the content they need, render and update their content during the gameplay loop, and unload completely when they are no longer active. Views are automatically destroyed by the engine when the active view is changed. Therefore, it is strongly recommended that you do not hold onto and recyle views!

Setting the view property on your frostflake instance will kick off the view Lifecycle.

Lifecycle

The View lifecycle starts when the active view is set on the FrostFlake instance like this:

FrostFlake.Game.view = new CustomView();

This action kicks off the following lifecycle:

  1. constructor: The constructor creates a new instance of the custom view. Avoid performing any logic in your view constructor, in most cases they should not be overridden.
  2. start: The start method is called automatically by the engine and kicks off the initialization process, which is asynchronous. The engine will wait for initialization to complete before beginning the update cycle. In most cases, you should not need to override this method.
  3. initialize: The asynchronous initialize method is where all asset loading and similar work should take place before the update cycle begins. Any assets used by game objects during the view's lifetime should be preloaded here. This guarantees that assets are available before they are needed in the gameloop.
  4. update: The update method is called every tick. This is where all frame-based logic should take place. The update cycle will not be called until the initialize method has completed it's work and all promises are resolved
  5. destroy: The destroy method is automatically called on the existing view when a new active view is set. This method should generally execute quickly and unload any assets no longer needed by the game.

For more information about the methods called during a view's lifecycle, see the View Methods section.

Create a Custom View

You will usually extend the View class to add screens, menus, or levels to your game. Here is an example of a custom view:

// imports go here

export default class CustomView extends View {

    // example asset to be loaded
    private readonly SPRITE_TEXTURE: string = "content/sprite.png";

    // example sprite
    private _sprite: Sprite;

    async initialize(): Promise<void> {

        // call the parent method
        await super.initialize();

        // async load a resource
        await Data.loadImage(this.SPRITE_TEXTURE);

        // create a new sprite object using the texture that was just loaded
        this._sprite = new Sprite(this.SPRITE_TEXTURE);

        // add the sprite to the view's children so it is updated and drawn
        this.addChild(this._sprite);
    }

    destroy(): void {
        super.destroy();

        // NOTE: children will be automatically destroyed in the parent method

        // OPTIONAL: unload the resource if it's no longer needed
        Data.removeItem(this.SPRITE_TEXTURE);
    }

    update(): void {
        super.update();

        // example frame logic, set rotation velocity when the
        // left mouse button is pressed
        if(FrostFlake.Game.input.buttonDown(Mouse.Left)) {
            this._sprite.velocity.rotation = 5;
        }
        else {
            this._sprite.velocity.rotation = 0;
        }
    }
}

Important View Methods

Note: It is critical to make sure you call the parent method for any method you override in your custom view. Failing to call things like super.update(); will result in many hard-to-diagnose bugs in your views!

constructor

The base constructor sets an initialized flag to false. The constructor for custom views should generally be empty.

addChild(positionable: Positionable): void

The addChild method adds a Positionable to the children collection, sets the parent property on the added child, and marks the collection as needing to be sorted for rendering order.

If the positionable to be added is already in the children collection, this method will throw an exception! This prevents tricky bugs such as double-updating of game entities.

You should always use the addChild method and never directly modify the children collection.

async initialize(): Promise

The asynchronous initialize method is where asset loading and potentially game object construction should happen. This method is automatically called by the engine and it will wait for all promises to resolve before beginning the update cycle.

clearChildren(): void

The clearChildren method calls removeChild on every child, removing it from the children collection and setting the child's parent to null.

destroy(): void

The destroymethod removes all children from the collection and sets their parent to null.

Override this method to perform any custom unloading of assets and game objects loaded during the initialize method or game loop.

destroyChild(positionable: Positionable): void

The destroyChild method removes a Positionable from the children collection, sets its parent to null, and calls destroy on the child.

removeChild(positionable: Positionable): void

The removeChild method removes a child from the children collection and sets its parent to null. It does not call destroy on the child Positionable.

start(): void

The start method is used by the engine to kick off the initialization process.

This method should generally not be overridden.

tryRemoveItem(item: any, list: Array): boolean

The tryRemoveItem method is called by removeChild and should generally not be called or overridden. Use the removeChild method to remove children from the view.

update(): void

The updatemethod is called by the engine every tick. The update method should be overridden to do frame-based game logic in your custom View.

The time delta is often needed for calculations in the update cycle. Frame time in FrostFlake is expressed in seconds. This is stored in the GameTime object available on the static game instance as follows:

FrostFlake.Game.time.frameSeconds