@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user