Added basic animation support to MapRender
This implementation is likely to change, but it does an excellent job bringing the map to life. The only frustrating part is that the game looks playable, but is not.master
parent
90b9208bca
commit
0d82e84daf
100
lib/MapRender.js
100
lib/MapRender.js
|
@ -29,6 +29,12 @@ ltjs.MapRender = Class( 'MapRender',
|
||||||
*/
|
*/
|
||||||
'private const _LOCK': '__$$MapRenderLock$$',
|
'private const _LOCK': '__$$MapRenderLock$$',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animation interval in milliseconds
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
'private const _ANIM_INTERVAL': 200,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2d context to which map should be drawn
|
* 2d context to which map should be drawn
|
||||||
|
@ -48,6 +54,12 @@ ltjs.MapRender = Class( 'MapRender',
|
||||||
*/
|
*/
|
||||||
'private _tiles': {},
|
'private _tiles': {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animation timer
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
'private _animTimer': 0,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize renderer with a canvas context and a tile set
|
* Initialize renderer with a canvas context and a tile set
|
||||||
|
@ -114,6 +126,9 @@ ltjs.MapRender = Class( 'MapRender',
|
||||||
{
|
{
|
||||||
var c = this._ctxObj.canvas;
|
var c = this._ctxObj.canvas;
|
||||||
|
|
||||||
|
// clear any running animations
|
||||||
|
this._clearAnimation();
|
||||||
|
|
||||||
// destroy the overlay canvas
|
// destroy the overlay canvas
|
||||||
c.parentNode.removeChild( c );
|
c.parentNode.removeChild( c );
|
||||||
|
|
||||||
|
@ -168,6 +183,9 @@ ltjs.MapRender = Class( 'MapRender',
|
||||||
sizey = size[ 1 ],
|
sizey = size[ 1 ],
|
||||||
i = objs.length,
|
i = objs.length,
|
||||||
|
|
||||||
|
// tiles to animate
|
||||||
|
anim = [],
|
||||||
|
|
||||||
// get the width and height from one of the tiles
|
// get the width and height from one of the tiles
|
||||||
t = this._tiles.dirt.data,
|
t = this._tiles.dirt.data,
|
||||||
w = t.width,
|
w = t.width,
|
||||||
|
@ -177,10 +195,12 @@ ltjs.MapRender = Class( 'MapRender',
|
||||||
// see Map.getObjects())
|
// see Map.getObjects())
|
||||||
while ( i-- )
|
while ( i-- )
|
||||||
{
|
{
|
||||||
var oid = objs[ i ],
|
var oid = objs[ i ],
|
||||||
tid = omap[ oid ],
|
tid = omap[ oid ],
|
||||||
x = ( Math.floor( i / sizex ) * w ),
|
tile = ( this._tiles[ tid ] || {} ).first,
|
||||||
y = ( ( i % sizey ) * h );
|
|
||||||
|
x = ( Math.floor( i / sizex ) * w ),
|
||||||
|
y = ( ( i % sizey ) * h );
|
||||||
|
|
||||||
// tunnels are handled a bit differently than other objects
|
// tunnels are handled a bit differently than other objects
|
||||||
if ( map.isObjectTunnel( oid ) )
|
if ( map.isObjectTunnel( oid ) )
|
||||||
|
@ -189,13 +209,28 @@ ltjs.MapRender = Class( 'MapRender',
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._drawTile( tid, x, y );
|
// queue for animation if it contains more than a single frame
|
||||||
|
if ( this._canAnimate( tid ) )
|
||||||
|
{
|
||||||
|
anim.push( [ tile, x, y ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
this._drawTile( tile, x, y );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._beginAnimation( anim );
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
'private _canAnimate': function( tid )
|
||||||
|
{
|
||||||
|
var tdata = this._tiles[ tid ];
|
||||||
|
return ( tdata.next !== tdata );
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw the tile identified by the given id
|
* Draw the tile identified by the given id
|
||||||
*
|
*
|
||||||
|
@ -209,12 +244,11 @@ ltjs.MapRender = Class( 'MapRender',
|
||||||
*
|
*
|
||||||
* @return {undefined}
|
* @return {undefined}
|
||||||
*/
|
*/
|
||||||
'private _drawTile': function( tid, x, y )
|
'private _drawTile': function( tile, x, y )
|
||||||
{
|
{
|
||||||
var tile = this._tiles[ tid ],
|
var ctx = ( tile.masked ) ? this._ctxObj : this._ctx;
|
||||||
ctx = ( tile.masked ) ? this._ctxObj : this._ctx;
|
|
||||||
|
|
||||||
ctx.putImageData( this._tiles[ tid ].first.data, x, y );
|
ctx.putImageData( tile.data, x, y );
|
||||||
|
|
||||||
if ( tile.masked )
|
if ( tile.masked )
|
||||||
{
|
{
|
||||||
|
@ -246,5 +280,53 @@ ltjs.MapRender = Class( 'MapRender',
|
||||||
|
|
||||||
// render the tile to the overlay canvas
|
// render the tile to the overlay canvas
|
||||||
this._ctxObj.putImageData( tdata, x, y );
|
this._ctxObj.putImageData( tdata, x, y );
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin basic tile animation
|
||||||
|
*
|
||||||
|
* At each animation interval, each tile will be advanced a single frame and
|
||||||
|
* rendered atop of the previous.
|
||||||
|
*
|
||||||
|
* @param {Array.<Array.<Object,number,number>>} anim array of tiles to
|
||||||
|
* animate; tdata,x,y
|
||||||
|
*
|
||||||
|
* @return {number} animation timer id
|
||||||
|
*/
|
||||||
|
'private _beginAnimation': function( anim )
|
||||||
|
{
|
||||||
|
var _self = this;
|
||||||
|
|
||||||
|
// clear any existing rendering animations
|
||||||
|
this._clearAnimation();
|
||||||
|
|
||||||
|
return this._animTimer = setInterval( function()
|
||||||
|
{
|
||||||
|
var i = anim.length;
|
||||||
|
|
||||||
|
while ( i-- )
|
||||||
|
{
|
||||||
|
var cur = anim[ i ];
|
||||||
|
|
||||||
|
// draw next frame
|
||||||
|
cur[ 0 ] = cur[ 0 ].next;
|
||||||
|
_self._drawTile.apply( _self, anim[ i ] );
|
||||||
|
}
|
||||||
|
}, this.__self.$( '_ANIM_INTERVAL' ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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!
|
||||||
|
*
|
||||||
|
* @return {undefined}
|
||||||
|
*/
|
||||||
|
'private _clearAnimation': function()
|
||||||
|
{
|
||||||
|
this._animTimer = +clearInterval( this._animTimer );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
Loading…
Reference in New Issue