diff --git a/Engine/Node/TileMapNode.cs b/Engine/Node/TileMapNode.cs
new file mode 100644
index 00000000..119fa5e3
--- /dev/null
+++ b/Engine/Node/TileMapNode.cs
@@ -0,0 +1,741 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Altseed2
+{
+ ///
+ /// 大量描画を行うノード
+ ///
+ [Serializable]
+ public class TileMapNode : TransformNode, IDrawn, ICullableDrawn
+ {
+ private readonly MapChipList chips;
+ private readonly RenderedPolygon renderedPolygon;
+ private bool requireUpdateVertexes = true;
+
+ ///
+ /// 格納されているを取得します。
+ ///
+ public ReadOnlyCollection Chips => _chips ??= new ReadOnlyCollection(chips);
+ [NonSerialized]
+ private ReadOnlyCollection _chips;
+
+ ///
+ /// の新しいインスタンスを生成します。
+ ///
+ /// Graphics昨日が初期化されていない
+ public TileMapNode()
+ {
+ if (!Engine.Config.EnabledCoreModules.HasFlag(CoreModules.Graphics)) throw new InvalidOperationException("Graphics機能が初期化されていません。");
+ chips = new MapChipList();
+ renderedPolygon = RenderedPolygon.Create();
+ }
+
+ #region IDrawn
+ Rendered ICullableDrawn.Rendered => renderedPolygon;
+
+ void IDrawn.Draw()
+ {
+ Engine.Renderer.DrawPolygon(renderedPolygon);
+ }
+
+ int ICullableDrawn.CullingId => renderedPolygon.Id;
+
+ ///
+ /// カメラグループを取得または設定します。
+ ///
+ public ulong CameraGroup
+ {
+ get => _CameraGroup;
+ set
+ {
+ if (_CameraGroup == value) return;
+ var old = _CameraGroup;
+ _CameraGroup = value;
+
+ if (IsRegistered)
+ Engine.UpdateDrawnCameraGroup(this, old);
+ }
+ }
+ private ulong _CameraGroup;
+
+ ///
+ /// 描画時の重ね順を取得または設定します。
+ ///
+ public int ZOrder
+ {
+ get => _ZOrder;
+ set
+ {
+ if (value == _ZOrder) return;
+
+ var old = _ZOrder;
+ _ZOrder = value;
+
+ if (IsRegistered)
+ Engine.UpdateDrawnZOrder(this, old);
+ }
+ }
+ private int _ZOrder;
+
+ ///
+ /// このノードを描画するかどうかを取得または設定します。
+ ///
+ public bool IsDrawn
+ {
+ get => _IsDrawn; set
+ {
+ if (_IsDrawn == value) return;
+ _IsDrawn = value;
+ this.UpdateIsDrawnActuallyOfDescendants();
+
+ }
+ }
+ private bool _IsDrawn = true;
+
+ ///
+ /// 先祖のを考慮して、このノードを描画するかどうかを取得します。
+ ///
+ public bool IsDrawnActually => (this as ICullableDrawn).IsDrawnActually;
+ bool ICullableDrawn.IsDrawnActually { get; set; } = true;
+ #endregion
+
+ #region Node
+ internal override void Registered()
+ {
+ base.Registered();
+ Engine.RegisterDrawn(this);
+ Engine.CullingSystem.Register(renderedPolygon);
+ }
+
+ internal override void Unregistered()
+ {
+ base.Unregistered();
+ Engine.UnregisterDrawn(this);
+ Engine.CullingSystem.Unregister(renderedPolygon);
+ }
+
+ internal override void Update()
+ {
+ if (requireUpdateVertexes)
+ {
+ UpdateVertexes();
+ requireUpdateVertexes = false;
+ }
+
+ base.Update();
+ }
+ #endregion
+
+ #region RenderedPolygon
+ ///
+ /// アルファブレンドを取得または設定します。
+ ///
+ public AlphaBlend AlphaBlend
+ {
+ get => renderedPolygon.AlphaBlend;
+ set
+ {
+ if (renderedPolygon.AlphaBlend == value) return;
+ renderedPolygon.AlphaBlend = value;
+ }
+ }
+
+ ///
+ /// 使用するマテリアルを取得または設定します。
+ ///
+ public Material Material
+ {
+ get => renderedPolygon.Material;
+ set
+ {
+ if (renderedPolygon.Material == value) return;
+ renderedPolygon.Material = value;
+ }
+ }
+
+ ///
+ /// 使用するテクスチャを取得または設定します。
+ ///
+ public TextureBase Texture
+ {
+ get => renderedPolygon.Texture;
+ set
+ {
+ if (renderedPolygon.Texture == value) return;
+ renderedPolygon.Texture = value;
+ renderedPolygon.Src = new RectF(default, value?.Size ?? new Vector2I(1, 1));
+ foreach (var chip in chips) chip.Src = new RectF(default, value?.Size ?? new Vector2I(1, 1));
+ }
+ }
+
+ ///
+ public sealed override Matrix44F InheritedTransform
+ {
+ get => base.InheritedTransform;
+ private protected set
+ {
+ base.InheritedTransform = value;
+ AbsoluteTransform = value * Matrix44F.GetTranslation2D(-CenterPosition);
+ renderedPolygon.Transform = AbsoluteTransform;
+ }
+ }
+ #endregion
+
+ ///
+ public sealed override Vector2F ContentSize
+ {
+ get
+ {
+ MathHelper.GetMinMax(out var min, out var max, renderedPolygon.Vertexes);
+ return max - min;
+ }
+ }
+
+ ///
+ /// を登録します。
+ ///
+ /// 登録するのインスタンス
+ /// がnull
+ /// を追加出来たらtrue,それ以外でそれ以外でfalse
+ public bool AddMapChip(MapChip chip)
+ {
+ if (!chips.Add(chip)) return false;
+ chip.Owner = this;
+ chip.OnAdded();
+ requireUpdateVertexes = true;
+ return true;
+ }
+
+ ///
+ /// 登録されているを全て削除します。
+ ///
+ public void ClearMapChips()
+ {
+ for (int i = 0; i < chips.Count; i++) chips[i].Owner = null;
+ chips.Clear();
+ requireUpdateVertexes = true;
+ }
+
+ ///
+ /// を削除します。
+ ///
+ /// 削除するのインスタンス
+ /// がnull
+ /// を削除出来たらtrue,それ以外でそれ以外でfalse
+ public bool RemoveChip(MapChip chip)
+ {
+ if (!chips.Remove(chip)) return false;
+ chip.Owner = null;
+ requireUpdateVertexes = true;
+ return true;
+ }
+
+ ///
+ /// 頂点の更新をリクエストします。
+ ///
+ internal void RequestUpdateVertexes()
+ {
+ requireUpdateVertexes = true;
+ }
+
+ private void UpdateVertexes()
+ {
+ chips.SortIfRequired();
+
+ var size = Texture?.Size ?? new Vector2I(1, 1);
+ var vertexes = new Vertex[4 * chips.Count];
+ var basicVertexes = new[]
+ {
+ new Vector3F(0f, 0f, 0.5f),
+ new Vector3F(size.X, 0f, 0.5f),
+ new Vector3F(size.X, size.Y, 0.5f),
+ new Vector3F(0f, size.Y, 0.5f),
+ };
+
+ var buffers = new int[chips.Count * 6];
+
+ for (int i = 0; i < chips.Count; i++)
+ {
+ var chip = chips[i];
+ var uv0 = chip.Src.Position / size;
+ var uvSize = chip.Src.Size / size;
+
+ var i4 = i * 4;
+ vertexes[i4] = new Vertex(chip.Transform.Transform3D(basicVertexes[0]), chip.Color, uv0, default);
+ vertexes[i4 + 1] = new Vertex(chip.Transform.Transform3D(basicVertexes[1]), chip.Color, new Vector2F(uv0.X + uvSize.X, uv0.Y), default);
+ vertexes[i4 + 2] = new Vertex(chip.Transform.Transform3D(basicVertexes[2]), chip.Color, uv0 + uvSize, default);
+ vertexes[i4 + 3] = new Vertex(chip.Transform.Transform3D(basicVertexes[3]), chip.Color, new Vector2F(uv0.X, uv0.Y + uvSize.Y), default);
+
+ for (int j = 0; j < 2; j++)
+ {
+ buffers[i * 6 + j * 3] = i4;
+ buffers[i * 6 + j * 3 + 1] = i4 + j + 1;
+ buffers[i * 6 + j * 3 + 2] = i4 + j + 2;
+ }
+ }
+
+ renderedPolygon.Vertexes.FromSpan(vertexes);
+ renderedPolygon.Vertexes = renderedPolygon.Vertexes;
+
+ renderedPolygon.Buffers.FromSpan(buffers);
+ renderedPolygon.Buffers = renderedPolygon.Buffers;
+ }
+ }
+
+ ///
+ /// 大量描画に使用するマップチップ
+ ///
+ [Serializable]
+ public sealed class MapChip
+ {
+ private bool requireCalcTransform = true;
+
+ internal MapChipList List { get; set; }
+
+ internal TileMapNode Owner { get; set; }
+
+ ///
+ /// 回転角度を取得または設定します。
+ ///
+ public float Angle
+ {
+ get => _angle;
+ set
+ {
+ if (_angle == value) return;
+ _angle = value;
+ requireCalcTransform = true;
+ Owner?.RequestUpdateVertexes();
+ }
+ }
+ private float _angle;
+
+ ///
+ /// 中心座標を取得または設定します。
+ ///
+ public Vector2F CenterPosition
+ {
+ get => _centerPosition;
+ set
+ {
+ if (_centerPosition == value) return;
+ _centerPosition = value;
+ requireCalcTransform = true;
+ Owner?.RequestUpdateVertexes();
+ }
+ }
+ private Vector2F _centerPosition;
+
+ ///
+ /// 色を取得または設定します。
+ ///
+ public Color Color
+ {
+ get => _color;
+ set
+ {
+ if (_color == value) return;
+ _color = value;
+ Owner?.RequestUpdateVertexes();
+ }
+ }
+ private Color _color = new Color(255, 255, 255);
+
+ ///
+ /// 左右を反転するかどうかを取得または設定します。
+ ///
+ public bool HorizontalFlip
+ {
+ get => _horizontalFlip;
+ set
+ {
+ if (_horizontalFlip == value) return;
+ _horizontalFlip = value;
+ requireCalcTransform = true;
+ Owner?.RequestUpdateVertexes();
+ }
+ }
+ private bool _horizontalFlip = false;
+
+ ///
+ /// 座標を取得または設定します。
+ ///
+ public Vector2F Position
+ {
+ get => _position;
+ set
+ {
+ if (_position == value) return;
+ _position = value;
+ requireCalcTransform = true;
+ Owner?.RequestUpdateVertexes();
+ }
+ }
+ private Vector2F _position;
+
+ ///
+ /// 拡大率を取得または設定します。
+ ///
+ public Vector2F Scale
+ {
+ get => _scale;
+ set
+ {
+ if (_scale == value) return;
+ _scale = value;
+ requireCalcTransform = true;
+ Owner?.RequestUpdateVertexes();
+ }
+ }
+ private Vector2F _scale = Vector2F.One;
+
+ ///
+ /// テクスチャの描画範囲を取得または設定します。
+ ///
+ public RectF Src
+ {
+ get => _src;
+ set
+ {
+ if (_src == value) return;
+ _src = value;
+ Owner?.RequestUpdateVertexes();
+ }
+ }
+ private RectF _src;
+
+ ///
+ /// 変形行列を取得します。
+ ///
+ internal Matrix44F Transform
+ {
+ get
+ {
+ if (requireCalcTransform)
+ {
+ var scale = Scale;
+ if (HorizontalFlip) scale.X *= -1;
+ if (VerticalFlip) scale.Y *= -1;
+ _transform = MathHelper.CalcTransform(Position, MathHelper.DegreeToRadian(Angle), scale) * Matrix44F.GetTranslation2D(-CenterPosition);
+ requireCalcTransform = false;
+ }
+ return _transform;
+ }
+ }
+ private Matrix44F _transform = Matrix44F.Identity;
+
+ ///
+ /// 上下を反転するかどうかを取得または設定します。
+ ///
+ public bool VerticalFlip
+ {
+ get => _verticalFlip;
+ set
+ {
+ if (_verticalFlip == value) return;
+ _verticalFlip = value;
+ requireCalcTransform = true;
+ Owner?.RequestUpdateVertexes();
+ }
+ }
+ private bool _verticalFlip = false;
+
+ ///
+ /// 重ね順を取得または設定します。
+ ///
+ public int ZOrder
+ {
+ get => _zOrder;
+ set
+ {
+ if (_zOrder == value) return;
+ _zOrder = value;
+ List?.RequestSort();
+ Owner?.RequestUpdateVertexes();
+ }
+ }
+ private int _zOrder;
+
+ ///
+ /// の新しいインスタンスを生成します。
+ ///
+ public MapChip() { }
+
+ internal void OnAdded()
+ {
+ Src = new RectF(default, Owner.Texture?.Size ?? new Vector2I(1, 1));
+ }
+ }
+
+ ///
+ /// を格納するコレクション
+ ///
+ [Serializable]
+ internal sealed class MapChipList : IList, IReadOnlyList
+ {
+ private static readonly MapChipComparer comparer = new MapChipComparer();
+ private MapChip[] items;
+ private bool requireSorted;
+ private int version;
+
+ ///
+ /// 格納されている要素数を取得します。
+ ///
+ public int Count { get; private set; }
+
+ bool ICollection.IsReadOnly => false;
+
+ ///
+ /// の新しいインスタンスを生成します。
+ ///
+ public MapChipList()
+ {
+ items = Array.Empty();
+ }
+
+ ///
+ /// 指定したインデックスの要素を取得します。
+ ///
+ /// 検索する要素のインデックス
+ /// が範囲外
+ /// に対応する要素
+ public MapChip this[int index]
+ {
+ get
+ {
+ if (index < 0 || Count <= index) throw new ArgumentOutOfRangeException(nameof(index), "インデックスが範囲外です");
+ return items[index];
+ }
+ }
+ MapChip IList.this[int index]
+ {
+ get => this[index];
+ set => throw new NotSupportedException("この操作はサポートされていません");
+ }
+
+ ///
+ /// を追加します。
+ ///
+ /// 追加するのインスタンス
+ /// がnull
+ /// を追加出来たらtrue,それ以外でfalse
+ public bool Add(MapChip item)
+ {
+ if (item == null) throw new ArgumentNullException(nameof(item), "引数がnullです");
+ if (item.List != null) return false;
+ var index = Array.BinarySearch(items, 0, Count, item, comparer);
+ if (index < 0) InsertPrivate(~index, item);
+ else InsertPrivate(index, item);
+ return true;
+ }
+
+ ///
+ /// の新しいインスタンスを生成します。
+ ///
+ /// ソートするかどうか
+ /// の新しいインスタンス
+ public Enumerator GetEnumerator(bool sort)
+ {
+ if (sort) SortIfRequired();
+ return new Enumerator(this);
+ }
+
+ private void InsertPrivate(int index, MapChip item)
+ {
+ if (items.Length < Count + 1) ReSize(Count + 1);
+ if (index < Count) Array.Copy(items, index, items, index + 1, Count - index);
+ items[index] = item;
+ version++;
+ Count++;
+ item.List = this;
+ }
+
+ ///
+ /// ソートをリクエストします。
+ ///
+ public void RequestSort()
+ {
+ requireSorted = true;
+ }
+
+ private void ReSize(int min)
+ {
+ if (min <= items.Length) return;
+ var size = items.Length == 0 ? 4 : items.Length * 2;
+ if ((uint)size > int.MaxValue) size = int.MaxValue;
+ if (size < min) size = min;
+ Array.Resize(ref items, size);
+ }
+
+ ///
+ /// ソートを実行します。
+ ///
+ public void Sort()
+ {
+ Array.Sort(items, comparer);
+ requireSorted = false;
+ version++;
+ }
+
+ ///
+ /// 必要がある場合にソートを実行します。
+ ///
+ public void SortIfRequired()
+ {
+ if (requireSorted) Sort();
+ }
+
+ #region IList
+ void ICollection.Add(MapChip item) => Add(item);
+
+ ///
+ /// 全ての要素を削除します。
+ ///
+ public void Clear()
+ {
+ if (Count == 0) return;
+ for (int i = 0; i < Count; i++) items[i].List = null;
+ Array.Clear(items, 0, Count);
+ Count = 0;
+ version++;
+ }
+
+ ///
+ /// 指定したが格納されているかどうかを取得します。
+ ///
+ /// 検索するのインスタンス
+ /// が格納されていたらtrue,それ以外でfalse
+ public bool Contains(MapChip item) => item != null && item.List == this;
+
+ void ICollection.CopyTo(MapChip[] array, int arrayIndex)
+ {
+ if (array == null) throw new ArgumentNullException(nameof(array), "引数がnullです");
+ if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex), "値が0未満です");
+ if (array.Length < Count + arrayIndex) throw new ArgumentException("サイズが足りません", nameof(array));
+ for (int i = 0; i < Count; i++) array[arrayIndex++] = items[i];
+ }
+
+ ///
+ /// の新しいインスタンスを生成します。
+ ///
+ /// の新しいインスタンス
+ public Enumerator GetEnumerator() => GetEnumerator(false);
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+ ///
+ /// 指定したのインデックスを取得します。
+ ///
+ /// 検索するのインスタンス
+ /// のインデックス 格納されていない場合は-1
+ public int IndexOf(MapChip item) => Contains(item) ? Array.IndexOf(items, item) : -1;
+
+ void IList.Insert(int index, MapChip item) => throw new NotSupportedException("この操作はサポートされていません");
+
+ ///
+ /// を削除します。
+ ///
+ /// 削除するのインスタンス
+ /// がnull
+ /// を追加出来たらtrue,それ以外でfalse
+ public bool Remove(MapChip item)
+ {
+ if (item == null) throw new ArgumentNullException(nameof(item), "引数がnullです");
+ var index = IndexOf(item);
+ if (index < 0) return false;
+ RemoveAt(index);
+ return true;
+ }
+
+ ///
+ /// 指定したインデックスの要素を削除する
+ ///
+ /// 削除する要素のインデックス
+ /// が範囲外
+ public void RemoveAt(int index)
+ {
+ if (index < 0 || Count - 1 < index) throw new ArgumentOutOfRangeException(nameof(index), "インデックスが範囲外です");
+ var chip = items[index];
+ if (index < --Count) Array.Copy(items, index + 1, items, index, Count - index);
+ items[index] = default;
+ chip.List = null;
+ version++;
+ }
+ #endregion
+
+ ///
+ /// 列挙を補助する構造体
+ ///
+ [Serializable]
+ public struct Enumerator : IEnumerator
+ {
+ private readonly MapChipList list;
+ private int index;
+ private readonly int version;
+
+ ///
+ /// 現在列挙されている要素を取得します。
+ ///
+ public MapChip Current { get; private set; }
+ readonly object IEnumerator.Current
+ {
+ get
+ {
+ if (index == 0 || list.Count + 1 == index) throw new InvalidOperationException("要素の取得に失敗しました");
+ return Current;
+ }
+ }
+
+ internal Enumerator(MapChipList list)
+ {
+ this.list = list;
+ Current = default;
+ index = 0;
+ version = list.version;
+ }
+
+ ///
+ /// このインスタンスを破棄します。
+ ///
+ public void Dispose() { }
+
+ ///
+ /// 列挙を次に進めます。
+ ///
+ /// 列挙中にコレクションが変更された
+ /// 列挙を次に進められたらtrue,それ以外でfalse
+ public bool MoveNext()
+ {
+ if (version != list.version) throw new InvalidOperationException("列挙中にコレクションが変更されました");
+ if ((uint)index < (uint)list.Count)
+ {
+ Current = list[index++];
+ return true;
+ }
+ Current = default;
+ index = list.Count + 1;
+ return false;
+ }
+
+ void IEnumerator.Reset()
+ {
+ if (version != list.version) throw new InvalidOperationException("列挙中にコレクションが変更されました");
+ Current = default;
+ index = 0;
+ }
+ }
+
+ private sealed class MapChipComparer : IComparer
+ {
+ public int Compare(MapChip x, MapChip y)
+ {
+ if (x == null) return y == null ? 0 : -1;
+ if (y == null) return 1;
+ return x.ZOrder.CompareTo(y.ZOrder);
+ }
+ }
+ }
+}
diff --git a/Test/DrawnNode.cs b/Test/DrawnNode.cs
index 23c2dd38..cb3a4906 100644
--- a/Test/DrawnNode.cs
+++ b/Test/DrawnNode.cs
@@ -399,6 +399,51 @@ public void IBPolygonNodeWithTexture()
tc.End();
}
+ [Test, Apartment(ApartmentState.STA)]
+ public void TileMapNode()
+ {
+ var tc = new TestCore();
+ tc.Init();
+
+ var texture = Texture2D.Load(@"TestData/IO/AltseedPink.png");
+ Assert.NotNull(texture);
+
+ var node = new TileMapNode()
+ {
+ Position = new Vector2F(250, 250),
+ Texture = texture
+ };
+ Engine.AddNode(node);
+
+ Assert.True(node.AddMapChip(new MapChip()
+ {
+ Angle = 30f,
+ CenterPosition = texture.Size / 2,
+ Color = new Color(255, 100, 100),
+ Position = new Vector2F(100f, 100f),
+ ZOrder = 0
+ }));
+ Assert.True(node.AddMapChip(new MapChip()
+ {
+ CenterPosition = texture.Size / 2,
+ Color = new Color(100, 100, 255),
+ Position = new Vector2F(-50f, 0f),
+ ZOrder = 1
+ }));
+ Assert.True(node.AddMapChip(new MapChip()
+ {
+ CenterPosition = texture.Size / 2,
+ Color = new Color(100, 255, 100),
+ Position = new Vector2F(0f, 0f),
+ Scale = new Vector2F(0.5f, 0.5f),
+ ZOrder = 2
+ }));
+
+ tc.LoopBody(null, null);
+
+ tc.End();
+ }
+
[Test, Apartment(ApartmentState.STA)]
public void CenterPosition()
{
diff --git a/Test/ReflectionSources.cs b/Test/ReflectionSources.cs
index d8c4b76c..ede966f1 100644
--- a/Test/ReflectionSources.cs
+++ b/Test/ReflectionSources.cs
@@ -1198,6 +1198,71 @@ private static Dictionary GetInfo()
};
result.Add(textNode.Type, textNode);
+ // Altseed2.TileMapNode
+ var tileMapNode = ReflectionInfo.Create(new TileMapNode()
+ {
+ AlphaBlend = AlphaBlend.Normal,
+ Angle = 30f,
+ CameraGroup = 1,
+ CenterPosition = new Vector2F(50f, 50f),
+ HorizontalFlip = false,
+ IsDrawn = false,
+ Material = Material.Create(),
+ Position = new Vector2F(30f, 30f),
+ Scale = new Vector2F(3f, 2f),
+ Texture = Texture2D.LoadStrict("TestData/IO/AltseedPink.png"),
+ VerticalFlip = false,
+ ZOrder = 10,
+ });
+ tileMapNode.PropertyInfos = new[]
+ {
+ tileMapNode.GetProperty("AlphaBlend"),
+ tileMapNode.GetProperty("Angle"),
+ tileMapNode.GetProperty("CameraGroup"),
+ tileMapNode.GetProperty("CenterPosition"),
+ tileMapNode.GetProperty("ContentSize"),
+ tileMapNode.GetProperty("HorizontalFlip"),
+ tileMapNode.GetProperty("IsDrawn"),
+ tileMapNode.GetProperty("IsRegistered"),
+ tileMapNode.GetProperty("IsUpdated"),
+ tileMapNode.GetProperty("IsUpdatedActually"),
+ tileMapNode.GetProperty("Material"),
+ tileMapNode.GetProperty("Position"),
+ tileMapNode.GetProperty("Scale"),
+ tileMapNode.GetProperty("Status"),
+ tileMapNode.GetProperty("Texture"),
+ tileMapNode.GetProperty("VerticalFlip"),
+ tileMapNode.GetProperty("ZOrder"),
+ };
+ result.Add(tileMapNode.Type, tileMapNode);
+
+ // Altseed2.MapChip
+ var mapChip = ReflectionInfo.Create(new MapChip()
+ {
+ Angle = 30f,
+ CenterPosition = new Vector2F(50f, 50f),
+ Color = new Color(255, 100, 100),
+ HorizontalFlip = true,
+ Position = new Vector2F(100f, 100f),
+ Scale = new Vector2F(3f, 2f),
+ Src = new RectF(50f, 50f, 100f, 100f),
+ VerticalFlip = false,
+ ZOrder = 3,
+ });
+ mapChip.PropertyInfos = new[]
+ {
+ mapChip.GetProperty("Angle"),
+ mapChip.GetProperty("CenterPosition"),
+ mapChip.GetProperty("Color"),
+ mapChip.GetProperty("HorizontalFlip"),
+ mapChip.GetProperty("Position"),
+ mapChip.GetProperty("Scale"),
+ mapChip.GetProperty("Src"),
+ mapChip.GetProperty("VerticalFlip"),
+ mapChip.GetProperty("ZOrder"),
+ };
+ result.Add(mapChip.Type, mapChip);
+
// Altseed2.TransformerNode
var transformerNode = ReflectionInfo.Create(new TransformerNode()
{