import 'dart:math' as math; import 'package:wolf_dart/classes/coordinate_2d.dart'; import 'package:wolf_dart/features/entities/enemies/enemy.dart'; import 'package:wolf_dart/features/entities/entity.dart'; class Dog extends Enemy { static const double speed = 0.05; bool _hasBittenThisCycle = false; static EnemyType get type => EnemyType.dog; Dog({ required super.x, required super.y, required super.angle, required super.mapId, }) : super( spriteIndex: type.spriteBaseIdx, state: EntityState.idle, ) { health = 1; damage = 5; } @override ({Coordinate2D movement, double newAngle}) update({ required int elapsedMs, required Coordinate2D playerPosition, required bool Function(int x, int y) isWalkable, required void Function(int damage) onDamagePlayer, required void Function(int x, int y) tryOpenDoor, }) { Coordinate2D movement = const Coordinate2D(0, 0); double newAngle = angle; checkWakeUp( elapsedMs: elapsedMs, playerPosition: playerPosition, isWalkable: isWalkable, ); double distance = position.distanceTo(playerPosition); double angleToPlayer = position.angleTo(playerPosition); if (state != EntityState.idle && state != EntityState.dead) { newAngle = angleToPlayer; } double diff = angleToPlayer - newAngle; while (diff <= -math.pi) { diff += 2 * math.pi; } while (diff > math.pi) { diff -= 2 * math.pi; } EnemyAnimation currentAnim = switch (state) { EntityState.patrolling => EnemyAnimation.walking, EntityState.attacking => EnemyAnimation.attacking, EntityState.dead => isDying ? EnemyAnimation.dying : EnemyAnimation.dead, _ => EnemyAnimation.idle, }; spriteIndex = type.getSpriteFromAnimation( animation: currentAnim, elapsedMs: elapsedMs, lastActionTime: lastActionTime, angleDiff: diff, ); if (state == EntityState.patrolling && distance < 1.0) { state = EntityState.attacking; lastActionTime = elapsedMs; _hasBittenThisCycle = false; } if (state == EntityState.attacking) { int time = elapsedMs - lastActionTime; if (time >= 200 && !_hasBittenThisCycle) { onDamagePlayer(damage); _hasBittenThisCycle = true; } else if (time >= 400) { state = EntityState.patrolling; lastActionTime = elapsedMs; } } return (movement: movement, newAngle: newAngle); } }