API Docs for:
Show:

File: src/renderer-layer.js

(function(root) {
    'use strict';

    /**
    * Represents a map tile layer to be rendered.
    * @class RendererLayer
    * @constructor
    * @param {Game} game - Game instance this obj is attached to.
    * @param {String} type - Type of `RendererLayer`. When created this object is merged with the value of `RendererLayer.Types[type]`.
    */
    var RendererLayer = function RendererLayer(game, type, settings) {
        this.game = game;
        this.type = type;
        var typeData = RendererLayer.Types[type];
        RL.Util.merge(this, typeData);

        for(var key in settings){
            if(this[key] !== void 0){
                this[key] = settings[key];
            }
        }
    };

    RendererLayer.prototype = {
        constructor: RendererLayer,

        /**
        * Game instance this obj is attached to.
        * @property game
        * @type Game
        */
        game: null,

        /**
        * The type of `RendererLayer` this is.
        * When created this object is merged with the value of `RendererLayer.Types[type]`. See constructor.
        * @property type
        * @type {String}
        */
        type: null,

        /**
         * If true, `this.getTileData()` will merge the `tileData` it would otherwise return with the `prevTileData` param (if provided).
         * objects are  from this layer should be merged with layers below before drawing.
         * @property mergeWithPrevLayer
         * @type {Boolean}
         */
        mergeWithPrevLayer: false,

        /**
         * If true, when `this.getTileData(x, y)` returns a value that evaluates to false, all tile layers above this one are not drawn by the `Renderer` for this map tile coord.
         * @property cancelTileDrawWhenNotFound
         * @type {Boolean}
         */
        cancelTileDrawWhenNotFound: false,

        /**
         * If true, `tileData` is drawn to the canvas after processing this layer.
         * @property draw
         * @type {Boolean}
         */
        draw: false,

        /**
         * Before draw function. Ignored if `this.draw = false`.
         * @property beforeDraw
         * @type {Function} `function(x, y, tileData, ctx){}`
         */
        beforeDraw: false,

        /**
         * After draw function. Ignored if `this.draw = false`.
         * @property afterDraw
         * @type {Function} `function(x, y, tileData, ctx){}`
         */
        afterDraw: false,

        /**
         * Get layer's `tileData` for a given map tile coord.
         * @method getTileData
         * @param {Number} x - Map tile x coord.
         * @param {Object} y - Map tile y coord.
         * @param {Object} [prevTileData] - `tileData` object for the given map tile coord from previous layer.
         * @return {TileData|Bool} false if nothing to render
         */
        getTileData: function(x, y, prevTileData){
            return false;
        },

        /**
         * Get layer's `TileData` for a given map tile coord.
         * Optionally modifying the `prevTileData` object param if `this.mergeWithPrevLayer = true`.
         * @method getModifiedTileData
         * @param {Number} x - Map tile x coord.
         * @param {Object} y - Map tile y coord.
         * @param {Object} [prevTileData] - `tileData` object for the given map tile coord from previous layer.
         * @return {TileData|Bool} false if nothing to render
         */
        getModifiedTileData: function(x, y, prevTileData){
            var tileData = this.getTileData(x, y, prevTileData);
            if(this.mergeWithPrevLayer && prevTileData){
                return this.mergeTileData(prevTileData, tileData);
            }
            return tileData;
        },

        /**
         * Merges 2 `tileData` objects.
         * Used to Merges layers of the same tile before drawing them.
         * @method mergeTileData
         * @param {TileData} tileData1 - `tileData` to merge to.
         * @param {TileData} tileData2 - `tileData` to merge from, properties with values on tileData2 replace matching properties on tileData1
         * @return {TileData} A new `tileData` object with merged values.
         */
        mergeTileData: function(tileData1, tileData2){
            var result = {},
                key, val;
            for(key in tileData1){
                result[key] = tileData1[key];
            }
            for(key in tileData2){
                val = tileData2[key];
                if(val !== false && val !== void 0){
                    result[key] = val;
                }
            }
            return result;
        },
    };

    /**
    * Describes different types of `RendererLayer`. Used by the `RendererLayer` constructor `type` param.
    *
    *     RendererLayer.Types = {
    *
    *         // ...
    *     }
    *
    * @class RendererLayer.Types
    * @static
    */
    RendererLayer.Types = {
        map: {
            merge: true,
            cancelTileDrawWhenNotFound: true,
            // draw: true,
            getTileData: function(x, y){

                if(!this.game){
                    return false;
                }

                var tile = this.game.map.get(x, y);

                if(!tile || !tile.explored){
                    return false;
                }

                var tileData = tile.getTileDrawData();

                return tileData;
            }
        },

        entity: {
            mergeWithPrevLayer: true,
            getTileData: function(x, y, prevTileData){
                if(!this.game){
                    return false;
                }
                var player = this.game.player;
                var entity = false;
                if (
                    player &&
                    x === player.x &&
                    y === player.y
                ) {
                    entity = player;
                } else if(this.game.entityManager){
                    entity = this.game.entityManager.get(x, y);

                }

                if(
                    this.game.player &&
                    this.game.player.fov &&
                    !this.game.player.fov.get(x, y)
                ){
                    return false;
                }

                if(entity){

                    var tileData = entity.getTileDrawData();
                    return tileData;
                }
                return false;
            }
        },
        lighting: {
            // this layer does mutate the prevTileData but not in the same way as merging
            mergeWithPrevLayer: false,
            draw: true,
            getTileData: function(x, y, prevTileData){
                if(!this.game){
                    return false;
                }
                if(this.game.lighting){
                    prevTileData = this.game.lighting.shadeTile(x, y, prevTileData);
                }
                return prevTileData;
            }
        },
        fov: {
            mergeWithPrevLayer: false,
            draw: true,
            beforeDraw: function(x, y, tileData, ctx){
                ctx.globalAlpha = this.game.renderer.nonVisibleTileAlpha;
            },
            afterDraw: function(x, y, tileData, ctx){
                ctx.globalAlpha = 1;
            },
            getTileData: function(x, y, prevTileData){
                if(!this.game){
                    return false;
                }
                if(
                    this.game.player &&
                    this.game.player.fov &&
                    this.game.player.fov.get(x, y)
                ){
                    return false;
                }

                return {
                    bgColor: this.game.renderer.bgColor
                };

            }
        }
    };

    root.RL.RendererLayer = RendererLayer;

}(this));