Files

58 lines
1.9 KiB
C#
Raw Permalink Normal View History

using Godot;
using Theriapolis.Core;
using Theriapolis.Core.Tactical;
namespace Theriapolis.GodotHost.Rendering;
/// <summary>
/// One Node2D per tactical chunk. Positioned at (chunk.OriginX, chunk.OriginY)
/// in world-pixel space; renders all CHUNK_SIZE x CHUNK_SIZE tiles via _Draw.
///
/// Godot caches CanvasItem _Draw output, so _Draw runs once on first paint
/// and the rasterised result is reused every frame thereafter. We only call
/// QueueRedraw() if the chunk's delta changes (M4 doesn't yet — chunks are
/// static once generated).
///
/// Each tactical tile is 1 world pixel wide; the source sprite is
/// TACTICAL_TILE_SPRITE_PX² and gets squashed into that 1×1 cell via
/// DrawTextureRect's destination rect. The camera's zoom (32x for tactical
/// view) magnifies the rasterisation back to native sprite resolution.
/// </summary>
public partial class TacticalChunkNode : Node2D
{
private TacticalChunk? _chunk;
public void Bind(TacticalChunk chunk)
{
_chunk = chunk;
Position = new Vector2(chunk.OriginX, chunk.OriginY);
QueueRedraw();
}
public override void _Draw()
{
if (_chunk is null) return;
int size = C.TACTICAL_CHUNK_SIZE;
// Pass 1: surfaces.
for (int ly = 0; ly < size; ly++)
for (int lx = 0; lx < size; lx++)
{
ref var t = ref _chunk.Tiles[lx, ly];
var tex = TacticalAtlas.GetSurface(t.Surface, t.Variant);
DrawTextureRect(tex, new Rect2(lx, ly, 1, 1), false);
}
// Pass 2: decos on top.
for (int ly = 0; ly < size; ly++)
for (int lx = 0; lx < size; lx++)
{
ref var t = ref _chunk.Tiles[lx, ly];
var tex = TacticalAtlas.GetDeco(t.Deco, t.Variant);
if (tex is null) continue;
DrawTextureRect(tex, new Rect2(lx, ly, 1, 1), false);
}
}
}