2using System.Runtime.Serialization;
17[JsonObject(IsReference =
true)]
20 #region static members
27 #endregion static members
34 protected internal int zOrder = 0;
38 protected internal bool visible;
42 protected internal Frame frame;
46 protected internal bool enableFog =
false;
50 protected internal Animator? animator;
61 private bool _adjustCollisionAreaByFrame;
62 private bool _hasAssignedFrame;
63 private bool _collisionAdjustExplicitlySet;
65 private bool _collisionTypeByFrame;
66 private bool _collisionTypeExplicitlySet;
67 private bool _collisionsEnabled;
68 private string? _collisionProfileName;
69 private long _sortKeyRenderPassId;
70 private TileSortKey _sortKey;
74 #region abstract properties
93 #endregion abstract properties
95 #region IDrawable members
101 public Guid
Id {
get;
internal set; } = Guid.NewGuid();
159 backbuffer.DrawTileFrame(
this, destRectScreen);
161 #endregion IDrawable members
183 bool usesDirtyRegionRendering =
184 SceneLayer.Scene?.UsesDirtyRegionRendering ??
true;
186 if (usesDirtyRegionRendering)
191 bool hasFrame = value.Tilesheet is not
null;
193 (_adjustCollisionAreaByFrame ||
194 (!_hasAssignedFrame && !_collisionAdjustExplicitlySet)))
196 SetCollisionAdjustFromFrame(value);
200 (_collisionTypeByFrame ||
201 (!_hasAssignedFrame && !_collisionTypeExplicitlySet)))
203 SetCollisionTypeFromFrame(value);
206 _hasAssignedFrame = hasFrame;
208 if (usesDirtyRegionRendering)
257 SceneLayer.CoordinateSystem.GetPolygonPts(
this,
false);
270 get => _adjustCollisionAreaByFrame;
273 _adjustCollisionAreaByFrame = value;
275 if (value && frame.Tilesheet is not
null)
276 SetCollisionAdjustFromFrame(frame);
286 get => _adjustCollisionArea;
289 _adjustCollisionArea = value;
290 _collisionAdjustExplicitlySet =
true;
301 get => _collisionType;
304 _collisionTypeExplicitlySet =
true;
305 SetCollisionTypeCore(value);
316 get => _collisionTypeByFrame;
319 _collisionTypeByFrame = value;
321 if (value && frame.Tilesheet is not
null)
322 SetCollisionTypeFromFrame(frame);
332 get => _collisionProfileName;
333 private set => _collisionProfileName = value;
342 get => _collisionsEnabled;
345 _collisionTypeExplicitlySet =
true;
355 SetCollisionTypeCore(enabledType);
378 if (
string.IsNullOrWhiteSpace(profileName))
379 throw new ArgumentException(
"Collision profile name cannot be empty.", nameof(profileName));
382 if (scene is not
null)
384 var profile = scene.CollisionProfiles.Get(profileName);
385 _ = profile.ResolveCollisionGroup(scene.CollisionGroups);
386 _ = profile.ResolveCollidesWith(scene.CollisionGroups);
390 ApplyCollisionProfileToCollider();
397 internal void RefreshCollisionProfile() => ApplyCollisionProfileToCollider();
405 ArgumentNullException.ThrowIfNull(source);
407 _adjustCollisionArea = source._adjustCollisionArea;
408 _adjustCollisionAreaByFrame = source._adjustCollisionAreaByFrame;
409 _hasAssignedFrame = frame.Tilesheet is not
null;
410 _collisionAdjustExplicitlySet = source._collisionAdjustExplicitlySet;
411 _collisionType = source._collisionType;
412 _collisionTypeByFrame = source._collisionTypeByFrame;
413 _collisionTypeExplicitlySet = source._collisionTypeExplicitlySet;
414 _collisionsEnabled = source._collisionsEnabled;
415 _collisionProfileName = source._collisionProfileName;
418 private void SetCollisionAdjustFromFrame(
Frame value)
425 private void SetCollisionTypeFromFrame(
Frame value)
434 _collisionType = collisionType;
435 ApplyCollisionTypeToCollider();
439 private void ApplyCollisionTypeToCollider()
444 switch (_collisionType)
455 private void SetCollisionsEnabledCore(
bool enabled)
457 _collisionsEnabled = enabled;
458 SynchronizeColliderRegistration();
461 private void SynchronizeColliderRegistration()
466 if (_collisionsEnabled)
472 private void ApplyCollisionProfileToCollider()
474 if (
_collider is
null ||
string.IsNullOrWhiteSpace(_collisionProfileName))
481 var profile = scene.CollisionProfiles.Get(_collisionProfileName);
482 _collider.CollisionGroup = profile.ResolveCollisionGroup(scene.CollisionGroups);
483 _collider.CollidesWith = profile.ResolveCollidesWith(scene.CollisionGroups);
506 ArgumentNullException.ThrowIfNull(collider);
512 ApplyCollisionProfileToCollider();
513 ApplyCollisionTypeToCollider();
514 SynchronizeColliderRegistration();
518 private void OnTileDeserialized(StreamingContext context)
520 _hasAssignedFrame = frame.Tilesheet is not
null;
522 if (_adjustCollisionAreaByFrame && _hasAssignedFrame)
523 SetCollisionAdjustFromFrame(frame);
525 if (_collisionTypeByFrame && _hasAssignedFrame)
526 SetCollisionTypeFromFrame(frame);
529 #region IComparable<Tile> Members
541 var thisKey = GetSortKeyForCompare();
542 var tileKey = tile.GetSortKeyForCompare();
544 if (thisKey.IsPositionFixed && !tileKey.IsPositionFixed)
547 if (!thisKey.IsPositionFixed && tileKey.IsPositionFixed)
550 return (thisKey.Location, thisKey.ZOrder, thisKey.SceneLayerX)
551 .CompareTo((tileKey.Location, tileKey.ZOrder, tileKey.SceneLayerX));
554 private TileSortKey GetSortKeyForCompare()
556 var renderContext = RenderContext.Current;
561 if (renderContext is
null)
562 return CaptureSortKey();
564 long renderPassId = renderContext.PassId;
565 if (_sortKeyRenderPassId != renderPassId)
567 _sortKey = CaptureSortKey();
568 _sortKeyRenderPassId = renderPassId;
574 private TileSortKey CaptureSortKey()
579 float location = isPositionFixed
580 ? drawLocationWorld.Top + overhang.Top
581 : drawLocationWorld.Bottom - overhang.Bottom - 1;
583 return new TileSortKey(
590 private readonly record
struct TileSortKey(
596 #endregion IComparable<Tile> Members
598 #region IDisposable Members
614 GC.SuppressFinalize(
this);
617 #endregion IDisposable Members
Manages animation playback for a Tile, controlling animation cycles, frame timing,...
Represents an abstract base class for drawable tiles in the Gondwana engine. Provides core functional...
bool CollisionsEnabled
Gets or sets whether this tile participates in collision detection.
virtual bool EnableFog
Gets or sets whether scene-layer fog applies to this tile.
virtual bool Visible
Gets or sets whether this drawable is visible.
virtual RectangleF GetCollisionAreaScreen(View view)
Transforms the collision bounds into screen pixels for the specified view.
virtual Frame CurrentFrame
Gets or sets the current frame. The initial frame supplies the tile's default collision adjustment an...
virtual RectangleF GetDrawLocationScreen(View view)
Transforms the drawable bounds into screen pixels for the specified view.
void AttachCollider(ICollider collider)
Attaches this tile's collider and applies any collision state that was set before the collider became...
virtual Rectangle CollisionArea
Gets the effective collision area in world coordinates.
SceneLayer SceneLayer
Gets the scene layer that owns this tile.
virtual void Draw(BackbufferBase backbuffer, RectangleF destRectScreen)
Draws the current content into the backbuffer at the supplied screen-pixel bounds.
virtual ? ICollider Collider
Gets the collision shape associated with this tile.
bool pauseAnimation
The pause animation.
void CopyCollisionSettingsFrom(Tile source)
Copies collision behavior, profile, and effective frame metadata from another tile.
string? Nickname
Gets or sets the optional lookup name.
virtual Point[] OutlinePointsWorld
Gets the tile outline vertices in world pixels.
virtual TileCollisionType CollisionType
Gets or sets the tile's collision behavior. This is initialized from the first assigned frame and may...
virtual void Dispose()
Releases the resources owned by this instance.
virtual bool AdjustCollisionAreaByFrame
Gets or sets whether frame changes replace the tile's collision adjustment with the newly selected fr...
virtual bool PauseAnimation
Gets or sets whether animation is paused.
virtual int ZOrder
Gets or sets the drawing order within the layer.
void SetCollisionProfile(string profileName)
Applies a named profile from this tile's parent scene. If the layer has not yet been attached to a sc...
TypedValueBag ValueBag
Gets the custom typed values associated with this object.
int CompareTo(Tile? tile)
Compares this tile with another tile using their render ordering.
Rectangle DrawLocationWorld
Gets the tile drawing bounds in world pixels.
virtual Spacing Overhang
Gets the current frame's visual overhang beyond its tile bounds.
void DetachCollider()
Detaches the current collider from its scene-layer registry without otherwise changing this tile's se...
string? CollisionProfileName
Gets the scene-level collision profile currently associated with this tile.
ICollider? _collider
The collider.
virtual Animator TileAnimator
Gets the animator associated with this tile.
static List< Tile > TilesAnimating
Gets the collection of all tiles that are currently animating in the scene.
virtual CollisionAdjust AdjustCollisionArea
Gets or sets the collision adjustment used to derive CollisionArea.
Guid Id
Gets the unique identifier.
virtual bool CollisionTypeByFrame
Gets or sets whether frame changes replace this tile's collision type with the newly selected frame's...
bool IsPositionFixed
Gets whether the tile occupies a fixed position in its layer.
PointF SceneLayerCoordinates
Gets the position in scene-layer grid coordinates.
Represents a base class for managing a graphical backbuffer, and is the in-memory surface where rende...
Represents a rendered view of a scene, combining a camera position with a viewport configuration to c...
A flexible, strongly-typed value container intended for runtime-attached metadata and ephemeral engin...
Represents an object that can be drawn on a visual surface, with properties for visibility and stacki...
World-space axis-aligned collider used by the collision system.
Represents an entity that participates in the collision system and has a defined collision area.
record struct Spacing([property:JsonProperty("left")] int Left, [property:JsonProperty("top")] int Top, [property:JsonProperty("right")] int Right, [property:JsonProperty("bottom")] int Bottom)
Represents dimensions in pixels when spacing Tilesheets.
CollisionResponseType
Defines how a collider responds to collisions with other colliders.
@ Trigger
Trigger collision response that reports overlaps without applying push-out or blocking movement.
TileCollisionType
Defines the default collision behavior associated with a tilesheet region, frame, or runtime tile.
@ None
Collision is disabled.
@ Blocking
Collision is enabled and overlapping solid colliders block movement.
@ Trigger
Collision is enabled and overlaps are reported without blocking movement.
Represents the source Tilesheet and its coordinates to render on a destination.
CollisionAdjust CollisionAdjust
Gets or sets the collision adjustment associated with this frame's region coordinates.
TileCollisionType CollisionType
Gets or sets the effective collision type associated with this frame's region coordinates.
Per-edge inset amounts applied to visual bounds to produce a collision rectangle.
static readonly CollisionAdjust None
Represents an adjustment with no pixel offsets.