mirror of
https://github.com/photonstorm/phaser
synced 2024-11-21 20:23:19 +00:00
Add Tiled animation support to TilemapLayer.
This commit is contained in:
parent
1a45ac8eea
commit
16abedf87b
4 changed files with 189 additions and 1 deletions
|
@ -329,6 +329,26 @@ var TilemapLayer = new Class({
|
|||
* @since 3.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* The time elapsed since timer initialization.
|
||||
* This drives the animation of the texture.
|
||||
*
|
||||
* @name Phaser.Tilemaps.TilemapLayer#timeElapsed
|
||||
* @type {number}
|
||||
* @since 3.90.0
|
||||
*/
|
||||
this.timeElapsed = 0;
|
||||
|
||||
/**
|
||||
* Whether the animation timer is paused.
|
||||
*
|
||||
* @name Phaser.Tilemaps.TilemapLayer#timePaused
|
||||
* @type {boolean}
|
||||
* @since 3.90.0
|
||||
* @default false
|
||||
*/
|
||||
this.timePaused = false;
|
||||
|
||||
this.setTilesets(tileset);
|
||||
this.setAlpha(this.layer.alpha);
|
||||
this.setPosition(x, y);
|
||||
|
@ -339,6 +359,23 @@ var TilemapLayer = new Class({
|
|||
this.initPostPipeline(false);
|
||||
},
|
||||
|
||||
// Overrides Game Object method
|
||||
addedToScene: function ()
|
||||
{
|
||||
this.scene.sys.updateList.add(this);
|
||||
},
|
||||
|
||||
// Overrides Game Object method
|
||||
removedFromScene: function ()
|
||||
{
|
||||
this.scene.sys.updateList.remove(this);
|
||||
},
|
||||
|
||||
preUpdate: function (time, delta)
|
||||
{
|
||||
this.updateTimer(time, delta);
|
||||
},
|
||||
|
||||
/**
|
||||
* Populates the internal `tileset` array with the Tileset references this Layer requires for rendering.
|
||||
*
|
||||
|
@ -1488,6 +1525,63 @@ var TilemapLayer = new Class({
|
|||
return this.tilemap.worldToTileXY(worldX, worldY, snapToFloor, point, camera, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Pauses or resumes the animation timer for this game object.
|
||||
*
|
||||
* @method Phaser.Tilemaps.TilemapLayer#setTimerPaused
|
||||
* @since 3.90.0
|
||||
* @param {boolean} [paused] - Pause state (`true` to pause, `false` to unpause). If not specified, the timer will unpause.
|
||||
* @return {this} This game object.
|
||||
*/
|
||||
setTimerPaused: function (paused)
|
||||
{
|
||||
this.timePaused = !!paused;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset the animation timer for this game object.
|
||||
*
|
||||
* @method Phaser.Tilemaps.TilemapLayer#resetTimer
|
||||
* @since 3.90.0
|
||||
* @param {number} [ms=0] - The time to reset the timer to.
|
||||
* @return {this} This game object.
|
||||
*/
|
||||
resetTimer: function (ms)
|
||||
{
|
||||
if (ms === undefined) { ms = 0; }
|
||||
this.timeElapsed = ms;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the timer for this game object.
|
||||
* This is called automatically by the preUpdate method.
|
||||
* The timer drives the animation of the texture.
|
||||
*
|
||||
* Override this method to create more advanced time management,
|
||||
* or set it to a NOOP function to disable the timer update.
|
||||
* If you want to control animations with a tween or input system,
|
||||
* disabling the timer update could be useful.
|
||||
*
|
||||
* @method Phaser.Tilemaps.TilemapLayer#updateTimer
|
||||
* @since 3.90.0
|
||||
* @param {number} time - The current time in milliseconds.
|
||||
* @param {number} delta - The time since the last update, in milliseconds.
|
||||
* @return {this} This game object.
|
||||
*/
|
||||
updateTimer: function (time, delta)
|
||||
{
|
||||
if (!this.timePaused)
|
||||
{
|
||||
this.timeElapsed += delta;
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroys this TilemapLayer and removes its link to the associated LayerData.
|
||||
*
|
||||
|
|
|
@ -63,6 +63,8 @@ var TilemapLayerWebGLRenderer = function (renderer, src, drawingContext)
|
|||
var submitterNode = src.customRenderNodes.Submitter || src.defaultRenderNodes.Submitter;
|
||||
var transformerNode = src.customRenderNodes.Transformer || src.defaultRenderNodes.Transformer;
|
||||
|
||||
var timeElapsed = src.timeElapsed;
|
||||
|
||||
for (var i = 0; i < tileCount; i++)
|
||||
{
|
||||
var tile = renderTiles[i];
|
||||
|
@ -74,7 +76,14 @@ var TilemapLayerWebGLRenderer = function (renderer, src, drawingContext)
|
|||
continue;
|
||||
}
|
||||
|
||||
var tileTexCoords = tileset.getTileTextureCoordinates(tile.index);
|
||||
var tileIndex = tileset.getAnimatedTileId(tile.index, timeElapsed);
|
||||
|
||||
if (tileIndex === null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var tileTexCoords = tileset.getTileTextureCoordinates(tileIndex);
|
||||
var tileWidth = tileset.tileWidth;
|
||||
var tileHeight = tileset.tileHeight;
|
||||
|
||||
|
|
|
@ -194,6 +194,20 @@ var Tileset = new Class({
|
|||
* @since 3.0.0
|
||||
*/
|
||||
this.texCoordinates = [];
|
||||
|
||||
/**
|
||||
* The number of frames above which a tile is considered to have
|
||||
* many animation frames. This is used to optimize rendering.
|
||||
* If a tile has fewer frames than this, frames are searched using
|
||||
* a linear search. If a tile has more, frames are searched using
|
||||
* a binary search.
|
||||
*
|
||||
* @name Phaser.Tilemaps.Tileset#animationSearchThreshold
|
||||
* @type {number}
|
||||
* @since 3.90.0
|
||||
* @default 64
|
||||
*/
|
||||
this.animationSearchThreshold = 64;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -269,6 +283,61 @@ var Tileset = new Class({
|
|||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the ID of the tile to use, given a base tile and time,
|
||||
* according to the tile's animation properties.
|
||||
*
|
||||
* If the tile is not animated, this method returns the base tile ID.
|
||||
*
|
||||
* @method Phaser.Tilemaps.Tileset#getAnimatedTileId
|
||||
* @since 3.90.0
|
||||
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
|
||||
* @param {number} milliseconds - The current time in milliseconds.
|
||||
* @return {?number} The tile ID to use, or null if the tile is not contained in this tileset.
|
||||
*/
|
||||
getAnimatedTileId: function (tileIndex, milliseconds)
|
||||
{
|
||||
if (!this.containsTileIndex(tileIndex)) { return null; }
|
||||
|
||||
var animData = this.getTileData(tileIndex);
|
||||
|
||||
if (!(animData && animData.animation)) { return tileIndex; }
|
||||
|
||||
milliseconds = milliseconds % animData.animationDuration;
|
||||
var anim = animData.animation;
|
||||
var frame = null;
|
||||
|
||||
// Binary search.
|
||||
|
||||
var low = 0;
|
||||
var high = anim.length - 1;
|
||||
var mid = 0;
|
||||
var startTime = 0;
|
||||
|
||||
while (low <= high)
|
||||
{
|
||||
mid = (low + high) >>> 1;
|
||||
frame = anim[mid];
|
||||
startTime = frame.startTime;
|
||||
|
||||
if (startTime <= milliseconds && startTime + frame.duration > milliseconds)
|
||||
{
|
||||
return frame.tileid + this.firstgid;
|
||||
}
|
||||
|
||||
if (startTime < milliseconds)
|
||||
{
|
||||
low = mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the texture coordinates (UV in pixels) in the Tileset image for the given tile index.
|
||||
* Returns null if tile index is not contained in this Tileset.
|
||||
|
|
|
@ -96,6 +96,22 @@ var ParseTilesets = function (json)
|
|||
(datas[tile.id] || (datas[tile.id] = {})).type = tile.type;
|
||||
}
|
||||
}
|
||||
|
||||
// Sum up animation length.
|
||||
for (var tileId in datas)
|
||||
{
|
||||
var animData = datas[tileId].animation;
|
||||
if (animData)
|
||||
{
|
||||
var animTime = 0;
|
||||
for (var j = 0; j < animData.length; j++)
|
||||
{
|
||||
animData[j].startTime = animTime;
|
||||
animTime += animData[j].duration;
|
||||
}
|
||||
datas[tileId].animationDuration = animTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(set.wangsets))
|
||||
|
|
Loading…
Reference in a new issue