Guards can spot you

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-13 19:31:40 +01:00
parent 92f6e23b82
commit c38595b393

View File

@@ -281,18 +281,26 @@ class _WolfRendererState extends State<WolfRenderer>
}
_spaceWasPressed = isSpacePressed;
// --- 4. UPDATE ENTITY SPRITES (8-WAY DIRECTIONAL) ---
// --- 4. UPDATE ENTITY LOGIC ---
for (Entity entity in entities) {
// 1. Wake up if the player is spotted!
if (entity.state == EntityState.idle) {
// Find angle from the guard TO the player
if (_hasLineOfSight(entity)) {
// "Halt!"
entity.state = EntityState.patrolling;
print("A guard spotted you!"); // Just for debugging
}
}
// 2. Visuals: 8-Way Directional Tracking
if (entity.state == EntityState.idle ||
entity.state == EntityState.patrolling) {
double dx = player.x - entity.x;
double dy = player.y - entity.y;
double angleToPlayer = math.atan2(dy, dx);
// Find the difference between where the guard is facing and where the player is
double diff = entity.angle - angleToPlayer;
// Wrap the angle to stay within -PI and +PI
while (diff <= -math.pi) {
diff += 2 * math.pi;
}
@@ -300,12 +308,10 @@ class _WolfRendererState extends State<WolfRenderer>
diff -= 2 * math.pi;
}
// Snap that difference to one of 8 octants (45 degrees each)
// Sprite 50 is Front, 51 is Front-Right, 52 is Right, etc.
int octant = ((diff + (math.pi / 8)) / (math.pi / 4)).floor() % 8;
if (octant < 0) octant += 8;
// Base idle sprite for the Brown Guard is 50
// Base sprite for the Brown Guard
entity.spriteIndex = 50 + octant;
}
}
@@ -349,6 +355,47 @@ class _WolfRendererState extends State<WolfRenderer>
}
}
bool _hasLineOfSight(Entity guard) {
double dx = player.x - guard.x;
double dy = player.y - guard.y;
double distance = math.sqrt(dx * dx + dy * dy);
// 1. FOV Check (Are you in front of them?)
double angleToPlayer = math.atan2(dy, dx);
double diff = guard.angle - angleToPlayer;
while (diff <= -math.pi) {
diff += 2 * math.pi;
}
while (diff > math.pi) {
diff -= 2 * math.pi;
}
// A standard guard FOV is about 180 degrees (90 degrees left/right)
if (diff.abs() > math.pi / 2) {
return false; // You are behind them!
}
// 2. Line of Sight Check (Are there walls in the way?)
double dirX = dx / distance;
double dirY = dy / distance;
// Step along the ray in small increments to check for solid blocks
double stepSize = 0.2;
for (double i = 0; i < distance; i += stepSize) {
int checkX = (guard.x + dirX * i).toInt();
int checkY = (guard.y + dirY * i).toInt();
// If we hit a solid wall or closed door, vision is blocked
if (!_isWalkable(checkX, checkY)) {
return false;
}
}
// If we made it all the way to the player without hitting a wall...
return true;
}
@override
Widget build(BuildContext context) {
if (_isLoading) {