From 47e022b5559196188948d06322e0b405596b1b04 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Sun, 20 Dec 2015 23:34:50 -0500 Subject: [PATCH 01/10] jshint and initial corrections This leaves issues that involve actual logic changes unresolved. It also raises an issue with the `Map` class, which is defined in ES6, and so will have to be renamed. --- .jshintrc | 20 ++++++++ Makefile.am | 7 ++- package.json.in | 3 +- src/ClassicGame.js | 36 ++++++------- src/ClassicGameObjectFactory.js | 8 +-- src/ClassicMap.js | 21 ++++---- src/ClassicTileDfn.js | 4 +- src/FileLoader.js | 8 +-- src/Game.js | 2 +- src/GameObjectFactory.js | 2 +- src/LtgLoader.js | 13 ++--- src/Map.js | 2 +- src/MapAction.js | 6 +-- src/MapBounds.js | 7 +-- src/MapRender.js | 70 +++++++++++++------------ src/MapSet.js | 4 +- src/MapState.js | 87 ++++++++++++++++---------------- src/TileDfn.js | 2 +- src/TileMasker.js | 68 +++++++++++++------------ src/gameobjs/GameObject.js | 2 +- src/gameobjs/Tank.js | 8 +-- src/gameobjs/classic/TankDown.js | 4 +- src/ui/MenuBar.js | 23 ++++----- src/version.js.in | 2 +- 24 files changed, 219 insertions(+), 190 deletions(-) create mode 100644 .jshintrc diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..7f6b15b --- /dev/null +++ b/.jshintrc @@ -0,0 +1,20 @@ +{ + "eqeqeq": true, + "esnext": true, + "forin": true, + "freeze": true, + "futurehostile": true, + "latedef": true, + "laxbreak": true, + "maxcomplexity": 100, + "maxdepth": 3, + "maxparams": 5, + "noarg": true, + "nocomma": true, + "node": true, + "nonbsp": true, + "nonew": true, + "undef": true, + "unused": true, + "varstmt": true +} diff --git a/Makefile.am b/Makefile.am index 2fc3379..78665a5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,7 +31,12 @@ modindex: $(nsindex) standalone: lasertank.js lasertank.js: modindex - ./node_modules/.bin/browserify -s lasertank --debug src/index.js > "$@" + ./node_modules/.bin/browserify \ + -t strictify \ + -s lasertank \ + --debug \ + src/index.js \ + > "$@" test: check check: diff --git a/package.json.in b/package.json.in index bbb64e9..cc41e4b 100644 --- a/package.json.in +++ b/package.json.in @@ -20,7 +20,8 @@ "devDependencies": { "chai": ">=1.9.1", "mocha": ">=1.18.2", - "browserify": "~12" + "browserify": "~12", + "strictify": "~0.2" }, "licenses": [ diff --git a/src/ClassicGame.js b/src/ClassicGame.js index ce6f116..0449713 100644 --- a/src/ClassicGame.js +++ b/src/ClassicGame.js @@ -18,17 +18,17 @@ */ -var Class = require( 'easejs' ).Class, - Game = require( './Game' ), - ClassicGameObjectFactory = require( './ClassicGameObjectFactory' ), - ClassicMap = require( './ClassicMap' ), - ClassicTileDfn = require( './ClassicTileDfn' ), - LtgLoader = require( './LtgLoader' ), - MapBounds = require( './MapBounds' ), - MapRender = require( './MapRender' ), - MapSet = require( './MapSet' ), - MapState = require( './MapState' ), - TileMasker = require( './TileMasker' ); +const Class = require( 'easejs' ).Class, + Game = require( './Game' ), + ClassicGameObjectFactory = require( './ClassicGameObjectFactory' ), + ClassicMap = require( './ClassicMap' ), + ClassicTileDfn = require( './ClassicTileDfn' ), + LtgLoader = require( './LtgLoader' ), + MapBounds = require( './MapBounds' ), + MapRender = require( './MapRender' ), + MapSet = require( './MapSet' ), + MapState = require( './MapState' ), + TileMasker = require( './TileMasker' ); /** * Facade for the classic (original) game of LaserTank @@ -92,7 +92,7 @@ module.exports = Class( 'ClassicGame' ) */ __construct: function( ltg_data, lvl_data ) { - var _self = this; + const _self = this; this._ltgLoader = LtgLoader(); this._masker = TileMasker( ClassicTileDfn() ); @@ -127,9 +127,9 @@ module.exports = Class( 'ClassicGame' ) this._render.clearCanvas(); } - var map = this._mapSet.getMapByNumber( 1 ), - map_state = MapState( map, this._gameObjFactory ), - bounds = MapBounds( map ); + const map = this._mapSet.getMapByNumber( 1 ), + map_state = MapState( map, this._gameObjFactory ), + bounds = MapBounds( map ); // render the first map (hardcoded for now) this._render = MapRender( ctx, this._tileSet ) @@ -138,7 +138,7 @@ module.exports = Class( 'ClassicGame' ) // POC window.onkeydown = function( event ) { - var dir; + let dir; switch ( event.keyCode ) { @@ -171,8 +171,8 @@ module.exports = Class( 'ClassicGame' ) 'public setTileData': function( data, callback ) { // get tile metadata - var _self = this, - meta = this._ltgLoader.fromString( data ); + const _self = this, + meta = this._ltgLoader.fromString( data ); this._masker.getMaskedTiles( meta.tiles, meta.mask, function( tdata ) { diff --git a/src/ClassicGameObjectFactory.js b/src/ClassicGameObjectFactory.js index 4c36d5d..f20cb9a 100644 --- a/src/ClassicGameObjectFactory.js +++ b/src/ClassicGameObjectFactory.js @@ -17,10 +17,10 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class, - GameObjectFactory = require( './GameObjectFactory' ), - GameObject = require( './gameobjs/GameObject' ), - Tank = require( './gameobjs/Tank' ); +const Class = require( 'easejs' ).Class, + GameObjectFactory = require( './GameObjectFactory' ), + GameObject = require( './gameobjs/GameObject' ), + Tank = require( './gameobjs/Tank' ); module.exports = Class( 'ClassicGameObjectFactory' ) diff --git a/src/ClassicMap.js b/src/ClassicMap.js index e436fb7..c8a8c88 100644 --- a/src/ClassicMap.js +++ b/src/ClassicMap.js @@ -40,8 +40,8 @@ * display. */ -var Class = require( 'easejs' ).Class, - Map = require( './Map' ); +const Class = require( 'easejs' ).Class, + Map = require( './Map' ); /** @@ -170,8 +170,8 @@ module.exports = Class( 'ClassicMap' ) */ 'public getObjects': function() { - var tiles = this._getDataSegment( '_GOSIZE', false ).split( '' ), - i = tiles.length; + const tiles = this._getDataSegment( '_GOSIZE', false ).split( '' ); + let i = tiles.length; while ( i-- ) { @@ -192,8 +192,8 @@ module.exports = Class( 'ClassicMap' ) { stripnull = ( arguments.length < 2 ) ? true : !!stripnull; - var s = this.__self.$( name ), - data = this._data.substr( ( this._offset + s[ 0 ] ), s[ 1 ] ); + const s = this.__self.$( name ), + data = this._data.substr( ( this._offset + s[ 0 ] ), s[ 1 ] ); return ( stripnull ) ? data.split( '\0' )[ 0 ] @@ -247,7 +247,7 @@ module.exports = Class( 'ClassicMap' ) { // get the tunnel id by stripping off the tunnel bitmask and then grab // the associated color - var tunnel_id = ( ( +oid ^ this.__self.$( '_TMASK' ) ) / 2 ); + const tunnel_id = ( ( +oid ^ this.__self.$( '_TMASK' ) ) / 2 ); return this.__self.$( '_TCOLORS' )[ tunnel_id ] || 'black'; }, @@ -311,9 +311,10 @@ module.exports = Class( 'ClassicMap' ) */ 'public getMapDifficulty': function() { - var val = this._getDataSegment( '_DIFFSIZE', false ), - i = val.length, - n = 0; + const val = this._getDataSegment( '_DIFFSIZE', false ); + + let i = val.length, + n = 0; // first, convert the value to an integer (from little-endian) while ( i-- ) n += ( val.charCodeAt( i ) << ( 8 * i ) ); diff --git a/src/ClassicTileDfn.js b/src/ClassicTileDfn.js index 0fef088..d506850 100644 --- a/src/ClassicTileDfn.js +++ b/src/ClassicTileDfn.js @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class, - TileDfn = require( './TileDfn' ); +const Class = require( 'easejs' ).Class, + TileDfn = require( './TileDfn' ); /** diff --git a/src/FileLoader.js b/src/FileLoader.js index 28ab62d..52bbc6b 100644 --- a/src/FileLoader.js +++ b/src/FileLoader.js @@ -21,7 +21,7 @@ * specs, as it depends on FileReader. */ -var Class = require( 'easejs' ).Class; +const Class = require( 'easejs' ).Class; /** @@ -100,12 +100,12 @@ module.exports = Class( 'FileLoader', */ 'private _loadFile': function( event ) { - var _self = this, - files = event.target.files; + const _self = this, + files = event.target.files; if ( files.length === 0 ) return; - var reader = new FileReader(); + const reader = new FileReader(); reader.onload = function( revent ) { _self._callback.call( this.__inst, null, revent.target.result ); diff --git a/src/Game.js b/src/Game.js index 30a4cf2..c3467f5 100644 --- a/src/Game.js +++ b/src/Game.js @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -var Interface = require( 'easejs' ).Interface; +const Interface = require( 'easejs' ).Interface; /** diff --git a/src/GameObjectFactory.js b/src/GameObjectFactory.js index a9bec24..eff3e8c 100644 --- a/src/GameObjectFactory.js +++ b/src/GameObjectFactory.js @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -var Interface = require( 'easejs' ).Interface; +const Interface = require( 'easejs' ).Interface; module.exports = Interface( 'GameObjectFactory', diff --git a/src/LtgLoader.js b/src/LtgLoader.js index 5c41bf0..bc3be30 100644 --- a/src/LtgLoader.js +++ b/src/LtgLoader.js @@ -42,7 +42,7 @@ * identify the file as a bitmap image.) */ -var Class = require( 'easejs' ).Class; +const Class = require( 'easejs' ).Class; /** @@ -73,7 +73,7 @@ module.exports = Class( 'LtgLoader', */ 'public fromString': function( ltg_data ) { - var mask_offset = this._getMaskOffsetFromData( ltg_data ); + const mask_offset = this._getMaskOffsetFromData( ltg_data ); return { name: this._getNameFromData( ltg_data ), @@ -112,7 +112,7 @@ module.exports = Class( 'LtgLoader', sgmt = this.__self.$( sgmt ); } - var data = String.prototype.substr.apply( ltg_data, sgmt ); + const data = String.prototype.substr.apply( ltg_data, sgmt ); return ( stripnull ) ? data.split( '\x00' )[ 0 ] @@ -187,8 +187,9 @@ module.exports = Class( 'LtgLoader', // grab the data and don't bother stripping off the null bytes (it would // function the same with them stripped, but let's avoid the confusion // since we are supposed to be working with a 32-bit value) - var data = this._getDataSegment( ltg_data, '_POS_MOFF', false ), - i = data.length, + const data = this._getDataSegment( ltg_data, '_POS_MOFF', false ); + + let i = data.length, offset = 0; // convert the DWORD entry (little-endian format, 32-bit) into an @@ -234,7 +235,7 @@ module.exports = Class( 'LtgLoader', */ 'private _getGameBitmap': function( ltg_data, mask_offset ) { - var bmp_offset = this.__self.$( '_OFFSET_HEADER_END' ); + const bmp_offset = this.__self.$( '_OFFSET_HEADER_END' ); // return the bitmap data up until the mask offset return ltg_data.substr( bmp_offset, ( mask_offset - bmp_offset ) ); diff --git a/src/Map.js b/src/Map.js index 7e7b46e..ef07389 100644 --- a/src/Map.js +++ b/src/Map.js @@ -29,7 +29,7 @@ * tunnel identified by index 0 is 0x40, index 1 is 0x42, and so on. */ -var Interface = require( 'easejs' ).Interface; +const Interface = require( 'easejs' ).Interface; /** diff --git a/src/MapAction.js b/src/MapAction.js index ed21069..601753b 100644 --- a/src/MapAction.js +++ b/src/MapAction.js @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class, - MapBounds = require( './MapBounds' ); +const Class = require( 'easejs' ).Class, + MapBounds = require( './MapBounds' ); module.exports = Class( 'MapAction', @@ -57,7 +57,7 @@ module.exports = Class( 'MapAction', 'public move': function() { - var method = [ + const method = [ 'getLeftPos', 'getUpperPos', 'getRightPos', diff --git a/src/MapBounds.js b/src/MapBounds.js index ed4884e..829b7e3 100644 --- a/src/MapBounds.js +++ b/src/MapBounds.js @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class, - Map = require( './Map' ); +const Class = require( 'easejs' ).Class, + Map = require( './Map' ); /** @@ -55,7 +55,8 @@ module.exports = Class( 'MapBounds', } // we are only interested in the dimensions of the map - var dimen = map.getDimensions(); + const dimen = map.getDimensions(); + this._mw = dimen[ 0 ]; this._mh = dimen[ 1 ]; }, diff --git a/src/MapRender.js b/src/MapRender.js index 8820d3f..ccdf305 100644 --- a/src/MapRender.js +++ b/src/MapRender.js @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class, - MapState = require( './MapState' ); +const Class = require( 'easejs' ).Class, + MapState = require( './MapState' ); /** @@ -97,8 +97,8 @@ module.exports = Class( 'MapRender', */ 'private _lockCanvas': function() { - var o = this._ctx, - l = this.__self.$( '_LOCK' ); + const o = this._ctx, + l = this.__self.$( '_LOCK' ); // simple one-line check to both set the lock and fail if the lock is // already set (implying that something else is already rendering to the @@ -127,7 +127,7 @@ module.exports = Class( 'MapRender', */ 'public freeCanvas': function() { - var c = this._ctxObj.canvas; + const c = this._ctxObj.canvas; // clear any running animations this._clearAnimation(); @@ -148,8 +148,8 @@ module.exports = Class( 'MapRender', */ 'private _getObjCanvas': function() { - var canvas = this._ctx.canvas, - canvas_obj = document.createElement( 'canvas' ); + const canvas = this._ctx.canvas, + canvas_obj = document.createElement( 'canvas' ); // mimic the dimensions and positions of the original canvas canvas_obj.style.position = 'absolute'; @@ -179,33 +179,31 @@ module.exports = Class( 'MapRender', throw TypeError( 'Invalid MapState provided' ); } - var objs = map.getObjects(), - size = map.getDimensions(), - omap = map.getObjectTileMap(), - sizex = size[ 0 ], - sizey = size[ 1 ], - i = objs.length, + const objs = map.getObjects(), + size = map.getDimensions(), + sizex = size[ 0 ], + sizey = size[ 1 ], - // tiles to animate - anim = [], + // tiles to animate + anim = [], - // get the width and height from one of the tiles - t = this._tiles.dirt.data, - w = t.width, - h = t.height; + // get the width and height from one of the tiles + t = this._tiles.dirt.data, + w = t.width, + h = t.height; this._clearCanvases(); - var _self = this; + const _self = this; map_state.onChange( function( obj, pos ) { - var oid = objs[ pos ], - tid = ( obj ) ? obj.getTid() : 'dirt', - tile = ( _self._tiles[ tid ] || {} ).first, + const oid = objs[ pos ], + tid = ( obj ) ? obj.getTid() : 'dirt', + tile = ( _self._tiles[ tid ] || {} ).first, - v = _self._getTileVector( pos, sizex, sizey, w, h ), - x = v[ 0 ], - y = v[ 1 ]; + v = _self._getTileVector( pos, sizex, sizey, w, h ), + x = v[ 0 ], + y = v[ 1 ]; if ( obj === null ) { @@ -280,8 +278,8 @@ module.exports = Class( 'MapRender', */ 'private _clearCanvases': function() { - var ctx = this._ctxObj, - c = ctx.canvas; + const ctx = this._ctxObj, + c = ctx.canvas; // we need only clear the overlay (to which masked tiles are rendered) ctx.clearRect( 0, 0, c.width, c.height ); @@ -297,7 +295,7 @@ module.exports = Class( 'MapRender', */ 'private _canAnimate': function( tid ) { - var tdata = this._tiles[ tid ]; + const tdata = this._tiles[ tid ]; return ( tdata.next !== tdata ); }, @@ -317,7 +315,7 @@ module.exports = Class( 'MapRender', */ 'private _drawTile': function( tile, x, y ) { - var ctx = ( tile.masked ) ? this._ctxObj : this._ctx; + const ctx = ( tile.masked ) ? this._ctxObj : this._ctx; ctx.putImageData( tile.data, x, y ); @@ -349,7 +347,7 @@ module.exports = Class( 'MapRender', */ 'private _renderTunnel': function( x, y, color ) { - var tdata = this._tiles.tunnel.data; + const tdata = this._tiles.tunnel.data; // fill tile with the appropriate background color for this tile this._ctx.fillStyle = color; @@ -373,24 +371,24 @@ module.exports = Class( 'MapRender', */ 'private _beginAnimation': function( anim ) { - var _self = this; + const _self = this; // clear any existing rendering animations this._clearAnimation(); - return this._animTimer = setInterval( function() + return ( this._animTimer = setInterval( function() { - var i = anim.length; + let i = anim.length; while ( i-- ) { - var cur = anim[ i ]; + const cur = anim[ i ]; // draw next frame cur[ 0 ] = cur[ 0 ].next; _self._drawTile.apply( _self, anim[ i ] ); } - }, this.__self.$( '_ANIM_INTERVAL' ) ); + }, this.__self.$( '_ANIM_INTERVAL' ) ) ); }, diff --git a/src/MapSet.js b/src/MapSet.js index 8f3a2c5..63b19fc 100644 --- a/src/MapSet.js +++ b/src/MapSet.js @@ -21,7 +21,7 @@ * file. */ -var Class = require( 'easejs' ).Class; +const Class = require( 'easejs' ).Class; @@ -85,7 +85,7 @@ module.exports = Class( 'MapSet', */ 'private _mapDataCheck': function() { - var n = ( this._data.length / this._mapCtor.getMapSize() ); + const n = ( this._data.length / this._mapCtor.getMapSize() ); // if the result is not an integer, then it is either not an LVL, the // file is corrupt, or we were given the wrong Map constructor diff --git a/src/MapState.js b/src/MapState.js index bd4f97a..7879e03 100644 --- a/src/MapState.js +++ b/src/MapState.js @@ -17,10 +17,10 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class, - MapAction = require( './MapAction' ), - GameObjectFactory = require( './GameObjectFactory' ), - GameObject = require( './gameobjs/GameObject' ); +const Class = require( 'easejs' ).Class, + MapAction = require( './MapAction' ), + GameObjectFactory = require( './GameObjectFactory' ), + GameObject = require( './gameobjs/GameObject' ); /** @@ -92,7 +92,7 @@ module.exports = Class( 'MapState', */ 'public flush': function() { - var _self = this; + const _self = this; // emit the change event for each game object this._forEachObj( function( obj, pos ) @@ -143,8 +143,8 @@ module.exports = Class( 'MapState', */ 'private _emitChange': function( obj, pos ) { - var i = -1, - l = this._stateCallbacks.length; + const l = this._stateCallbacks.length; + let i = -1; while ( ++i < l ) { @@ -153,7 +153,7 @@ module.exports = Class( 'MapState', if ( obj === null ) { - var _self = this; + const _self = this; this._objs[ pos ].forEach( function( o ) { if ( o === null ) return; @@ -178,12 +178,12 @@ module.exports = Class( 'MapState', */ 'private _initObjects': function( objs, objmap ) { - var i = objs.length; + let i = objs.length; while ( i-- ) { - var val = objs[ i ], - obj = this._createObj( objmap[ val ] ); + const val = objs[ i ], + obj = this._createObj( objmap[ val ] ); this._objs[ i ] = []; this._addObj( obj, i ); @@ -214,7 +214,7 @@ module.exports = Class( 'MapState', */ 'private _createObj': function( tid, from ) { - var obj = this._objFactory.createObject( tid ); + const obj = this._objFactory.createObject( tid ); // if a previous object was provided, copy over its mutable attributes if ( from ) @@ -301,8 +301,7 @@ module.exports = Class( 'MapState', */ 'private _replaceObj': function( cur, newobj, pos ) { - var o = this._objs[ pos ], - i = o.length; + const o = this._objs[ pos ]; // type checks if ( !( Array.isArray( o ) ) ) @@ -316,29 +315,27 @@ module.exports = Class( 'MapState', throw TypeError( "Invalid GameObject or null provided: " + newobj ); } - var free = null; + let i = o.length, + free = null; - ( function() + while ( i-- ) { - while ( i-- ) + if ( o[ i ] === cur ) { - if ( o[ i ] === cur ) - { - o[ i ] = newobj; - return; - } - else if ( o[ i ] === null ) - { - // record this as a free position for additions - free = i; - } + o[ i ] = newobj; + return; } + else if ( o[ i ] === null ) + { + // record this as a free position for additions + free = i; + } + } - // not found; add - if ( newobj === null ) return; - else if ( free ) o[ i ] = newobj; - else o.push( newobj ); - } )(); + // not found; add + if ( newobj === null ) return; + else if ( free ) o[ i ] = newobj; + else o.push( newobj ); // notify observers of the change this._emitChange( newobj, pos ); @@ -435,7 +432,7 @@ module.exports = Class( 'MapState', } // replace game object with a new one - var newobj = this._createObj( state, cur ); + const newobj = this._createObj( state, cur ); this._replaceObj( cur, newobj, pos ); return newobj; @@ -460,11 +457,11 @@ module.exports = Class( 'MapState', */ 'private _createStateCallback': function( cur, pos, c ) { - var _self = this; + const _self = this; return function( state ) { - var newobj = _self._changeState( cur, state, pos ); + const newobj = _self._changeState( cur, state, pos ); if ( typeof c === 'function' ) { @@ -493,7 +490,7 @@ module.exports = Class( 'MapState', */ 'private _createMoveCallback': function( obj, pos, c ) { - var _self = this; + const _self = this; return function( dest ) { @@ -523,11 +520,11 @@ module.exports = Class( 'MapState', */ 'public movePlayer': function( direction, bounds ) { - var _self = this, - player = this._player; + const _self = this, + player = this._player; // XXX: tightly coupled - var action = MapAction( + const action = MapAction( bounds, this._createMoveCallback( player, this._playerPos, function( pos ) { @@ -535,10 +532,14 @@ module.exports = Class( 'MapState', } ) ); - var sc = this._createStateCallback( player, this._playerPos, function( o ) - { - _self._player = o; - } ); + const sc = this._createStateCallback( + player, + this._playerPos, + function( o ) + { + _self._player = o; + } + ); action.direction = direction; action.srcPos = this._playerPos; diff --git a/src/TileDfn.js b/src/TileDfn.js index 80a0988..031ff34 100644 --- a/src/TileDfn.js +++ b/src/TileDfn.js @@ -75,7 +75,7 @@ * thinice - thin ice */ - var Interface = require( 'easejs' ).Interface; + const Interface = require( 'easejs' ).Interface; /** diff --git a/src/TileMasker.js b/src/TileMasker.js index 72f0087..8f76c8f 100644 --- a/src/TileMasker.js +++ b/src/TileMasker.js @@ -63,8 +63,8 @@ * rendering. */ -var Class = require( 'easejs' ).Class, - TileDfn = require( './TileDfn' ); +const Class = require( 'easejs' ).Class, + TileDfn = require( './TileDfn' ); /** * Slices tiles and applies masks @@ -137,7 +137,7 @@ module.exports = Class( 'TileMasker', // rather than accepting a context, we will create our own canvas in // memory to perform our operations (it will not be added to the DOM, so // these operations will not be visible to the user) - var context = document.createElement( 'canvas' ).getContext( '2d' ); + let context = document.createElement( 'canvas' ).getContext( '2d' ); // size the canvas so that it can fit the entire tileset context.canvas.width = this._setWidth; @@ -161,8 +161,8 @@ module.exports = Class( 'TileMasker', 'private _calcSetDimensions': function( tile_dfn ) { // these vars are for clarity - var sizes = tile_dfn.getTileDimensions(), - n = this._tileDfn.length; + const sizes = tile_dfn.getTileDimensions(), + n = this._tileDfn.length; // store values so that we do not have to make additional calls to our // TileDfn instance @@ -201,7 +201,7 @@ module.exports = Class( 'TileMasker', */ 'public getMaskedTiles': function( bmp_game, bmp_mask, callback ) { - var _self = this; + const _self = this; this._getImageData( bmp_mask, function( data_mask ) { @@ -248,26 +248,27 @@ module.exports = Class( 'TileMasker', */ 'virtual protected getMaskedTileSet': function( data_mask, callback ) { - var tdata = this._tileDfn, - tiles = {}, - i = -1, - len = tdata.length, + const tdata = this._tileDfn, + len = tdata.length, - // shorten the names - tw = this._tileWidth, - th = this._tileHeight, - xn = this._tilesPerRow; + // shorten the names + tw = this._tileWidth, + th = this._tileHeight, + xn = this._tilesPerRow; + + let tiles = {}, + i = -1; // create each tile (preserving order, thus no decrementing) while ( ++i < len ) { - var id = tdata[ i ][ 0 ], - mask = tdata[ i ][ 1 ], + const id = tdata[ i ][ 0 ], + mask = tdata[ i ][ 1 ]; - // calculate the X and Y position of this tile based on the tile - // and bitmap dimensions - x = ( ( i % xn ) * th ), - y = ( ( Math.floor( i / xn ) ) * tw ); + // calculate the X and Y position of this tile based on the tile + // and bitmap dimensions + const x = ( ( i % xn ) * th ), + y = ( ( Math.floor( i / xn ) ) * tw ); // the third index indicates whether or not a mask should be applied // to the tile @@ -297,7 +298,7 @@ module.exports = Class( 'TileMasker', */ 'protected appendTileFrame': function( set, id, mask, data ) { - var prev = set[ id ]; + const prev = set[ id ]; set[ id ] = { data: data, @@ -314,7 +315,7 @@ module.exports = Class( 'TileMasker', // if there was a previous entry, set its 'next' entry to our new frame, // expanding the linked list - prev && ( prev.next = set[ id ] ) + if ( prev ) prev.next = set[ id ]; }, @@ -347,18 +348,19 @@ module.exports = Class( 'TileMasker', */ 'virtual protected getMaskedTileData': function( data_mask, x, y ) { - var raw = this.getTileData( x, y ), - w = raw.width, - h = raw.height, - mw = data_mask.width, - yi = h; + const raw = this.getTileData( x, y ), + w = raw.width, + h = raw.height, + mw = data_mask.width; + + let yi = h; // apply the mask to the raw tile data (simple and easy-to-understand // algorithm; we can refine it later if need be), looping through each // pixel while ( yi-- ) { - xi = w; + let xi = w; while ( xi-- ) { @@ -366,8 +368,8 @@ module.exports = Class( 'TileMasker', // (remember that, although we are dealing with applying the // mask to a single tile, the mask image contains all tiles, so // we must calculate its position accordingly) - var mi = ( ( ( yi + y ) * ( mw * 4 ) ) + ( ( xi + x ) * 4 ) ), - mr = data_mask.data[ mi ]; + const mi = ( ( ( yi + y ) * ( mw * 4 ) ) + ( ( xi + x ) * 4 ) ), + mr = data_mask.data[ mi ]; // manipulate the alpha channel of our tile; if the R value for // the mask is not 0, then this pixel in our tile should be @@ -414,8 +416,8 @@ module.exports = Class( 'TileMasker', */ 'private _renderImage': function( bmp, callback ) { - var _self = this, - img = new Image(); + const _self = this, + img = new Image(); img.onload = function() { @@ -437,7 +439,7 @@ module.exports = Class( 'TileMasker', */ 'private _getImageData': function( bmp, callback ) { - var _self = this; + const _self = this; this._renderImage( bmp, function() { diff --git a/src/gameobjs/GameObject.js b/src/gameobjs/GameObject.js index 206e80d..7d0abed 100644 --- a/src/gameobjs/GameObject.js +++ b/src/gameobjs/GameObject.js @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class; +const Class = require( 'easejs' ).Class; module.exports = Class( 'GameObject', diff --git a/src/gameobjs/Tank.js b/src/gameobjs/Tank.js index 3d239fd..073aeae 100644 --- a/src/gameobjs/Tank.js +++ b/src/gameobjs/Tank.js @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class, - GameObject = require( './GameObject' ); +const Class = require( 'easejs' ).Class, + GameObject = require( './GameObject' ); module.exports = Class( 'Tank' ) @@ -26,12 +26,12 @@ module.exports = Class( 'Tank' ) { 'override public move': function( direction, c, sc ) { - var state = [ 'tleft', 'tup', 'tright', 'tdown' ][ direction ]; + const state = [ 'tleft', 'tup', 'tright', 'tdown' ][ direction ]; if ( state !== this.getTid() ) { sc( state ); - return; + return this; } // let parent handle the movement diff --git a/src/gameobjs/classic/TankDown.js b/src/gameobjs/classic/TankDown.js index f2bc0dc..efbcf4e 100644 --- a/src/gameobjs/classic/TankDown.js +++ b/src/gameobjs/classic/TankDown.js @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class, - Tank = require( '../Tank' ); +const Class = require( 'easejs' ).Class, + Tank = require( '../Tank' ); module.exports = Class( 'TankDown' ) diff --git a/src/ui/MenuBar.js b/src/ui/MenuBar.js index d7988e2..dd44473 100644 --- a/src/ui/MenuBar.js +++ b/src/ui/MenuBar.js @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -var Class = require( 'easejs' ).Class; +const Class = require( 'easejs' ).Class; /** @@ -68,16 +68,15 @@ module.exports = Class( 'MenuBar', */ 'private _initMenuActivation': function() { - var _self = this, - id = this._bar.id, - menus = this._bar.parentNode.querySelectorAll( '#'+id+' > li > a' ), - i = menus.length, + const id = this._bar.id, + menus = this._bar.parentNode.querySelectorAll( '#'+id+' > li > a' ), + click = function( event ) + { + event.target.parentNode.parentNode.className += ' focus'; + return false; + }; - click = function( event ) - { - event.target.parentNode.parentNode.className += ' focus'; - return false; - }; + let i = menus.length; // on menu click, apply focus class (this allows the menu to be opened // properly on click rather than a simple CSS hover menu) @@ -103,8 +102,8 @@ module.exports = Class( 'MenuBar', */ 'private _hookMenuMouseOut': function() { - var _self = this, - bar = this._bar; + const _self = this, + bar = this._bar; this._bar.addEventListener( 'mouseout', function( event ) { diff --git a/src/version.js.in b/src/version.js.in index 94df6af..db60588 100644 --- a/src/version.js.in +++ b/src/version.js.in @@ -19,7 +19,7 @@ * this program. If not, see . */ -var major = @MAJOR@, +let major = @MAJOR@, minor = @MINOR@, rev = @REV@, suffix = '@SUFFIX@', From 36a3ee63f6f90fe03e25af133795fa25a983f597 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Mon, 21 Dec 2015 00:08:38 -0500 Subject: [PATCH 02/10] {Map=>Level} This resolves conflicts with the ES6 Map prototype. --- src/ClassicGame.js | 55 +++---- src/Game.js | 4 +- src/{ClassicMap.js => level/ClassicLevel.js} | 145 +++++++++-------- src/{Map.js => level/Level.js} | 56 +++---- src/{MapAction.js => level/LevelAction.js} | 10 +- src/{MapBounds.js => level/LevelBounds.js} | 58 +++---- src/{MapRender.js => level/LevelRender.js} | 122 +++++++------- src/{MapSet.js => level/LevelSet.js} | 63 ++++---- src/{MapState.js => level/LevelState.js} | 162 ++++++++++--------- test/ltgloader-demo.html | 38 ++--- 10 files changed, 364 insertions(+), 349 deletions(-) rename src/{ClassicMap.js => level/ClassicLevel.js} (67%) rename src/{Map.js => level/Level.js} (70%) rename src/{MapAction.js => level/LevelAction.js} (89%) rename src/{MapBounds.js => level/LevelBounds.js} (80%) rename src/{MapRender.js => level/LevelRender.js} (76%) rename src/{MapSet.js => level/LevelSet.js} (55%) rename src/{MapState.js => level/LevelState.js} (77%) diff --git a/src/ClassicGame.js b/src/ClassicGame.js index 0449713..2d12f96 100644 --- a/src/ClassicGame.js +++ b/src/ClassicGame.js @@ -21,15 +21,16 @@ const Class = require( 'easejs' ).Class, Game = require( './Game' ), ClassicGameObjectFactory = require( './ClassicGameObjectFactory' ), - ClassicMap = require( './ClassicMap' ), ClassicTileDfn = require( './ClassicTileDfn' ), LtgLoader = require( './LtgLoader' ), - MapBounds = require( './MapBounds' ), - MapRender = require( './MapRender' ), - MapSet = require( './MapSet' ), - MapState = require( './MapState' ), + ClassicLevel = require( './level/ClassicLevel' ), + LevelBounds = require( './level/LevelBounds' ), + LevelRender = require( './level/LevelRender' ), + LevelSet = require( './level/LevelSet' ), + LevelState = require( './level/LevelState' ), TileMasker = require( './TileMasker' ); + /** * Facade for the classic (original) game of LaserTank */ @@ -56,10 +57,10 @@ module.exports = Class( 'ClassicGame' ) 'private _tileSet': null, /** - * Set of available maps - * @type {MapSet} + * Set of available levels + * @type {LevelSet} */ - 'private _mapSet': null, + 'private _levelSet': null, /** * Event handlers @@ -68,8 +69,8 @@ module.exports = Class( 'ClassicGame' ) 'private _callback': {}, /** - * Performs map rendering - * @type {MapRender} + * Performs level rendering + * @type {LevelRender} */ 'private _render': null, @@ -83,8 +84,8 @@ module.exports = Class( 'ClassicGame' ) /** * Initialize game with LTG and LVL data * - * The LTG and LVL data can be changed at any time, but are required in the - * constructor because they are needed in order for the game to be + * The LTG and LVL data can be changed at any time, but are required in + * the constructor because they are needed in order for the game to be * functional. * * @param {string} ltg_data binary string containing LTG file data @@ -99,10 +100,10 @@ module.exports = Class( 'ClassicGame' ) this._gameObjFactory = ClassicGameObjectFactory(); - // load initial tile and map data from the LTG and LVL data + // load initial tile and level data from the LTG and LVL data this.setTileData( ltg_data, function() { - this.setMapData( lvl_data, function() + this.setLevelData( lvl_data, function() { _self._trigger( 'ready' ); } ); @@ -119,21 +120,21 @@ module.exports = Class( 'ClassicGame' ) */ 'public renderTo': function( ctx ) { - // if there is a previous renderer, free its canvas before continuing - // (to both clean up and to free any locks, allowing for tile set and - // map changes) + // if there is a previous renderer, free its canvas before + // continuing (to both clean up and to free any locks, allowing for + // tile set and level changes) if ( this._render ) { this._render.clearCanvas(); } - const map = this._mapSet.getMapByNumber( 1 ), - map_state = MapState( map, this._gameObjFactory ), - bounds = MapBounds( map ); + const level = this._levelSet.getLevelByNumber( 1 ), + level_state = LevelState( level, this._gameObjFactory ), + bounds = LevelBounds( level ); - // render the first map (hardcoded for now) - this._render = MapRender( ctx, this._tileSet ) - .render( map, map_state ); + // render the first level (hardcoded for now) + this._render = LevelRender( ctx, this._tileSet ) + .render( level, level_state ); // POC window.onkeydown = function( event ) @@ -153,7 +154,7 @@ module.exports = Class( 'ClassicGame' ) return; } - map_state.movePlayer( dir, bounds ); + level_state.movePlayer( dir, bounds ); }; return this; @@ -185,16 +186,16 @@ module.exports = Class( 'ClassicGame' ) /** - * Set LVL data for maps + * Set LVL data for levels * * @param {string} data binary string containing LVL data * @param {function()} callback function to call when complete * * @return {ClassicGame} self */ - 'public setMapData': function( data, callback ) + 'public setLevelData': function( data, callback ) { - this._mapSet = MapSet( data, ClassicMap ); + this._levelSet = LevelSet( data, ClassicLevel ); callback.call( this.__inst ); return this; diff --git a/src/Game.js b/src/Game.js index c3467f5..e2dad64 100644 --- a/src/Game.js +++ b/src/Game.js @@ -50,14 +50,14 @@ module.exports = Interface( 'Game', /** - * Set LVL data for maps + * Set LVL data for levels * * @param {string} data binary string containing LVL data * @param {function()} callback function to call when complete * * @return {Game} self */ - 'public setMapData': [ 'data', 'callback' ], + 'public setLevelData': [ 'data', 'callback' ], /** diff --git a/src/ClassicMap.js b/src/level/ClassicLevel.js similarity index 67% rename from src/ClassicMap.js rename to src/level/ClassicLevel.js index c8a8c88..e44dd95 100644 --- a/src/ClassicMap.js +++ b/src/level/ClassicLevel.js @@ -1,5 +1,5 @@ /** - * Represents a classic map (level) + * Represents a classic level * * Copyright (C) 2012, 2015 Mike Gerwitz * @@ -17,7 +17,7 @@ * along with this program. If not, see . * * - * Each map is concatenated in the file and consists of the following + * Each level is concatenated in the file and consists of the following * information: * * - Playfield data (game objects), 16x16 multidimensional char array @@ -27,34 +27,34 @@ * - Difficulty, 16-bit integer, little endian * * One can easily calculate the position of the level in a file, given its - * number, by multiplying by the size of the data structure (see TLEVEL, LTANK.H - * in the original sources). + * number, by multiplying by the size of the data structure (see TLEVEL, + * LTANK.H in the original sources). * * It is worth mentioning how the playfield data is stored. Since the * multidimensional array is defined as [x][y], the array is created as an - * "array of columns", meaning that the data is organized in columns instead of - * rows. For example, when viewing the data in a HEX editor that displays 16 - * bytes per line (e.g. xxd), the map would appear to be mirrored rotated 90 - * degrees counter-clockwise. To make it easier to visualize, one can create a - * map with a number of tunnels in a pattern to take advantage of the ASCII - * display. + * "array of columns", meaning that the data is organized in columns instead + * of rows. For example, when viewing the data in a HEX editor that displays + * 16 bytes per line (e.g. xxd), the level would appear to be mirrored + * rotated 90 degrees counter-clockwise. To make it easier to visualize, one + * can create a level with a number of tunnels in a pattern to take + * advantage of the ASCII display. */ const Class = require( 'easejs' ).Class, - Map = require( './Map' ); + Level = require( './Level' ); /** - * Represents a classic map, as they exist in the original game. + * Represents a classic level, as they exist in the original game. * - * Classic maps are 16x16 tiles in size (for a total of 256 tiles). + * Classic levels are 16x16 tiles in size (for a total of 256 tiles). */ -module.exports = Class( 'ClassicMap' ) - .implement( Map ) +module.exports = Class( 'ClassicLevel' ) + .implement( Level ) .extend( { /** - * Size of each map in bytes + * Size of each level in bytes * @type {number} */ 'private const _SIZE': 576, @@ -70,13 +70,13 @@ module.exports = Class( 'ClassicMap' ) 'private const _GOSIZE': [ 0, 256 ], /** - * Offset and length of map name + * Offset and length of level name * @type {Array.} */ 'private const _NAMESIZE': [ 256, 31 ], /** - * Offset and length of map hint + * Offset and length of level hint * @type {Array.} */ 'private const _HINTSIZE': [ 287, 256 ], @@ -105,12 +105,13 @@ module.exports = Class( 'ClassicMap' ) /** * Colors used to identify tunnels * - * These colors will be rendered in the background and will bleed through - * the transparent portions of the tile. We use explicit HEX codes rather - * than CSS color names because environments may vary the colors used. + * These colors will be rendered in the background and will bleed + * through the transparent portions of the tile. We use explicit HEX + * codes rather than CSS color names because environments may vary the + * colors used. * - * Taken from ColorList in LTANK2.C in the original sources. Note that there - * is an endianness difference. + * Taken from ColorList in LTANK2.C in the original sources. Note that + * there is an endianness difference. * * @type {Array.} */ @@ -121,36 +122,36 @@ module.exports = Class( 'ClassicMap' ) /** - * Map set data (binary string) + * Level set data (binary string) * @type {string} */ 'private _data': null, /** - * Map id (1-indexed) + * Level id (1-indexed) * @type {string} */ 'private _id': 0, /** - * Offset of beginning of map data in bytes + * Offset of beginning of level data in bytes * @type {number} */ 'private _offset': 0, /** - * Initialize map with map data and the given id + * Initialize level with level data and the given id * - * @param {MapSet} set map set data - * @param {number} id 1-indexed map id + * @param {LevelSet} set level set data + * @param {number} id 1-indexed level id */ __construct: function( data, id ) { this._data = ''+( data ); this._id = +id; - // calculate map offset in LVL data + // calculate level offset in LVL data this._offset = ( this.__self.$( '_SIZE' ) * ( this._id - 1 ) ); }, @@ -158,13 +159,13 @@ module.exports = Class( 'ClassicMap' ) /** * Retrieve game objects * - * The game objects are returned in a manner consistent with the original - * sources - in columns, not rows. The reason for this is that the original - * game uses a multi-dimensional array [x][y], which creates an array of - * columns (TPLAYFIELD, LTANK.H). + * The game objects are returned in a manner consistent with the + * original sources - in columns, not rows. The reason for this is that + * the original game uses a multi-dimensional array [x][y], which + * creates an array of columns (TPLAYFIELD, LTANK.H). * - * The object data at the requested position will be loaded and converted to - * integers (from a binary string). + * The object data at the requested position will be loaded and + * converted to integers (from a binary string). * * @return {Array.} array of game objects */ @@ -202,7 +203,7 @@ module.exports = Class( 'ClassicMap' ) /** - * Retrieve map dimensions + * Retrieve level dimensions * * @return {Array.} width and height in tiles */ @@ -213,11 +214,11 @@ module.exports = Class( 'ClassicMap' ) /** - * Retrieve map of object codes to their appropriate tiles + * Retrieve level of object codes to their appropriate tiles * * @return {Array.} */ - 'public getObjectTileMap': function() + 'public getObjectTileLevel': function() { // we return these values here instead of returning, say, a constant, // because we would have to clone it to ensure that our inner state @@ -235,9 +236,10 @@ module.exports = Class( 'ClassicMap' ) /** * Retrieve tunnel color * - * The color will be rendered in the background and will bleed through the - * transparent portions of the tile. We use explicit HEX codes rather than - * CSS color names because environments may vary the colors used. + * The color will be rendered in the background and will bleed through + * the transparent portions of the tile. We use explicit HEX codes + * rather than CSS color names because environments may vary the colors + * used. * * @param {number} oid tunnel object id * @@ -245,8 +247,8 @@ module.exports = Class( 'ClassicMap' ) */ 'public getTunnelColor': function( oid ) { - // get the tunnel id by stripping off the tunnel bitmask and then grab - // the associated color + // get the tunnel id by stripping off the tunnel bitmask and then + // grab the associated color const tunnel_id = ( ( +oid ^ this.__self.$( '_TMASK' ) ) / 2 ); return this.__self.$( '_TCOLORS' )[ tunnel_id ] || 'black'; @@ -265,51 +267,51 @@ module.exports = Class( 'ClassicMap' ) /** - * Retrieve map name + * Retrieve level name * - * @return {string} map name + * @return {string} level name */ - 'public getMapName': function() + 'public getLevelName': function() { return this._getDataSegment( '_NAMESIZE' ); }, /** - * Retrieve map author name + * Retrieve level author name * - * @return {string} map author name + * @return {string} level author name */ - 'public getMapAuthor': function() + 'public getLevelAuthor': function() { return this._getDataSegment( '_AUTHORSIZE' ); }, /** - * Retrieve map hint + * Retrieve level hint * - * @return {string} map hint + * @return {string} level hint */ - 'public getMapHint': function() + 'public getLevelHint': function() { return this._getDataSegment( '_HINTSIZE' ); }, /** - * Retrieve map difficulty + * Retrieve level difficulty * - * The map difficulty will be returned as a 0-indexed value between 0 and 4, - * with 0 representing "kids" and 4 representing "deadly". + * The level difficulty will be returned as a 0-indexed value between 0 + * and 4, with 0 representing "kids" and 4 representing "deadly". * * The original game uses a bitmask for this value (thus the 16-bit - * integer), which is really of no particular use. For simplicity's sake, we - * will convert it. + * integer), which is really of no particular use. For simplicity's + * sake, we will convert it. * * @return {number} 0-indexed difficulty level */ - 'public getMapDifficulty': function() + 'public getLevelDifficulty': function() { const val = this._getDataSegment( '_DIFFSIZE', false ); @@ -320,25 +322,26 @@ module.exports = Class( 'ClassicMap' ) while ( i-- ) n += ( val.charCodeAt( i ) << ( 8 * i ) ); // Finally, convert to a simple 0-4 value to represent difficulty by - // taking the binary logarithm of the value (lg(n); original game uses - // bitmasks). For those who do not understand logarithms, the concept - // here is simple: if we are given a difficulty of "hard" (value of 8), - // that has a binary representation of: 1000. We are interested in the - // position of the 1-bit. Since each bit position is an exponent of two, - // we can reverse that calculation with a binary logarithm. So, log2(8), - // also written as lg(8), is equal to 3, since 2^3 = 8. Similarly, - // "deadly" = 16 = 0001 0000 => lg(16) = 4, and "kids" = 1 = 0001 => - // lg(1) = 0. This gives us a 0-indexed difficulty value. + // taking the binary logarithm of the value (lg(n); original game + // uses bitmasks). For those who do not understand logarithms, the + // concept here is simple: if we are given a difficulty of "hard" + // (value of 8), that has a binary representation of: 1000. We are + // interested in the position of the 1-bit. Since each bit position + // is an exponent of two, we can reverse that calculation with a + // binary logarithm. So, log2(8), also written as lg(8), is equal to + // 3, since 2^3 = 8. Similarly, "deadly" = 16 = 0001 0000 => lg(16) + // = 4, and "kids" = 1 = 0001 => lg(1) = 0. This gives us a + // 0-indexed difficulty value. return ( Math.log( n ) / Math.log( 2 ) ); }, /** - * Retrieve size of map in bytes + * Retrieve size of level in bytes * - * @return {number} size of map in bytes + * @return {number} size of level in bytes */ - 'public static getMapSize': function() + 'public static getLevelSize': function() { return this.$( '_SIZE' ); } diff --git a/src/Map.js b/src/level/Level.js similarity index 70% rename from src/Map.js rename to src/level/Level.js index ef07389..13a646d 100644 --- a/src/Map.js +++ b/src/level/Level.js @@ -17,7 +17,7 @@ * along with this program. If not, see . * * - * The details on exactly how the map data is stored is left to specific + * The details on exactly how the level data is stored is left to specific * implementations. However, the following is common to each file format: * * - All game objects for the playfield should be returned in columns rather @@ -33,22 +33,22 @@ const Interface = require( 'easejs' ).Interface; /** - * Represents a map (level) + * Represents a game level * - * Maps simply act as basic wrappers around a set of maps, returning only the - * data associated with the requested map. This allows the data to be lazily - * sliced out of the map file. + * Levels simply act as basic wrappers around a set of maps, returning only the + * data associated with the requested level. This allows the data to be lazily + * sliced out of the level file. * * Note that this interface specifies a constructor definition; this allows it * to be used in place of a separate Factory class. */ -module.exports = Interface( 'Map', +module.exports = Interface( 'Level', { /** - * Initialize map with map data and the given id + * Initialize level with level data and the given id * - * @param {MapSet} set map set data - * @param {number} id 1-indexed map id + * @param {LevelSet} set level set data + * @param {number} id 1-indexed level id */ __construct: [ 'set', 'id' ], @@ -67,7 +67,7 @@ module.exports = Interface( 'Map', /** - * Retrieve map dimensions + * Retrieve level dimensions * * @return {Array.} width and height in tiles */ @@ -75,11 +75,11 @@ module.exports = Interface( 'Map', /** - * Retrieve map of object codes to their appropriate tiles + * Retrieve level of object codes to their appropriate tiles * * @return {Array.} */ - 'public getObjectTileMap': [], + 'public getObjectTileLevel': [], /** @@ -106,44 +106,44 @@ module.exports = Interface( 'Map', /** - * Retrieve map name + * Retrieve level name * - * @return {string} map name + * @return {string} level name */ - 'public getMapName': [], + 'public getLevelName': [], /** - * Retrieve map author name + * Retrieve level author name * - * @return {string} map author name + * @return {string} level author name */ - 'public getMapAuthor': [], + 'public getLevelAuthor': [], /** - * Retrieve map hint + * Retrieve level hint * - * @return {string} map hint + * @return {string} level hint */ - 'public getMapHint': [], + 'public getLevelHint': [], /** - * Retrieve map difficulty + * Retrieve level difficulty * - * The map difficulty should be returned as a 0-indexed value between 0 and - * 4, with 0 representing "kids" and 4 representing "deadly". + * The level difficulty should be returned as a 0-indexed value between + * 0 and 4, with 0 representing "kids" and 4 representing "deadly". * * @return {number} 0-indexed difficulty level */ - 'public getMapDifficulty': [], + 'public getLevelDifficulty': [], /** - * Retrieve size of map in bytes + * Retrieve size of level in bytes * - * @return {number} size of map in bytes + * @return {number} size of level in bytes */ - 'public static getMapSize': [] + 'public static getLevelSize': [] } ); diff --git a/src/MapAction.js b/src/level/LevelAction.js similarity index 89% rename from src/MapAction.js rename to src/level/LevelAction.js index 601753b..c3bf1a0 100644 --- a/src/MapAction.js +++ b/src/level/LevelAction.js @@ -17,11 +17,11 @@ * along with this program. If not, see . */ -const Class = require( 'easejs' ).Class, - MapBounds = require( './MapBounds' ); +const Class = require( 'easejs' ).Class, + LevelBounds = require( './LevelBounds' ); -module.exports = Class( 'MapAction', +module.exports = Class( 'LevelAction', { // arranged by keycode 'const D__MIN': 0, @@ -43,9 +43,9 @@ module.exports = Class( 'MapAction', __construct: function( bounds, move_callback ) { - if ( !( Class.isA( MapBounds, bounds ) ) ) + if ( !( Class.isA( LevelBounds, bounds ) ) ) { - throw TypeError( 'Invalid MapBounds provided' ); + throw TypeError( 'Invalid LevelBounds provided' ); } this._dir = this.__self.$( 'D_UP' ); diff --git a/src/MapBounds.js b/src/level/LevelBounds.js similarity index 80% rename from src/MapBounds.js rename to src/level/LevelBounds.js index 829b7e3..004f937 100644 --- a/src/MapBounds.js +++ b/src/level/LevelBounds.js @@ -1,5 +1,5 @@ /** - * Handles map boundaries for collision detection and movement + * Handles level boundaries for collision detection and movement * * Copyright (C) 2012, 2015 Mike Gerwitz * @@ -18,44 +18,44 @@ */ const Class = require( 'easejs' ).Class, - Map = require( './Map' ); + Level = require( './Level' ); /** - * Calculates map bounding box + * Calculates level bounding box * - * This simply encapsulates the process of determining whether a given position - * is against an edge of the map. + * This simply encapsulates the process of determining whether a given + * position is against an edge of the level. */ -module.exports = Class( 'MapBounds', +module.exports = Class( 'LevelBounds', { /** - * Map width (number of tiles) + * Level width (number of tiles) * @type {number} */ 'private _mw': 0, /** - * Map height (number of tiles) + * Level height (number of tiles) * @type {number} */ 'private _mh': 0, /** - * Initialize bounding box for a given map + * Initialize bounding box for a given level * - * @param {Map} map map for which bounds should be calculated + * @param {Level} level level for which bounds should be calculated */ - __construct: function( map ) + __construct: function( level ) { - if ( !( Class.isA( Map, map ) ) ) + if ( !( Class.isA( Level, level ) ) ) { - throw TypeError( 'Invalid Map provided' ); + throw TypeError( 'Invalid Level provided' ); } - // we are only interested in the dimensions of the map - const dimen = map.getDimensions(); + // we are only interested in the dimensions of the level + const dimen = level.getDimensions(); this._mw = dimen[ 0 ]; this._mh = dimen[ 1 ]; @@ -65,7 +65,7 @@ module.exports = Class( 'MapBounds', /** * Retrieve the tile position above the given position * - * If the given tile position is at the top of the map, then the given + * If the given tile position is at the top of the level, then the given * position will be returned. * * @param {number} pos original tile position @@ -83,8 +83,8 @@ module.exports = Class( 'MapBounds', /** * Retrieve the tile position below the given position * - * If the given tile position is at the bottom of the map, then the given - * position will be returned. + * If the given tile position is at the bottom of the level, then the + * given position will be returned. * * @param {number} pos original tile position * @@ -101,8 +101,8 @@ module.exports = Class( 'MapBounds', /** * Retrieve the tile position to the left of the given position * - * If the given tile position is at the leftmost column of the map, then the - * given position will be returned. + * If the given tile position is at the leftmost column of the level, + * then the given position will be returned. * * @param {number} pos original tile position * @@ -120,8 +120,8 @@ module.exports = Class( 'MapBounds', /** * Retrieve the tile position to the right of the given position * - * If the given tile position is at the rightmost column of the map, then - * the given position will be returned. + * If the given tile position is at the rightmost column of the level, + * then the given position will be returned. * * @param {number} pos original tile position * @@ -137,7 +137,7 @@ module.exports = Class( 'MapBounds', /** - * Determines if the given position is in the topmost row of the map + * Determines if the given position is in the topmost row of the level * * @param {number} pos tile position * @@ -145,14 +145,14 @@ module.exports = Class( 'MapBounds', */ 'public isAtTop': function( pos ) { - // since tile positions are zero-indexed, we know that we're at the top - // if the map height divides the position + // since tile positions are zero-indexed, we know that we're at the + // top if the level height divides the position return ( pos % this._mh === 0 ); }, /** - * Determines if the given position is in the bottom row of the map + * Determines if the given position is in the bottom row of the level * * @param {number} pos tile position * @@ -166,7 +166,8 @@ module.exports = Class( 'MapBounds', /** - * Determines if the given position is in the leftmost column of the map + * Determines if the given position is in the leftmost column of the + * level * * @param {number} pos tile position * @@ -180,7 +181,8 @@ module.exports = Class( 'MapBounds', /** - * Determines if the given position is in the rightmost column of the map + * Determines if the given position is in the rightmost column of the + * level * * @param {number} pos tile position * diff --git a/src/MapRender.js b/src/level/LevelRender.js similarity index 76% rename from src/MapRender.js rename to src/level/LevelRender.js index ccdf305..fa08758 100644 --- a/src/MapRender.js +++ b/src/level/LevelRender.js @@ -1,5 +1,5 @@ /** - * Renders a given map + * Renders a given level * * Copyright (C) 2012, 2015 Mike Gerwitz * @@ -18,19 +18,19 @@ */ const Class = require( 'easejs' ).Class, - MapState = require( './MapState' ); + LevelState = require( './LevelState' ); /** - * Renders a map to a canvas + * Renders a level to a canvas */ -module.exports = Class( 'MapRender', +module.exports = Class( 'LevelRender', { /** * Property to hold lock bit on canvas element * @type {string} */ - 'private const _LOCK': '__$$MapRenderLock$$', + 'private const _LOCK': '__$$LevelRenderLock$$', /** * Animation interval in milliseconds @@ -40,7 +40,7 @@ module.exports = Class( 'MapRender', /** - * 2d context to which map should be drawn + * 2d context to which level should be drawn * @type {CanvasRenderingContext2d} */ 'private _ctx': null, @@ -67,8 +67,8 @@ module.exports = Class( 'MapRender', /** * Initialize renderer with a canvas context and a tile set * - * An additional canvas of equal dimensions will be created and laid atop of - * the provided canvas to render masked game objects. + * An additional canvas of equal dimensions will be created and laid + * atop of the provided canvas to render masked game objects. * * @param {CanvasRenderingContext2d} ctx canvas 2d context * @param {Object} tiles tile set to render @@ -79,7 +79,7 @@ module.exports = Class( 'MapRender', this._tiles = tiles; // ensure that we are exclusively rendering to this canvas (no other - // MapRenders) + // LevelRenders) this._lockCanvas(); this._ctxObj = this._getObjCanvas(); @@ -87,11 +87,13 @@ module.exports = Class( 'MapRender', /** - * Lock the canvas to prevent other MapRender instances from rendering to it + * Lock the canvas to prevent other LevelRender instances from rendering + * to it * - * The purpose of this is to provide feedback to the user/developer in the - * event that multiple MapRender instances are attempting to render to the - * same canvas, which would certainly cause display issues and confusion. + * The purpose of this is to provide feedback to the user/developer in + * the event that multiple LevelRender instances are attempting to + * render to the same canvas, which would certainly cause display issues + * and confusion. * * @return {undefined} */ @@ -100,9 +102,9 @@ module.exports = Class( 'MapRender', const o = this._ctx, l = this.__self.$( '_LOCK' ); - // simple one-line check to both set the lock and fail if the lock is - // already set (implying that something else is already rendering to the - // canvas) + // simple one-line check to both set the lock and fail if the lock + // is already set (implying that something else is already rendering + // to the canvas) if ( ( o[ l ] ^= 1 ) !== 1 ) { // reset the lock @@ -110,20 +112,20 @@ module.exports = Class( 'MapRender', throw Error( 'Could not set exclusive lock on canvas (in use by another ' + - 'MapRender instance)' + 'LevelRender instance)' ); } }, /** - * Remove exclusive lock on canvas to permit other MapRender instances to - * render to it + * Remove exclusive lock on canvas to permit other LevelRender instances + * to render to it * - * This will also destroy the overlay canvas that the masked objects were - * rendered to. The remaining canvas will not be cleared. + * This will also destroy the overlay canvas that the masked objects + * were rendered to. The remaining canvas will not be cleared. * - * @return {MapRender} self + * @return {LevelRender} self */ 'public freeCanvas': function() { @@ -166,21 +168,21 @@ module.exports = Class( 'MapRender', /** - * Render the provided map + * Render the provided level * - * @param {Map} map map to render + * @param {Level} level level to render * - * @return {MapRender} self + * @return {LevelRender} self */ - 'public render': function( map, map_state ) + 'public render': function( level, level_state ) { - if ( !( Class.isA( MapState, map_state ) ) ) + if ( !( Class.isA( LevelState, level_state ) ) ) { - throw TypeError( 'Invalid MapState provided' ); + throw TypeError( 'Invalid LevelState provided' ); } - const objs = map.getObjects(), - size = map.getDimensions(), + const objs = level.getObjects(), + size = level.getDimensions(), sizex = size[ 0 ], sizey = size[ 1 ], @@ -195,7 +197,7 @@ module.exports = Class( 'MapRender', this._clearCanvases(); const _self = this; - map_state.onChange( function( obj, pos ) + level_state.onChange( function( obj, pos ) { const oid = objs[ pos ], tid = ( obj ) ? obj.getTid() : 'dirt', @@ -212,9 +214,9 @@ module.exports = Class( 'MapRender', } // tunnels are handled a bit differently than other objects - if ( map.isObjectTunnel( oid ) ) + if ( level.isObjectTunnel( oid ) ) { - _self._renderTunnel( x, y, map.getTunnelColor( oid ) ); + _self._renderTunnel( x, y, level.getTunnelColor( oid ) ); return; } @@ -227,10 +229,10 @@ module.exports = Class( 'MapRender', _self._drawTile( tile, x, y ); } ); - map_state.flush(); + level_state.flush(); - // render each object (remember, we're dealing with columns, not rows; - // see Map.getObjects()) + // render each object (remember, we're dealing with columns, not + // rows; see Level.getObjects()) this._beginAnimation( anim ); @@ -239,12 +241,12 @@ module.exports = Class( 'MapRender', /** - * Retrieve a vector representing the x and y position coordinates of a tile - * position + * Retrieve a vector representing the x and y position coordinates of a + * tile position * * @param {number} pos tile position - * @param {number} sizex number of horizontal tiles in map - * @param {number} sizey number of vertical tiles in map + * @param {number} sizex number of horizontal tiles in level + * @param {number} sizey number of vertical tiles in level * @param {number} w tile width * @param {number} h tile height * @@ -262,17 +264,17 @@ module.exports = Class( 'MapRender', /** * Clears overlay canvas * - * This should be used before first rendering a map to ensure that any - * artifacts from previous map renderings will be erased. + * This should be used before first rendering a level to ensure that any + * artifacts from previous level renderings will be erased. * * We need only clear the overlay canvas, because the lower canvas will - * always be overwritten with tiles in every location. Because none of the - * tiles written to the lower canvas are masked, nothing from the previous - * render would ever peek through (of course, putImageData() would overwrite - * it even if that were the case). As such, clearing the lower canvas would - * simply be a waste of time and only serve to degrade performance - * (especially if this is being used with maps larger than the classic - * 16x16). + * always be overwritten with tiles in every location. Because none of + * the tiles written to the lower canvas are masked, nothing from the + * previous render would ever peek through (of course, putImageData() + * would overwrite it even if that were the case). As such, clearing the + * lower canvas would simply be a waste of time and only serve to + * degrade performance (especially if this is being used with levels + * larger than the classic 16x16). * * @return {undefined} */ @@ -281,7 +283,8 @@ module.exports = Class( 'MapRender', const ctx = this._ctxObj, c = ctx.canvas; - // we need only clear the overlay (to which masked tiles are rendered) + // we need only clear the overlay (to which masked tiles are + // rendered) ctx.clearRect( 0, 0, c.width, c.height ); }, @@ -303,9 +306,10 @@ module.exports = Class( 'MapRender', /** * Draw the tile identified by the given id * - * The tile will be drawn to the appropriate canvas depending on whether or - * not it has been masked. If it does have a mask, it will be drawn to the - * overlaying canvas and the dirt tile will be drawn underneath it. + * The tile will be drawn to the appropriate canvas depending on whether + * or not it has been masked. If it does have a mask, it will be drawn + * to the overlaying canvas and the dirt tile will be drawn underneath + * it. * * @param {string} tid tile id * @param {number} x left position @@ -336,8 +340,8 @@ module.exports = Class( 'MapRender', * Render the given tunnel * * The tunnel background color (which will peek through the mask) is - * rendered to the base canvas, whereas the tunnel tile itself is rendered - * on the overlaying canvas. + * rendered to the base canvas, whereas the tunnel tile itself is + * rendered on the overlaying canvas. * * @param {number} x left position * @param {number} y top position @@ -361,8 +365,8 @@ module.exports = Class( 'MapRender', /** * Begin basic tile animation * - * At each animation interval, each tile will be advanced a single frame and - * rendered atop of the previous. + * At each animation interval, each tile will be advanced a single frame + * and rendered atop of the previous. * * @param {Array.>} anim array of tiles to * animate; tdata,x,y @@ -395,8 +399,8 @@ module.exports = Class( 'MapRender', /** * Clear any running animation timers * - * It is important that this be done when a MapRender instance is done being - * used, or it will remain in memory indefinitely! + * It is important that this be done when a LevelRender instance is done + * being used, or it will remain in memory indefinitely! * * @return {undefined} */ diff --git a/src/MapSet.js b/src/level/LevelSet.js similarity index 55% rename from src/MapSet.js rename to src/level/LevelSet.js index 63b19fc..3967b88 100644 --- a/src/MapSet.js +++ b/src/level/LevelSet.js @@ -17,22 +17,20 @@ * along with this program. If not, see . * * - * Maps (the term "level" is used in the game) are stored in a fixed-width LVL - * file. + * Levels are stored in a fixed-width LVL file. */ const Class = require( 'easejs' ).Class; - /** * Handles delegation of LVL data * - * This acts as a Map factory, leaving all processing responsibilities to the - * Map instance. Consequently, any custom map format would be supported, - * provided that the appropriate Map is handling it. + * This acts as a Level factory, leaving all processing responsibilities to + * the Level instance. Consequently, any custom level format would be + * supported, provided that the appropriate Level is handling it. */ -module.exports = Class( 'MapSet', +module.exports = Class( 'LevelSet', { /** * Raw level set data (binary) @@ -41,61 +39,62 @@ module.exports = Class( 'MapSet', 'private _data': '', /** - * Constructor used to create new map instances + * Constructor used to create new level instances * @type {Function} */ - 'private _mapCtor': null, + 'private _levelCtor': null, /** - * Number of maps in the given LVL data + * Number of levels in the given LVL data * @type {number} */ - 'private _mapCount': 0, + 'private _levelCount': 0, /** - * Initialize map set with LVL data and a Map constructor + * Initialize level set with LVL data and a Level constructor * - * The Map constructor is used in place of a separate Map factory. + * The Level constructor is used in place of a separate Level factory. * * @param {string} data binary LVL data - * @param {Map} map_ctor Map constructor + * @param {Level} level_ctor Level constructor */ - __construct: function( data, map_ctor ) + __construct: function( data, level_ctor ) { this._data = ''+( data ); - this._mapCtor = map_ctor; + this._levelCtor = level_ctor; // perform a simple integrity check on the provided data - this._mapDataCheck(); + this._levelDataCheck(); }, /** - * Perform a simple map data integrity check + * Perform a simple level data integrity check * * This is intended to throw an error if we believe the LVL data to be - * invalid, or if the LVL data is invalid for the given Map constructor. - * The check will simply ensure that the map size (in bytes) divides into - * the total LVL size (in bytes) without any remainder. + * invalid, or if the LVL data is invalid for the given Level + * constructor. The check will simply ensure that the level size (in + * bytes) divides into the total LVL size (in bytes) without any + * remainder. * * This is by no means fool-proof, but it should catch most. * * @return {undefined} */ - 'private _mapDataCheck': function() + 'private _levelDataCheck': function() { - const n = ( this._data.length / this._mapCtor.getMapSize() ); + const n = ( this._data.length / this._levelCtor.getLevelSize() ); - // if the result is not an integer, then it is either not an LVL, the - // file is corrupt, or we were given the wrong Map constructor + // if the result is not an integer, then it is either not an LVL, + // the file is corrupt, or we were given the wrong Level constructor if ( n % 1 ) { throw Error( 'Invalid or corrupt LVL data' ); } // we already calculated it, so we may as well store it - this._mapCount = n; + this._levelCount = n; }, @@ -104,19 +103,19 @@ module.exports = Class( 'MapSet', * * @param {number} id number of level to load, 1-indexed */ - 'public getMapByNumber': function( id ) + 'public getLevelByNumber': function( id ) { - return this._mapCtor( this._data, id ); + return this._levelCtor( this._data, id ); }, /** - * Retrieve the number of maps in the LVL file + * Retrieve the number of levels in the LVL file * - * @return {number} number of maps + * @return {number} number of levels */ - 'public getMapCount': function() + 'public getLevelCount': function() { - return this._mapCount; + return this._levelCount; }, } ); diff --git a/src/MapState.js b/src/level/LevelState.js similarity index 77% rename from src/MapState.js rename to src/level/LevelState.js index 7879e03..3216254 100644 --- a/src/MapState.js +++ b/src/level/LevelState.js @@ -1,5 +1,5 @@ /** - * Represents the current state of a map + * Represents the current state of a level * * Copyright (C) 2012, 2015 Mike Gerwitz * @@ -18,15 +18,15 @@ */ const Class = require( 'easejs' ).Class, - MapAction = require( './MapAction' ), - GameObjectFactory = require( './GameObjectFactory' ), - GameObject = require( './gameobjs/GameObject' ); + LevelAction = require( './LevelAction' ), + GameObjectFactory = require( '../GameObjectFactory' ), + GameObject = require( '../gameobjs/GameObject' ); /** - * Represents the current state of a map + * Represents the current state of a level */ -module.exports = Class( 'MapState', +module.exports = Class( 'LevelState', { /** * Game object factory @@ -47,7 +47,7 @@ module.exports = Class( 'MapState', 'private _player': null, /** - * Game objects representing every object on the map + * Game objects representing every object on the level * @type {GameObject} */ 'private _objs': [], @@ -60,35 +60,37 @@ module.exports = Class( 'MapState', /** - * Initializes map state with a given map and factory with which to create - * game objects + * Initializes level state with a given level and factory with which to + * create game objects * - * Game objects influence map state rules, therefore fundamental game logic - * may be altered simply by passing in a custom GameObjectFactory instance. + * Game objects influence level state rules, therefore fundamental game + * logic may be altered simply by passing in a custom GameObjectFactory + * instance. * - * @param {Map} map game map + * @param {Level} level game level * @param {GameObjectFactory} obj_factory game object factory */ - __construct: function( map, obj_factory ) + __construct: function( level, obj_factory ) { if ( !( Class.isA( GameObjectFactory, obj_factory ) ) ) { throw TypeError( 'Invalid GameObjectFactory provided' ); } - // initialize game objects based on the initial map state + // initialize game objects based on the initial level state this._objFactory = obj_factory; - this._initObjects( map.getObjects(), map.getObjectTileMap() ); + this._initObjects( level.getObjects(), level.getObjectTileLevel() ); }, /** - * Flush map state, triggering the change event for each game object + * Flush level state, triggering the change event for each game object * - * This may be used to perform an initial rendering or re-draw of the entire - * map. Note that this should not be used to re-render the map after - * movements or state changes, as that would not be performant (especially - * since the map size could be arbitrarily large). + * This may be used to perform an initial rendering or re-draw of the + * entire level. Note that this should not be used to re-render the + * level after movements or state changes, as that would not be + * performant (especially since the level size could be arbitrarily + * large). */ 'public flush': function() { @@ -105,20 +107,20 @@ module.exports = Class( 'MapState', /** * Register an object change callback * - * Registers a continuation to be called when a game object changes state - * (a state change may represent an object transforming into another, a - * movement, or anything else that requires re-rendering). + * Registers a continuation to be called when a game object changes + * state (a state change may represent an object transforming into + * another, a movement, or anything else that requires re-rendering). * * TODO: use event base * - * The continuation will be passed the game object in its new state its tile - * position. If the game object is null, then it is to be assumed that the - * object no longer exists (e.g. has moved to another location) and should - * be cleared. + * The continuation will be passed the game object in its new state its + * tile position. If the game object is null, then it is to be assumed + * that the object no longer exists (e.g. has moved to another location) + * and should be cleared. * * @param {function(GameObject,number)} callback continuation * - * @return {MapState} self + * @return {LevelState} self */ 'public onChange': function( callback ) { @@ -130,11 +132,11 @@ module.exports = Class( 'MapState', /** * Emit a change event for the given object * - * States that an object's state has changed; see the onChange() method for - * additional information. A change may not necessarily imply that the - * object itself has changed---the change may simply represent a new - * position or---in the case of a null object---that the position has been - * cleared of an object. + * States that an object's state has changed; see the onChange() method + * for additional information. A change may not necessarily imply that + * the object itself has changed---the change may simply represent a new + * position or---in the case of a null object---that the position has + * been cleared of an object. * * @param {GameObject} obj the game object that has updated, or null * @param {number} pos tile position of the game object @@ -165,25 +167,25 @@ module.exports = Class( 'MapState', /** - * Initialize game objects for the map's original (default) state + * Initialize game objects for the level's original (default) state * - * All necessary game objects will be created to represent all objects on - * the map at its default state. Effectively, this creates the default map - * state. + * All necessary game objects will be created to represent all objects + * on the level at its default state. Effectively, this creates the + * default level state. * * @param {Array.} objs game object data (object ids) - * @param {Array.} objmap map from object ids to their tile ids + * @param {Array.} objlevel level from object ids to their tile ids * * @return {undefined} */ - 'private _initObjects': function( objs, objmap ) + 'private _initObjects': function( objs, objlevel ) { let i = objs.length; while ( i-- ) { const val = objs[ i ], - obj = this._createObj( objmap[ val ] ); + obj = this._createObj( objlevel[ val ] ); this._objs[ i ] = []; this._addObj( obj, i ); @@ -198,14 +200,14 @@ module.exports = Class( 'MapState', /** - * Creates a game object from a given tile id and (optionally) a previous - * object + * Creates a game object from a given tile id and (optionally) a + * previous object * * A previous game object may be provided if state is to be transferred * between objects---that is, the transformation of one game object into - * another may require a certain transfer of information. If no such game - * object is provided, then the game object will be created with its default - * state. + * another may require a certain transfer of information. If no such + * game object is provided, then the game object will be created with + * its default state. * * @param {string} tid tile id * @param {GameObject?} from optional game object for state change data @@ -216,7 +218,8 @@ module.exports = Class( 'MapState', { const obj = this._objFactory.createObject( tid ); - // if a previous object was provided, copy over its mutable attributes + // if a previous object was provided, copy over its mutable + // attributes if ( from ) { from.cloneTo( obj ); @@ -227,7 +230,7 @@ module.exports = Class( 'MapState', /** - * Invokes a continuation for each game object on the map + * Invokes a continuation for each game object on the level * * The continuation will be called with the game object and its tile * position. @@ -251,7 +254,8 @@ module.exports = Class( 'MapState', /** * Add a game object at the given tile position * - * It is an error to provide an invalid tile position or non-game object. + * It is an error to provide an invalid tile position or non-game + * object. * * @param {GameObject} obj game object to add * @param {number} pos tile position @@ -273,22 +277,22 @@ module.exports = Class( 'MapState', * Replaces the given game object at the given tile position with a new game * object * - * If the given game object can be found at the given tile position, then it - * will be replaced with the new given game object. If it cannot be found, - * then it will be added at the given tile position without any replacement - * being made (effectively an append), unless the given replacement object - * is null. + * If the given game object can be found at the given tile position, + * then it will be replaced with the new given game object. If it cannot + * be found, then it will be added at the given tile position without + * any replacement being made (effectively an append), unless the given + * replacement object is null. * - * If appending, the object will be placed in any open space (represented by - * a null); ``open'' space is created when an object is replaced with null, - * which has the effect of removing an object entirely (with no - * replacement). + * If appending, the object will be placed in any open space + * (represented by a null); ``open'' space is created when an object is + * replaced with null, which has the effect of removing an object + * entirely (with no replacement). * * The change will result in the notification of any observers that have * registered continuations for game object state changes. * - * It is an error to provide an unknown tile position or a replacement that - * is not a game object. + * It is an error to provide an unknown tile position or a replacement + * that is not a game object. * * @param {GameObject} cur game object to replace (or null) * @param {GameObject} newobj replacement game object @@ -366,8 +370,8 @@ module.exports = Class( 'MapState', /** * Move a game object from one tile position to another * - * This has the direct effect of (a) removing the given game object from its - * original position and (b) adding it to its new position. + * This has the direct effect of (a) removing the given game object from + * its original position and (b) adding it to its new position. * * It is an error to specify an object that is not a game object, or to * specify tile positions that do not exist. @@ -392,8 +396,8 @@ module.exports = Class( 'MapState', * Initializes player game object and tile position references * * These references exist purely for performance, preventing the need to - * scan for game objects that may represent the player. This also allows for - * any arbitrary game object to represent the "player". + * scan for game objects that may represent the player. This also allows + * for any arbitrary game object to represent the "player". * * @param {GameObject} obj game object representing the player * @param {number} pos player tile position @@ -408,11 +412,12 @@ module.exports = Class( 'MapState', /** * Changes the state of a game object at a given tile position * - * The "state" of a game object is represented by the object's type. If the - * state is unchanged, then no action will be taken. Otherwise, the game - * object at the given tile position, if available, will be replaced with a - * new game object representing the given state. If a game object cannot be - * found at the given tile position, then it will be added. + * The "state" of a game object is represented by the object's type. If + * the state is unchanged, then no action will be taken. Otherwise, the + * game object at the given tile position, if available, will be + * replaced with a new game object representing the given state. If a + * game object cannot be found at the given tile position, then it will + * be added. * * @param {GameObject} cur current game object * @param {string} state new object state @@ -445,8 +450,9 @@ module.exports = Class( 'MapState', * Produces a continuation that will perform a state change on the given * game object. The desired state should be passed to the continuation. * - * If an additional continuation c is provided, it will be invoked after the - * state change and may be used to process the resulting game object. + * If an additional continuation c is provided, it will be invoked after + * the state change and may be used to process the resulting game + * object. * * @param {GameObject} cur game object to alter * @param {number} pos game object tile position @@ -475,11 +481,11 @@ module.exports = Class( 'MapState', * Creates a callback to move a game object to a new tile position * * Produces a continuation that will perform a tile position move on the - * given game object. The desired direction of movement should be passed to - * the continuation (see MapAction for direction codes). + * given game object. The desired direction of movement should be passed + * to the continuation (see LevelAction for direction codes). * - * If an additional continuation c is provided, it will be invoked after the - * movement and may be used to process the new position. + * If an additional continuation c is provided, it will be invoked after + * the movement and may be used to process the new position. * * @param {GameObject} cur game object to alter * @param {number} pos game object tile position @@ -508,13 +514,13 @@ module.exports = Class( 'MapState', /** * Move a player in the given direction * - * The directions, as defined in MapAction, are: 0:left, 1:up, 2:right, - * 3:down. + * The directions, as defined in LevelAction, are: 0:left, 1:up, + * 2:right, 3:down. * * XXX: the bounds argument is temporary * * @param {number} direction direction code - * @param {MapBounds} bounds map boundaries + * @param {LevelBounds} bounds level boundaries * * @return {undefined} */ @@ -524,7 +530,7 @@ module.exports = Class( 'MapState', player = this._player; // XXX: tightly coupled - const action = MapAction( + const action = LevelAction( bounds, this._createMoveCallback( player, this._playerPos, function( pos ) { diff --git a/test/ltgloader-demo.html b/test/ltgloader-demo.html index a964cb3..e16b965 100644 --- a/test/ltgloader-demo.html +++ b/test/ltgloader-demo.html @@ -73,14 +73,14 @@ Your browser does not support the canvas element. - +