| name | shapes |
| description | Working with Shapes in FlatRedBall2. Use when working with AARect, Circle, Polygon, TileShapes, shape creation, visibility, color, IsFilled, OutlineThickness, or visual properties of shapes. Also covers SolidSides for one-way platforms and tile grids. Trigger on any shape-related question. |
Working with Shapes in FlatRedBall2
All shape types and TileShapes are in the FlatRedBall2.Collision namespace — add using FlatRedBall2.Collision; in any file that uses them.
FlatRedBall2 has three built-in shape types: AARect, Circle, and Polygon. All shapes implement both IRenderable and ICollidable, so they handle both drawing and collision.
Shape Types
| Type | Key Properties | Notes |
|---|
AARect | Width, Height | Cannot rotate |
Circle | Radius | |
Polygon | Points, Rotation | Use factory methods to create |
Exposing a shape from an Entity: make the field a public auto-property (public Circle Circle { get; private set; }) and let callers write entity.Circle.Color = ... directly. Do not wrap it in a forwarding property like FillColor — that pattern silently fails when assigned after CustomInitialize. See entities-and-factories → references/reactive-properties.md.
Step 1: Create a Shape
var rect = new AARect { X = 0, Y = 0, Width = 64, Height = 64 };
var circle = new Circle { X = 100, Y = 0, Radius = 32 };
var poly = Polygon.CreateRectangle(64, 64);
var custom = Polygon.FromPoints(new[] {
new Vector2(0, 0), new Vector2(50, 0), new Vector2(25, 40),
});
Step 2: Make the Shape Visible
Shapes default to IsVisible = false. Always set IsVisible = true or the shape won't render.
Step 3: Add to the Render Pipeline
Option A — Directly on the Screen: Call Add in CustomInitialize:
Add(rect);
Option B — Attached to an Entity: entity.Add(shape) auto-adds to the render pipeline (as long as Engine is set).
Note: entity.Add(child) only auto-registers if the entity already has an Engine reference (via Factory or Screen.Register).
Visual Properties
var rect = new AARect
{
Color = new Color(220, 60, 60, 200),
IsFilled = false,
OutlineThickness = 3f,
IsVisible = true,
};
Polygon fill: IsFilled = true ear-clip triangulates and fills the interior (works for concave polygons). IsFilled = false renders outline only. Set OutlineThickness = 0 to suppress the border when filled.
Dashed/dotted outlines, gradients, drop shadows: FRB shapes render solid outlines only. For richer visualization, drop into Gum's RectangleRuntime — Gum ships with every FRB2 game, so there's nothing to add (see gum-integration). Docs: https://docs.flatredball.com/gum/code/standard-visuals/rectangleruntime
Cleanup
rect.Destroy();
For shapes added directly to the screen (not via entity.Add), also call Remove(rect).
Common Pitfalls
- Shape is invisible — forgot
IsVisible = true. Default is false.
- Shape is not drawn — forgot
Add(shape) on screen, or entity.Add(shape) before entity was registered.
- Shape position looks wrong — Y+ is up (see
physics-and-movement). In platformers, entity origin = feet, so offset shapes upward by Height/2 (see platformer-movement skill).
- Polygon not rotating — use
Polygon, not AARect.
TileShapes
TileShapes is a grid-based static collision structure for tile maps. Set X, Y, and GridSize before adding tiles — positions are computed at insertion time and not updated if those properties change later.
var tiles = new TileShapes { X = 0f, Y = 0f, GridSize = 16f };
tiles.AddTileAtCell(int col, int row);
tiles.AddTileAtWorld(float x, float y);
tiles.RemoveTileAtCell(col, row);
tiles.GetTileAtCell(col, row);
tiles.IsVisible = true;
SolidSides are maintained automatically on every add/remove — interior shared edges between adjacent tiles are cleared to prevent seam snagging. No manual refresh needed.
Integrates with AddCollisionRelationship — see collision-relationships skill.
SolidSides (AARect only)
Controls which sides of a rectangle act as solid collision surfaces. Use for one-way platforms (SolidSides.Up = only top is solid) and removing interior sides from adjacent tiles to prevent seam snagging.
Default is SolidSides.All. Values combine with | and &= ~.
For detailed usage and dynamic tile grids, see:
references/reposition-directions.md — Full examples, dynamic grids, Gum naming conflict workaround
Debug overlay
Overlay.DrawSolidSides visualizes RD state on the set of rectangles you ask about: each active face shows a small green triangle inside the rect pointing toward that face; suppressed faces show nothing. Pass a Factory<T> to inspect every entity's first AARect child, or a TileShapes to inspect every tile. There is no parameterless overload — the caller always specifies what to see.
public override void CustomActivity(FrameTime time)
{
Overlay.DrawSolidSides(_brickFactory);
Overlay.DrawSolidSides(_solidTiles);
}