const HasScenesMixin = require('./HasScenesMixin')
const HasEntitiesMixin = require('./HasEntitiesMixin')
/**
* Scene is the base class for scenes, which can contain child Scenes, {@link Entity}s, and {@link Props}
*
* @mixes HasScenesMixin
* @mixes HasEntitiesMixin
* @abstract
*/
class Scene {
/**
* Create a new Scene with the specified options.
* @param {object} options The options for the GameEngine, composed of the properties.
* @property {Asset} asset The {@link Asset} to use for the Scene tiles
* @property {Object} parent The parent of this Scene
* @property {integer} x The x-coordinate in pixels relative to its parent (optional, default 0)
* @property {integer} y The y-coordinate in pixels relative to its parent (optional, default 0)
* @property {integer} z The z-coordinate relative to its parent (optional, default 0)
* @property {float} scale The current scale (zoom) where 1 = 100% (optional, default 1)
* @property {boolean} visible Set if this Scene is visible (optional, default true)
* @property {boolean} enableScroll Enable mouse scrolling (optional, default true)
*/
constructor (options = {}) {
// A Scene can have subscenes
HasScenesMixin(this, options)
// A Scene can have entities
HasEntitiesMixin(this)
// Asset is the graphical asset used for drawing this Scene.
// Usually, an asset will be divided up into 'layers' of a specified width and height.
// A Scene will display a large array of these layers for each layer, and a Scene may contain multiple layers.
// Layers are drawn in ascending order, and each layer be associated with a group of entities, based on the entity's z.
this.asset = options.asset
// The current X/Y from the origin of the container (the GameEngine, or the parent Scene)
this.x = options.x || 0
this.y = options.y || 0
// The Z index, in the stack of the container (the GameEngine, or the parent Scene)
this.z = options.z || 0
// The Parent container (the GameEngine, or the parent Scene)
this.parent = typeof (options.parent) === 'undefined' ? null : options.parent
// The visible flag. Invisible Scenes and their children are not drawn
this.visible = typeof (options.visible) === 'undefined' ? true : !!options.visible
// The scale and rotation settings for this Scene. This context affects all child scenes and entities also
this.scale = typeof (options.scale) === 'undefined' ? 1 : options.scale
this.rotate = typeof (options.rotate) === 'undefined' ? 0 : options.rotate
this.redraw()
}
/**
* Mark this scene to be redran.
*/
redraw () {
this._doredraw = true
this.redrawScenes()
this.redrawEntities()
}
/**
* Draw the Scene into the given context. You should override draw with your draw logic.
* @param {CanvasRenderingContext2D} context The context in which to draw
*/
draw (context) {
// If we're not marked for a redraw or we're invisible, return
if (!this._doredraw || !this.visible) return
// Save the context params
context.save()
// Reset the origin to our coordinates (so child entities are relative to us)
context.translate(this.x, this.y)
context.scale(this.scale, this.scale)
context.rotate(this.rotate)
// Scene Drawing Logic should go here.
// Restore the context params for the next thing being drawn
context.restore()
// Reset the redraw flag
this._doredraw = false
}
}
/**
* In PERSPECTIVE_OVERHEAD mode, a Scene will simply draw all tile levels, subscenes and entities in order from their z-coordinate.
*/
Scene.PERSPECTIVE_OVERHEAD = 1
/**
*In PERSPECTIVE_ANGLE mode, a Scene will draw all tile levels, subscenes and entities in order from their z and y coordinates modified their hotspot y coordinate.
*/
Scene.PERSPECTIVE_ANGLE = 2
module.exports = Scene