diff --git a/images/dirt.gif b/images/dirt.gif new file mode 100644 index 0000000..c71f2fe Binary files /dev/null and b/images/dirt.gif differ diff --git a/images/hud.bmp b/images/hud.bmp new file mode 100644 index 0000000..396ddb9 Binary files /dev/null and b/images/hud.bmp differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..ae2f46b --- /dev/null +++ b/index.html @@ -0,0 +1,41 @@ + + + + LaserTank.js + + + +
+ + Your web browser does not support the canvas element. + +
+   +
+ +
+
+ Load LTG and LVL +

This section is temporary and is used during development.

+ + + +
+
+
+ + + + + + + + + + + + + + + + diff --git a/lib/FileLoader.js b/lib/FileLoader.js new file mode 100644 index 0000000..2c47119 --- /dev/null +++ b/lib/FileLoader.js @@ -0,0 +1,120 @@ +/** + * Loads a file from disk and returns a binary string + * + * 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 . + * + * + * The file uses a number of features introduced in the HTML5 and ECMAScript + * specs, as it depends on FileReader. + */ + + +/** + * Load file into memory as binary string from a given file element + * + * This class handles the loading of only a single file (as that is all this + * project requires). + */ +ltjs.FileLoader = Class( 'FileLoader', +{ + /** + * DOM file element to watch + * @type {HTMLInputElement} + */ + 'private _element': null, + + /** + * Callback to call on file load + * @type {function(Error,string)} + */ + 'private _callback': null, + + + /** + * Initialize file loader, monitoring the given file element + * + * @param {HtmlInputElement} element file element to monitor + */ + __construct: function( element ) + { + if ( element.type !== 'file' ) + { + throw TypeError( 'Expected file element, given ' + element.type ); + } + + this._element = element; + }, + + + /** + * Bind callback to file load event + * + * The given callback will be called when the file is loaded. It must accept + * two arguments: the first will be used to indicate an error (otherwise + * null) and the second argument will contain the binary string of data + * (unless an error occurred, in which case it will be undefined). + * + * @param {function(Error,string)} callback file load callback + * + * @return {FileLoader} self + */ + 'public onLoad': function( callback ) + { + this._callback = callback; + + // we do not want to monitor the change event until *after* a callback + // is registered (it is otherwise pointless) + this._element.addEventListener( 'change', this._loadFile.bind( this ) ); + + // attempt to load file immediately (in case a file has already been + // selected) + this._loadFile( { target: this._element } ); + + return this; + }, + + + /** + * Process file and invokes callback with result + * + * Called on filename change. + * + * @param {Object} event change event + * + * @return {undefined} + */ + 'private _loadFile': function( event ) + { + var _self = this, + files = event.target.files; + + if ( files.length === 0 ) return; + + var reader = new FileReader(); + reader.onload = function( revent ) + { + _self._callback.call( this.__inst, null, revent.target.result ); + }; + reader.onerror = function( e ) + { + _self._callback.call( this.__inst, e ); + }; + + // load file + reader.readAsBinaryString( files[ 0 ] ); + } +} ); + diff --git a/scripts/game.js b/scripts/game.js new file mode 100644 index 0000000..fb6458d --- /dev/null +++ b/scripts/game.js @@ -0,0 +1,69 @@ +/** + * Game initialization script + * + * 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 . + */ + +( function() +{ + +var load_ltg = ltjs.FileLoader( document.getElementById( 'ltg' ) ), + load_lvl = ltjs.FileLoader( document.getElementById( 'lvl' ) ), + + ctx = document.getElementById( 'render' ).getContext( '2d' ), + + ltg_loader = ltjs.LtgLoader(), + masker = ltjs.TileMasker( ltjs.ClassicTileDfn() ), + tile_set = null, + map_set = null, + render = null; + +load_ltg.onLoad( function( e, data ) +{ + if ( e ) throw e; + + // get tile metadata + var meta = ltg_loader.fromString( data ); + + masker.getMaskedTiles( meta.tiles, meta.mask, function( tdata ) + { + tile_set = tdata; + gamechk(); + } ); +} ); + +load_lvl.onLoad( function( e, data ) +{ + if ( e ) throw e; + + map_set = ltjs.MapSet( data, ltjs.ClassicMap ); + + gamechk(); +} ); + +function gamechk() +{ + if ( !( tile_set && map_set ) ) return; + + // clear any existing locks before rendering (allowing the user to change + // tile sets and map sets) + render && render.freeCanvas(); + + render = ltjs.MapRender( ctx, tile_set ); + render.render( map_set.getMapByNumber( 1 ) ); +} + +} )(); diff --git a/style.css b/style.css new file mode 100644 index 0000000..c361a91 --- /dev/null +++ b/style.css @@ -0,0 +1,36 @@ +/** stylesheet for lasertank-js **/ + +body { + background-image: url('images/dirt.gif'); +} + +.game { + position: relative; + + margin: 0px auto; + width: 696px; +} + +/* 16x16 board */ +.game canvas { + width: 512px; + height: 512px; + border: 2px inset gray; +} + +.game .hud { + position: absolute; + + background-image: url('images/hud.bmp'); + background-repeat: no-repeat; + + width: 180px; + height: 245px; + right: 0px; + top: 0px; +} + +/** temporary during development **/ +.load { + background-color: rgba( 255, 255, 255, 0.5 ); +}