work on minimap

This commit is contained in:
Boki 2026-02-17 13:24:12 -05:00
parent 3bb0315912
commit 2565028ad0
4 changed files with 33 additions and 21 deletions

View file

@ -263,6 +263,7 @@ public class MinimapCapture : IFrameConsumer, IDisposable
_colorTracker.SampleFrame(hsv, wallMask);
using var kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(3, 3));
Cv2.MorphologyEx(wallMask, wallMask, MorphTypes.Close, kernel); // fill 1-2px gaps
Cv2.Dilate(wallMask, wallMask, kernel);
FilterSmallComponents(wallMask, _config.WallMinArea);

View file

@ -161,6 +161,7 @@ public class NavigationExecutor : IDisposable
if (gdx * gdx + gdy * gdy < 20 * 20)
{
Log.Information("Checkpoint reached at ({X},{Y})", goal.X, goal.Y);
_worldMap.RemoveCheckpointOff(goal);
_checkpointGoal = null;
_currentPath = null; // force re-path
}

View file

@ -332,15 +332,14 @@ public class WorldMap : IDisposable
dstRoi.Set(row, col, (byte)MapCell.Explored);
}
// Mark fog on canvas (on top of Unknown or Explored — not Wall)
// Mark fog on canvas (only on Unknown cells — never overwrite Explored)
if (isCorner)
{
for (var row = 0; row < h; row++)
for (var col = 0; col < w; col++)
{
if (srcRoi.At<byte>(row, col) != (byte)MapCell.Fog) continue;
var dst = dstRoi.At<byte>(row, col);
if (dst == (byte)MapCell.Unknown || dst == (byte)MapCell.Explored)
if (dstRoi.At<byte>(row, col) == (byte)MapCell.Unknown)
dstRoi.Set(row, col, (byte)MapCell.Fog);
}
}
@ -359,8 +358,7 @@ public class WorldMap : IDisposable
var fy = srcY + row - halfSize;
if (fx * fx + fy * fy < fogInner2) continue;
var dst = dstRoi.At<byte>(row, col);
if (dst == (byte)MapCell.Unknown || dst == (byte)MapCell.Explored)
if (dstRoi.At<byte>(row, col) == (byte)MapCell.Unknown)
dstRoi.Set(row, col, (byte)MapCell.Fog);
}
}
@ -368,10 +366,7 @@ public class WorldMap : IDisposable
}
/// <summary>
/// Mark explored area: circle around player position.
/// Unknown cells are marked Explored within the full radius.
/// Fog cells are only cleared in the inner portion (fogClearRadius),
/// preserving fog at the edge so it stays visible on the viewport.
/// Mark explored area: circle around player position, overwrite Unknown and Fog cells.
/// </summary>
private void PaintExploredCircle(MapPosition position)
{
@ -379,8 +374,6 @@ public class WorldMap : IDisposable
var pcy = (int)Math.Round(position.Y);
var r = _config.ExploredRadius;
var r2 = r * r;
var fogClear = r - 20;
var fogClear2 = fogClear * fogClear;
var y0 = Math.Max(0, pcy - r);
var y1 = Math.Min(_canvasSize - 1, pcy + r);
@ -392,12 +385,9 @@ public class WorldMap : IDisposable
{
var dx = x - pcx;
var dy = y - pcy;
var d2 = dx * dx + dy * dy;
if (d2 > r2) continue;
if (dx * dx + dy * dy > r2) continue;
var cell = _canvas.At<byte>(y, x);
if (cell == (byte)MapCell.Unknown)
_canvas.Set(y, x, (byte)MapCell.Explored);
else if (cell == (byte)MapCell.Fog && d2 <= fogClear2)
if (cell == (byte)MapCell.Unknown || cell == (byte)MapCell.Fog)
_canvas.Set(y, x, (byte)MapCell.Explored);
}
}
@ -604,6 +594,24 @@ public class WorldMap : IDisposable
return false;
}
/// <summary>
/// Remove a checkpoint from the off list (e.g. when the player has reached it).
/// </summary>
public void RemoveCheckpointOff(Point cp, int radius = 20)
{
var r2 = radius * radius;
for (var i = _checkpointsOff.Count - 1; i >= 0; i--)
{
var dx = _checkpointsOff[i].Pos.X - cp.X;
var dy = _checkpointsOff[i].Pos.Y - cp.Y;
if (dx * dx + dy * dy <= r2)
{
_checkpointsOff.RemoveAt(i);
break;
}
}
}
/// <summary>
/// Returns the nearest unactivated checkpoint within maxDist canvas pixels, or null.
/// </summary>

View file

@ -73,12 +73,12 @@
<TabItem Header="State">
<Grid RowDefinitions="Auto,*" Margin="0,6,0,0">
<!-- Top row: Inventory + Minimap side by side -->
<Grid Grid.Row="0" ColumnDefinitions="*,Auto" Margin="0,0,0,6">
<!-- Top row: Inventory + Minimap side by side (splitter-resizable) -->
<Grid Grid.Row="0" ColumnDefinitions="*,5,300" Margin="0,0,0,6">
<!-- Inventory Grid (12x5) -->
<Border Grid.Column="0" Background="#161b22" BorderBrush="#30363d"
BorderThickness="1" CornerRadius="8" Padding="8" Margin="0,0,6,0">
BorderThickness="1" CornerRadius="8" Padding="8" MinWidth="200">
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,4">
<TextBlock Text="INVENTORY" FontSize="11" FontWeight="SemiBold"
@ -107,9 +107,11 @@
</DockPanel>
</Border>
<GridSplitter Grid.Column="1" Background="Transparent" />
<!-- Minimap -->
<Border Grid.Column="1" Background="#161b22" BorderBrush="#30363d"
BorderThickness="1" CornerRadius="8" Padding="8" Width="300">
<Border Grid.Column="2" Background="#161b22" BorderBrush="#30363d"
BorderThickness="1" CornerRadius="8" Padding="8" MinWidth="150">
<DockPanel>
<Grid DockPanel.Dock="Top" ColumnDefinitions="Auto,*,Auto" Margin="0,0,0,4">
<TextBlock Grid.Column="0" Text="MINIMAP" FontSize="11" FontWeight="SemiBold"