diff --git a/lib/features/renderer/renderer.dart b/lib/features/renderer/renderer.dart index 613c8e2..03eadcd 100644 --- a/lib/features/renderer/renderer.dart +++ b/lib/features/renderer/renderer.dart @@ -282,25 +282,31 @@ class _WolfRendererState extends State _spaceWasPressed = isSpacePressed; // --- 4. UPDATE ENTITY LOGIC --- + const double enemySpeed = 0.03; // Slightly slower than the player + for (Entity entity in entities) { // 1. Wake up if the player is spotted! if (entity.state == EntityState.idle) { if (_hasLineOfSight(entity)) { - // "Halt!" entity.state = EntityState.patrolling; - print("A guard spotted you!"); // Just for debugging } } - // 2. Visuals: 8-Way Directional Tracking + // 2. State-based Logic & Animation if (entity.state == EntityState.idle || entity.state == EntityState.patrolling) { double dx = player.x - entity.x; double dy = player.y - entity.y; + double distance = math.sqrt(dx * dx + dy * dy); double angleToPlayer = math.atan2(dy, dx); - double diff = entity.angle - angleToPlayer; + // If patrolling, force the guard to turn and face the player + if (entity.state == EntityState.patrolling) { + entity.angle = angleToPlayer; + } + // Calculate the octant for the 8-directional sprites + double diff = entity.angle - angleToPlayer; while (diff <= -math.pi) { diff += 2 * math.pi; } @@ -311,8 +317,31 @@ class _WolfRendererState extends State int octant = ((diff + (math.pi / 8)) / (math.pi / 4)).floor() % 8; if (octant < 0) octant += 8; - // Base sprite for the Brown Guard - entity.spriteIndex = 50 + octant; + if (entity.state == EntityState.idle) { + // Standing still + entity.spriteIndex = 50 + octant; + } else if (entity.state == EntityState.patrolling) { + // A. Move towards the player (stop if they get too close) + if (distance > 0.8) { + double moveX = entity.x + math.cos(entity.angle) * enemySpeed; + double moveY = entity.y + math.sin(entity.angle) * enemySpeed; + + // Basic collision so they slide along walls instead of phasing through + if (_isWalkable(moveX.toInt(), entity.y.toInt())) { + entity.x = moveX; + } + if (_isWalkable(entity.x.toInt(), moveY.toInt())) { + entity.y = moveY; + } + } + + // B. Animate the walk cycle (4 steps) + // We use the elapsed time to change the frame every 150ms + int walkFrame = (elapsed.inMilliseconds ~/ 150) % 4; + + // Frames start at 58. Each of the 4 walk steps has 8 directional sprites. + entity.spriteIndex = 58 + (walkFrame * 8) + octant; + } } }