mirror of
https://github.com/AlexMacocian/MonoGame.Extended.git
synced 2026-07-15 15:09:29 +00:00
Fixes incorrect rendering of flipped animation tiles
This commit is contained in:
@@ -4,15 +4,17 @@ namespace MonoGame.Extended.Tiled.Renderers
|
||||
{
|
||||
public sealed class TiledMapAnimatedLayerModel : TiledMapLayerModel
|
||||
{
|
||||
public TiledMapAnimatedLayerModel(GraphicsDevice graphicsDevice, Texture2D texture, VertexPositionTexture[] vertices, ushort[] indices, TiledMapTilesetAnimatedTile[] animatedTilesetTiles)
|
||||
public TiledMapAnimatedLayerModel(GraphicsDevice graphicsDevice, Texture2D texture, VertexPositionTexture[] vertices, ushort[] indices, TiledMapTilesetAnimatedTile[] animatedTilesetTiles, TiledMapTileFlipFlags[] animatedTilesetTileFlipFlags)
|
||||
: base(graphicsDevice, texture, vertices, indices)
|
||||
{
|
||||
Vertices = vertices;
|
||||
AnimatedTilesetTiles = animatedTilesetTiles;
|
||||
AnimatedTilesetFlipFlags = animatedTilesetTileFlipFlags;
|
||||
}
|
||||
|
||||
public VertexPositionTexture[] Vertices { get; }
|
||||
public TiledMapTilesetAnimatedTile[] AnimatedTilesetTiles { get; }
|
||||
public TiledMapTileFlipFlags[] AnimatedTilesetFlipFlags { get; }
|
||||
|
||||
protected override VertexBuffer CreateVertexBuffer(GraphicsDevice graphicsDevice, int vertexCount)
|
||||
{
|
||||
@@ -24,4 +26,4 @@ namespace MonoGame.Extended.Tiled.Renderers
|
||||
return new DynamicIndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, indexCount, BufferUsage.WriteOnly); ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,18 +8,21 @@ namespace MonoGame.Extended.Tiled.Renderers
|
||||
public TiledMapAnimatedLayerModelBuilder()
|
||||
{
|
||||
AnimatedTilesetTiles = new List<TiledMapTilesetAnimatedTile>();
|
||||
AnimatedTilesetFlipFlags = new List<TiledMapTileFlipFlags>();
|
||||
}
|
||||
|
||||
public List<TiledMapTilesetAnimatedTile> AnimatedTilesetTiles { get; }
|
||||
public List<TiledMapTileFlipFlags> AnimatedTilesetFlipFlags { get; }
|
||||
|
||||
protected override void ClearBuffers()
|
||||
{
|
||||
AnimatedTilesetTiles.Clear();
|
||||
AnimatedTilesetFlipFlags.Clear();
|
||||
}
|
||||
|
||||
protected override TiledMapAnimatedLayerModel CreateModel(GraphicsDevice graphicsDevice, Texture2D texture)
|
||||
{
|
||||
return new TiledMapAnimatedLayerModel(graphicsDevice, texture, Vertices.ToArray(), Indices.ToArray(), AnimatedTilesetTiles.ToArray());
|
||||
return new TiledMapAnimatedLayerModel(graphicsDevice, texture, Vertices.ToArray(), Indices.ToArray(), AnimatedTilesetTiles.ToArray(), AnimatedTilesetFlipFlags.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,9 @@ namespace MonoGame.Extended.Tiled.Renderers
|
||||
if (tilesetTile is TiledMapTilesetAnimatedTile animatedTilesetTile)
|
||||
{
|
||||
animatedLayerBuilder.AddSprite(texture, position, sourceRectangle, flipFlags);
|
||||
animatedTilesetTile.CreateTextureRotations(tileset, flipFlags);
|
||||
animatedLayerBuilder.AnimatedTilesetTiles.Add(animatedTilesetTile);
|
||||
animatedLayerBuilder.AnimatedTilesetFlipFlags.Add(flipFlags);
|
||||
|
||||
if (animatedLayerBuilder.IsFull)
|
||||
layerModels.Add(animatedLayerBuilder.Build(_graphicsDevice, texture));
|
||||
|
||||
@@ -62,9 +62,9 @@ namespace MonoGame.Extended.Tiled.Renderers
|
||||
{
|
||||
var verticesPointer = fixedVerticesPointer;
|
||||
|
||||
foreach (var animatedTile in animatedModel.AnimatedTilesetTiles)
|
||||
for (int i = 0; i < animatedModel.AnimatedTilesetTiles.Length; i++)
|
||||
{
|
||||
var currentFrameTextureCoordinates = animatedTile.CurrentAnimationFrame.TextureCoordinates;
|
||||
var currentFrameTextureCoordinates = animatedModel.AnimatedTilesetTiles[i].CurrentAnimationFrame.GetTextureCoordinates(animatedModel.AnimatedTilesetFlipFlags[i]);
|
||||
|
||||
// ReSharper disable ArrangeRedundantParentheses
|
||||
(*verticesPointer++).TextureCoordinate = currentFrameTextureCoordinates[0];
|
||||
|
||||
@@ -23,6 +23,14 @@ namespace MonoGame.Extended.Tiled
|
||||
CurrentAnimationFrame = AnimationFrames[0];
|
||||
}
|
||||
|
||||
public void CreateTextureRotations(TiledMapTileset tileset, TiledMapTileFlipFlags flipFlags)
|
||||
{
|
||||
for (int i = 0; i < AnimationFrames.Count; i++)
|
||||
{
|
||||
AnimationFrames[i].CreateTextureRotations(tileset, flipFlags);
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
_timer += gameTime.ElapsedGameTime;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace MonoGame.Extended.Tiled
|
||||
@@ -8,6 +9,7 @@ namespace MonoGame.Extended.Tiled
|
||||
public readonly int LocalTileIdentifier;
|
||||
public readonly TimeSpan Duration;
|
||||
public readonly Vector2[] TextureCoordinates;
|
||||
private readonly Dictionary<TiledMapTileFlipFlags, Vector2[]> _flipDictionary = new Dictionary<TiledMapTileFlipFlags, Vector2[]>();
|
||||
|
||||
internal TiledMapTilesetTileAnimationFrame(TiledMapTileset tileset, int localTileIdentifier, int durationInMilliseconds)
|
||||
{
|
||||
@@ -17,6 +19,101 @@ namespace MonoGame.Extended.Tiled
|
||||
CreateTextureCoordinates(tileset);
|
||||
}
|
||||
|
||||
public Vector2[] GetTextureCoordinates(TiledMapTileFlipFlags flipFlags)
|
||||
{
|
||||
if (!_flipDictionary.TryGetValue(flipFlags, out Vector2[] flippedTextureCoordiantes))
|
||||
{
|
||||
return TextureCoordinates;
|
||||
}
|
||||
else
|
||||
{
|
||||
return flippedTextureCoordiantes;
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateTextureRotations(TiledMapTileset tileset, TiledMapTileFlipFlags flipFlags)
|
||||
{
|
||||
if (!_flipDictionary.ContainsKey(flipFlags))
|
||||
{
|
||||
if (flipFlags == TiledMapTileFlipFlags.None)
|
||||
{
|
||||
_flipDictionary.Add(flipFlags, TextureCoordinates);
|
||||
}
|
||||
else
|
||||
{
|
||||
_flipDictionary.Add(flipFlags, TransformTextureCoordinates(tileset, flipFlags));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2[] TransformTextureCoordinates(TiledMapTileset tileset, TiledMapTileFlipFlags flipFlags)
|
||||
{
|
||||
var sourceRectangle = tileset.GetTileRegion(LocalTileIdentifier);
|
||||
var texture = tileset.Texture;
|
||||
var texelLeft = (float)sourceRectangle.X / texture.Width;
|
||||
var texelTop = (float)sourceRectangle.Y / texture.Height;
|
||||
var texelRight = (sourceRectangle.X + sourceRectangle.Width) / (float)texture.Width;
|
||||
var texelBottom = (sourceRectangle.Y + sourceRectangle.Height) / (float)texture.Height;
|
||||
|
||||
var flipDiagonally = (flipFlags & TiledMapTileFlipFlags.FlipDiagonally) != 0;
|
||||
var flipHorizontally = (flipFlags & TiledMapTileFlipFlags.FlipHorizontally) != 0;
|
||||
var flipVertically = (flipFlags & TiledMapTileFlipFlags.FlipVertically) != 0;
|
||||
var transform = new Vector2[4];
|
||||
|
||||
transform[0].X = texelLeft;
|
||||
transform[0].Y = texelTop;
|
||||
|
||||
transform[1].X = texelRight;
|
||||
transform[1].Y = texelTop;
|
||||
|
||||
transform[2].X = texelLeft;
|
||||
transform[2].Y = texelBottom;
|
||||
|
||||
transform[3].X = texelRight;
|
||||
transform[3].Y = texelBottom;
|
||||
|
||||
if (flipDiagonally)
|
||||
{
|
||||
FloatHelper.Swap(ref transform[1].X, ref transform[2].X);
|
||||
FloatHelper.Swap(ref transform[1].Y, ref transform[2].Y);
|
||||
}
|
||||
|
||||
if (flipHorizontally)
|
||||
{
|
||||
if (flipDiagonally)
|
||||
{
|
||||
FloatHelper.Swap(ref transform[0].Y, ref transform[1].Y);
|
||||
FloatHelper.Swap(ref transform[2].Y, ref transform[3].Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatHelper.Swap(ref transform[0].X, ref transform[1].X);
|
||||
FloatHelper.Swap(ref transform[2].X, ref transform[3].X);
|
||||
}
|
||||
}
|
||||
|
||||
if (flipVertically)
|
||||
{
|
||||
if (flipDiagonally)
|
||||
{
|
||||
FloatHelper.Swap(ref transform[0].X, ref transform[2].X);
|
||||
FloatHelper.Swap(ref transform[1].X, ref transform[3].X);
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatHelper.Swap(ref transform[0].Y, ref transform[2].Y);
|
||||
FloatHelper.Swap(ref transform[1].Y, ref transform[3].Y);
|
||||
}
|
||||
}
|
||||
|
||||
transform[0] = transform[0];
|
||||
transform[1] = transform[1];
|
||||
transform[2] = transform[2];
|
||||
transform[3] = transform[3];
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
private void CreateTextureCoordinates(TiledMapTileset tileset)
|
||||
{
|
||||
var sourceRectangle = tileset.GetTileRegion(LocalTileIdentifier);
|
||||
@@ -44,4 +141,4 @@ namespace MonoGame.Extended.Tiled
|
||||
return $"{LocalTileIdentifier}:{Duration}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user