Render terrain from tilemap
This commit is contained in:
BIN
src/ReactorMaintenance.Win2D/Images/tilemap.png
Normal file
BIN
src/ReactorMaintenance.Win2D/Images/tilemap.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 MiB |
@@ -41,6 +41,7 @@
|
|||||||
<canvas:CanvasControl
|
<canvas:CanvasControl
|
||||||
x:Name="LevelCanvas"
|
x:Name="LevelCanvas"
|
||||||
ClearColor="#101215"
|
ClearColor="#101215"
|
||||||
|
CreateResources="LevelCanvas_CreateResources"
|
||||||
Draw="LevelCanvas_Draw"
|
Draw="LevelCanvas_Draw"
|
||||||
PointerPressed="LevelCanvas_PointerPressed"
|
PointerPressed="LevelCanvas_PointerPressed"
|
||||||
PointerMoved="LevelCanvas_PointerMoved"
|
PointerMoved="LevelCanvas_PointerMoved"
|
||||||
@@ -87,4 +88,4 @@
|
|||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ using Windows.Storage;
|
|||||||
using Windows.Storage.Pickers;
|
using Windows.Storage.Pickers;
|
||||||
using Windows.UI;
|
using Windows.UI;
|
||||||
using Microsoft.Graphics.Canvas;
|
using Microsoft.Graphics.Canvas;
|
||||||
using Microsoft.Graphics.Canvas.Geometry;
|
|
||||||
using Microsoft.Graphics.Canvas.Text;
|
using Microsoft.Graphics.Canvas.Text;
|
||||||
|
using Microsoft.Graphics.Canvas.UI;
|
||||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||||
using Microsoft.UI;
|
using Microsoft.UI;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
@@ -43,6 +43,16 @@ public sealed partial class MainWindow
|
|||||||
RefreshInspector();
|
RefreshInspector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LevelCanvas_CreateResources(CanvasControl sender, CanvasCreateResourcesEventArgs args)
|
||||||
|
{
|
||||||
|
args.TrackAsyncAction(LoadTilemapAsync(sender).AsAsyncAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadTilemapAsync(CanvasControl sender)
|
||||||
|
{
|
||||||
|
m_TerrainTilemap = await CanvasBitmap.LoadAsync(sender, new Uri("ms-appx:///Images/tilemap.png"));
|
||||||
|
}
|
||||||
|
|
||||||
private void ToolPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void ToolPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (ToolPicker.SelectedItem is EEditorTool tool)
|
if (ToolPicker.SelectedItem is EEditorTool tool)
|
||||||
@@ -213,99 +223,41 @@ public sealed partial class MainWindow
|
|||||||
|
|
||||||
private void DrawDualTerrainTile(CanvasDrawingSession drawing, Rect rect, int floorMask)
|
private void DrawDualTerrainTile(CanvasDrawingSession drawing, Rect rect, int floorMask)
|
||||||
{
|
{
|
||||||
var wallColor = ColorHelper.FromArgb(255, 54, 61, 68);
|
if (m_TerrainTilemap is null)
|
||||||
var floorColor = ColorHelper.FromArgb(255, 31, 36, 40);
|
return;
|
||||||
|
|
||||||
var wallMask = c_AllCorners ^ floorMask;
|
var wallMask = c_AllCorners ^ floorMask;
|
||||||
|
var sourceRect = TilemapSourceRect(wallMask);
|
||||||
drawing.FillRectangle(rect, floorColor);
|
drawing.DrawImage(m_TerrainTilemap, rect, sourceRect);
|
||||||
DrawDualTerrainTile(drawing, rect, wallColor, floorColor, GetDualTerrainTileId(wallMask));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetDualTerrainTileId(int wallMask)
|
private static Rect TilemapSourceRect(int wallMask)
|
||||||
{
|
{
|
||||||
return wallMask;
|
var tilePosition = wallMask switch {
|
||||||
}
|
c_BottomLeftCorner => new GridPosition(0, 0),
|
||||||
|
c_TopRightCorner | c_BottomRightCorner => new GridPosition(1, 0),
|
||||||
private static void DrawDualTerrainTile(CanvasDrawingSession drawing, Rect rect, Color wallColor, Color floorColor, int tileId)
|
c_TopLeftCorner | c_BottomLeftCorner | c_BottomRightCorner => new GridPosition(2, 0),
|
||||||
{
|
c_BottomLeftCorner | c_BottomRightCorner => new GridPosition(3, 0),
|
||||||
if (tileId == 0)
|
c_TopLeftCorner | c_BottomRightCorner => new GridPosition(0, 1),
|
||||||
return;
|
c_BottomLeftCorner | c_TopRightCorner | c_BottomRightCorner => new GridPosition(1, 1),
|
||||||
|
c_AllCorners => new GridPosition(2, 1),
|
||||||
if (tileId == c_AllCorners)
|
c_TopLeftCorner | c_BottomLeftCorner | c_TopRightCorner => new GridPosition(3, 1),
|
||||||
{
|
c_TopRightCorner => new GridPosition(0, 2),
|
||||||
drawing.FillRectangle(rect, wallColor);
|
c_TopLeftCorner | c_TopRightCorner => new GridPosition(1, 2),
|
||||||
return;
|
c_TopLeftCorner | c_TopRightCorner | c_BottomRightCorner => new GridPosition(2, 2),
|
||||||
}
|
c_BottomLeftCorner | c_TopLeftCorner => new GridPosition(3, 2),
|
||||||
|
0 => new GridPosition(0, 3),
|
||||||
switch (tileId)
|
c_BottomRightCorner => new GridPosition(1, 3),
|
||||||
{
|
c_BottomLeftCorner | c_TopRightCorner => new GridPosition(2, 3),
|
||||||
case c_TopLeftCorner:
|
c_TopLeftCorner => new GridPosition(3, 3),
|
||||||
case c_TopRightCorner:
|
_ => throw new ArgumentOutOfRangeException(nameof(wallMask), wallMask, "Unsupported tile mask.")
|
||||||
case c_BottomLeftCorner:
|
|
||||||
case c_BottomRightCorner:
|
|
||||||
DrawTerrainCorner(drawing, rect, wallColor, tileId);
|
|
||||||
break;
|
|
||||||
case c_TopLeftCorner | c_TopRightCorner:
|
|
||||||
drawing.FillRectangle(new(rect.X, rect.Y, rect.Width, rect.Height / 2), wallColor);
|
|
||||||
break;
|
|
||||||
case c_BottomLeftCorner | c_BottomRightCorner:
|
|
||||||
drawing.FillRectangle(new(rect.X, rect.Y + rect.Height / 2, rect.Width, rect.Height / 2), wallColor);
|
|
||||||
break;
|
|
||||||
case c_TopLeftCorner | c_BottomLeftCorner:
|
|
||||||
drawing.FillRectangle(new(rect.X, rect.Y, rect.Width / 2, rect.Height), wallColor);
|
|
||||||
break;
|
|
||||||
case c_TopRightCorner | c_BottomRightCorner:
|
|
||||||
drawing.FillRectangle(new(rect.X + rect.Width / 2, rect.Y, rect.Width / 2, rect.Height), wallColor);
|
|
||||||
break;
|
|
||||||
case c_TopLeftCorner | c_BottomRightCorner:
|
|
||||||
DrawTerrainCorner(drawing, rect, wallColor, c_TopLeftCorner);
|
|
||||||
DrawTerrainCorner(drawing, rect, wallColor, c_BottomRightCorner);
|
|
||||||
break;
|
|
||||||
case c_TopRightCorner | c_BottomLeftCorner:
|
|
||||||
DrawTerrainCorner(drawing, rect, wallColor, c_TopRightCorner);
|
|
||||||
DrawTerrainCorner(drawing, rect, wallColor, c_BottomLeftCorner);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
drawing.FillRectangle(rect, wallColor);
|
|
||||||
DrawTerrainCorner(drawing, rect, floorColor, c_AllCorners ^ tileId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DrawTerrainCorner(CanvasDrawingSession drawing, Rect rect, Color color, int corner)
|
|
||||||
{
|
|
||||||
var radiusX = (float)rect.Width / 2;
|
|
||||||
var radiusY = (float)rect.Height / 2;
|
|
||||||
var center = corner switch {
|
|
||||||
c_TopLeftCorner => new Vector2((float)rect.X, (float)rect.Y),
|
|
||||||
c_TopRightCorner => new Vector2((float)(rect.X + rect.Width), (float)rect.Y),
|
|
||||||
c_BottomRightCorner => new Vector2((float)(rect.X + rect.Width), (float)(rect.Y + rect.Height)),
|
|
||||||
c_BottomLeftCorner => new Vector2((float)rect.X, (float)(rect.Y + rect.Height)),
|
|
||||||
_ => new Vector2((float)(rect.X + rect.Width / 2), (float)(rect.Y + rect.Height / 2))
|
|
||||||
};
|
|
||||||
var start = corner switch {
|
|
||||||
c_TopLeftCorner => new Vector2(center.X + radiusX, center.Y),
|
|
||||||
c_TopRightCorner => new Vector2(center.X, center.Y + radiusY),
|
|
||||||
c_BottomRightCorner => new Vector2(center.X - radiusX, center.Y),
|
|
||||||
c_BottomLeftCorner => new Vector2(center.X, center.Y - radiusY),
|
|
||||||
_ => center
|
|
||||||
};
|
|
||||||
var end = corner switch {
|
|
||||||
c_TopLeftCorner => new Vector2(center.X, center.Y + radiusY),
|
|
||||||
c_TopRightCorner => new Vector2(center.X - radiusX, center.Y),
|
|
||||||
c_BottomRightCorner => new Vector2(center.X, center.Y - radiusY),
|
|
||||||
c_BottomLeftCorner => new Vector2(center.X + radiusX, center.Y),
|
|
||||||
_ => center
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using var builder = new CanvasPathBuilder(drawing);
|
return new(
|
||||||
builder.BeginFigure(center);
|
tilePosition.X * c_TilemapTileSize,
|
||||||
builder.AddLine(start);
|
tilePosition.Y * c_TilemapTileSize,
|
||||||
builder.AddArc(end, radiusX, radiusY, 0, CanvasSweepDirection.Clockwise, CanvasArcSize.Small);
|
c_TilemapTileSize,
|
||||||
builder.EndFigure(CanvasFigureLoop.Closed);
|
c_TilemapTileSize);
|
||||||
|
|
||||||
using var geometry = CanvasGeometry.CreatePath(builder);
|
|
||||||
drawing.FillGeometry(geometry, color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetDualTileMask(int x, int y)
|
private int GetDualTileMask(int x, int y)
|
||||||
@@ -486,11 +438,13 @@ public sealed partial class MainWindow
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly SimulationEngine m_Simulation = new();
|
private readonly SimulationEngine m_Simulation = new();
|
||||||
|
private const int c_TilemapTileSize = 512;
|
||||||
private const int c_TopLeftCorner = 1;
|
private const int c_TopLeftCorner = 1;
|
||||||
private const int c_TopRightCorner = 2;
|
private const int c_TopRightCorner = 2;
|
||||||
private const int c_BottomLeftCorner = 4;
|
private const int c_BottomLeftCorner = 4;
|
||||||
private const int c_BottomRightCorner = 8;
|
private const int c_BottomRightCorner = 8;
|
||||||
private const int c_AllCorners = c_TopLeftCorner | c_TopRightCorner | c_BottomLeftCorner | c_BottomRightCorner;
|
private const int c_AllCorners = c_TopLeftCorner | c_TopRightCorner | c_BottomLeftCorner | c_BottomRightCorner;
|
||||||
|
private CanvasBitmap? m_TerrainTilemap;
|
||||||
private StorageFile? m_CurrentFile;
|
private StorageFile? m_CurrentFile;
|
||||||
private LevelState m_Level;
|
private LevelState m_Level;
|
||||||
private bool m_Painting;
|
private bool m_Painting;
|
||||||
|
|||||||
@@ -24,4 +24,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\ReactorMaintenance.Simulation\ReactorMaintenance.Simulation.csproj" />
|
<ProjectReference Include="..\ReactorMaintenance.Simulation\ReactorMaintenance.Simulation.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Images\tilemap.png" CopyToOutputDirectory="PreserveNewest" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user