1
0
Fork 0
lasertank-js/lib/ClassicMap.js

342 lines
9.7 KiB
JavaScript
Raw Normal View History

Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
/**
* Represents a classic map (level)
*
* Copyright (C) 2012 Mike Gerwitz
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* Each map is concatenated in the file and consists of the following
* information:
*
* - Playfield data (game objects), 16x16 multidimensional char array
* - Level name, 31 characters
* - Hint, 256 characters
* - Author, 31 characters
* - 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).
*
* 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.
*/
/**
* Represents a classic map, as they exist in the original game.
*
* Classic maps are 16x16 tiles in size (for a total of 256 tiles).
*/
ltjs.ClassicMap = Class( 'ClassicMap' )
.implement( ltjs.Map )
.extend(
{
/**
* Size of each map in bytes
* @type {number}
*/
'private const _SIZE': 576,
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
/**
* Game object offset and size
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
*
* The game objects are stores as a 16x16 multi-dimensional signed char
* array (in the C sources).
*
* @type {Array.<number>}
*/
'private const _GOSIZE': [ 0, 256 ],
/**
* Offset and length of map name
* @type {Array.<number>}
*/
'private const _NAMESIZE': [ 256, 31 ],
/**
* Offset and length of map hint
* @type {Array.<number>}
*/
'private const _HINTSIZE': [ 287, 256 ],
/**
* Offset and length of author name
* @type {Array.<number>}
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
*/
'private const _AUTHORSIZE': [ 543, 31 ],
/**
* Offset and length of difficulty level
*
* 16-bit integer, little-endian
*
* @type {Array.<number>}
*/
'private const _DIFFSIZE': [ 574, 2 ],
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
/**
* Tunnel bitmask
* @type {number}
*/
'private const _TMASK': 0x40,
/**
* 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.
*
* Taken from ColorList in LTANK2.C in the original sources. Note that there
* is an endianness difference.
*
* @type {Array.<string>}
*/
'private const _TCOLORS': [
'#ff0000', '#00ff00', '#0000ff', '#00ffff', // r g b c
'#ffff00', '#ff00ff', '#ffffff', '#808080' // y m w b
],
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
/**
* Map set data (binary string)
* @type {string}
*/
'private _data': null,
/**
* Map id (1-indexed)
* @type {string}
*/
'private _id': 0,
/**
* Offset of beginning of map data in bytes
* @type {number}
*/
'private _offset': 0,
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
/**
* Initialize map with map data and the given id
*
* @param {ltjs.MapSet} set map set data
* @param {number} id 1-indexed map id
*/
__construct: function( data, id )
{
this._data = ''+( data );
this._id = +id;
// calculate map offset in LVL data
this._offset = ( this.__self.$( '_SIZE' ) * ( this._id - 1 ) );
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
},
/**
* 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 object data at the requested position will be loaded and converted to
* integers (from a binary string).
*
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
* @return {Array.<number>} array of game objects
*/
'public getObjects': function()
{
var tiles = this._getDataSegment( '_GOSIZE', false ).split( '' ),
i = tiles.length;
while ( i-- )
{
tiles[ i ] = tiles[ i ].charCodeAt( 0 );
}
return tiles;
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
},
/**
* Retrieve segment of data
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
*
* @param {string} name name of constant containing segment dfn
* @param {=boolean} stripnull whether to strip null bytes (default true)
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
*/
'private _getDataSegment': function( name, stripnull )
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
{
stripnull = ( arguments.length < 2 ) ? true : !!stripnull;
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
var s = this.__self.$( name ),
data = this._data.substr( ( this._offset + s[ 0 ] ), s[ 1 ] );
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
return ( stripnull )
? data.split( '\0' )[ 0 ]
: data;
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
},
/**
* Retrieve map dimensions
*
* @return {Array.<number>} width and height in tiles
*/
'public getDimensions': function()
{
return [ 16, 16 ];
},
/**
* Retrieve map of object codes to their appropriate tiles
*
* @return {Array.<string>}
*/
'public getObjectTileMap': 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
// would not be altered
return [
'dirt', 'tup', 'base', 'water', 'block', 'mblock', 'brick',
'atup', 'atright', 'atdown', 'atleft', 'mirrorul', 'mirrorur',
'mirrordr', 'mirrordl', 'owup', 'owright', 'owdown', 'owleft',
'cblock', 'rmirrorul', 'rmirrorur', 'rmirrordr', 'rmirrordl',
'ice', 'thinice'
];
},
/**
* 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.
*
* @param {number} oid tunnel object id
*
* @return {string} tunnel color
*/
'public getTunnelColor': function( oid )
{
// get the tunnel id by stripping off the tunnel bitmask and then grab
// the associated color
var tunnel_id = ( ( +oid ^ this.__self.$( '_TMASK' ) ) / 2 );
return this.__self.$( '_TCOLORS' )[ tunnel_id ] || 'black';
},
/**
* Determines if the given object is a tunnel
*
* @return {boolean} true if tunnel, otherwise false
*/
'public isObjectTunnel': function( oid )
{
return ( oid & this.__self.$( '_TMASK' ) );
},
/**
* Retrieve map name
*
* @return {string} map name
*/
'public getMapName': function()
{
return this._getDataSegment( '_NAMESIZE' );
},
/**
* Retrieve map author name
*
* @return {string} map author name
*/
'public getMapAuthor': function()
{
return this._getDataSegment( '_AUTHORSIZE' );
},
/**
* Retrieve map hint
*
* @return {string} map hint
*/
'public getMapHint': function()
{
return this._getDataSegment( '_HINTSIZE' );
},
/**
* Retrieve map 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 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.
*
* @return {number} 0-indexed difficulty level
*/
'public getMapDifficulty': function()
{
var val = this._getDataSegment( '_DIFFSIZE', false ),
i = val.length,
n = 0;
// first, convert the value to an integer (from little-endian)
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.
return ( Math.log( n ) / Math.log( 2 ) );
},
/**
* Retrieve size of map in bytes
*
* @return {number} size of map in bytes
*/
'public static getMapSize': function()
{
return this.$( '_SIZE' );
Initial map rendering support The next major step for the clone is the loading and parsing of LVL files (maps). This is especially imporant for the purpose of ensuring that users can continue to use the maps the know and love (and possibly created themselves), rather than having to recreate them in the clone. The maps are concatenated into a single fixed-width file and loaded (in the original sources) into the TLEVEL struct (LTANK.H). The main thing to note about this data is the manner in which the object data (the playfield) is stored. The TPLAYFIELD type (defined as a 16x16 multidimensional signed char array) is formatted as [x][y], meaning that it is an array of *columns*, not rows. While at first confusing, this does not complicate matters any. This commit adds initial rendering support for the playfield via MapRender and is demonstrated in the same demo file as LtgLoader. After loading a tile set, the user can load an LVL file. The rendering is done using two canvas elements, the second of which is created by MapRender itself and overlayed atop of the original canvas. Unmasked tiles are rendered to the bottom canvas and masked tiles to the upper, allowing us to move game objects without having to redraw underlying tiles. This is also necessary as the context putImageData() method overwrites any existing data rather than leaving values corresponding to the transparent pixels in tact. This commit also added support for tunnel coloring - each set of tunnels has its own distinct color. The color values were taken from ColorList in LTANK2.C in the original sources rather than using CSS color names (e.g. 'red', 'blue', 'magenta') because different environments may assign slightly different colors to those values (as an example, FireFox does not use #00FF00 for 'green'). Tunnels themselves are identified by a bitmask (0x40), so we can get the tunnel id by XORing with that mask. The ids are incremented by two in the LVL data (e.g. 0x40 for index 1, 0x42 for index 2), so we can then divide by two and take that index in the color array. This color is used to fill the tile with a solid color in the lower canvas. We can then paint the tile on the upper canvas, which will allow the color of the lower canvas to peek through the transparent pixels. Animation support has not yet been added (but animations are still visible in the demo to the left of the map rendering). This is an exciting start, as we can clearly see what the game will look like in the browser. This commit also does not cover any additional level metadata (e.g. author, difficulty, hints); that will be addressed in future commits and added to the demo.
2012-03-15 23:30:20 -04:00
}
} );