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
|
|
|
/**
|
|
|
|
* Handles the loading of LVL files
|
|
|
|
*
|
|
|
|
* 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/>.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Maps (the term "level" is used in the game) are stored in a fixed-width LVL
|
|
|
|
* file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
ltjs.MapSet = Class( 'MapSet',
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Raw level set data (binary)
|
|
|
|
* @type {string}
|
|
|
|
*/
|
|
|
|
'private _data': '',
|
|
|
|
|
2012-03-17 16:09:08 -04:00
|
|
|
/**
|
|
|
|
* Constructor used to create new map instances
|
|
|
|
* @type {Function}
|
|
|
|
*/
|
|
|
|
'private _mapCtor': null,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Number of maps in the given LVL data
|
|
|
|
* @type {number}
|
|
|
|
*/
|
|
|
|
'private _mapCount': 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 set with LVL data and a Map constructor
|
|
|
|
*
|
|
|
|
* The Map constructor is used in place of a separate Map factory.
|
|
|
|
*
|
|
|
|
* @param {string} data binary LVL data
|
|
|
|
* @param {ltjs.Map} map_ctor Map constructor
|
|
|
|
*/
|
|
|
|
__construct: function( data, map_ctor )
|
|
|
|
{
|
|
|
|
this._data = ''+( data );
|
|
|
|
this._mapCtor = map_ctor;
|
2012-03-17 16:09:08 -04:00
|
|
|
|
|
|
|
// perform a simple integrity check on the provided data
|
|
|
|
this._mapDataCheck();
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Perform a simple map 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.
|
|
|
|
*
|
|
|
|
* This is by no means fool-proof, but it should catch most.
|
|
|
|
*
|
|
|
|
* @return {undefined}
|
|
|
|
*/
|
|
|
|
'private _mapDataCheck': function()
|
|
|
|
{
|
|
|
|
var 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
|
|
|
|
if ( n % 1 )
|
|
|
|
{
|
|
|
|
throw Error( 'Invalid or corrupt LVL data' );
|
|
|
|
}
|
|
|
|
|
|
|
|
// we already calculated it, so we may as well store it
|
|
|
|
this._mapCount = n;
|
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
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load a level by the given number (e.g. level 1)
|
|
|
|
*
|
|
|
|
* @param {number} id number of level to load, 1-indexed
|
|
|
|
*/
|
|
|
|
'public getMapByNumber': function( id )
|
|
|
|
{
|
|
|
|
return this._mapCtor( this._data, id );
|
2012-03-17 16:09:08 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve the number of maps in the LVL file
|
|
|
|
*
|
|
|
|
* @return {number} number of maps
|
|
|
|
*/
|
|
|
|
'public getMapCount': function()
|
|
|
|
{
|
|
|
|
return this._mapCount;
|
|
|
|
},
|
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
|
|
|
} );
|