diff --git a/lib/features/difficulty/difficulty_screen.dart b/lib/features/difficulty/difficulty_screen.dart index 3add573..9377de7 100644 --- a/lib/features/difficulty/difficulty_screen.dart +++ b/lib/features/difficulty/difficulty_screen.dart @@ -9,6 +9,21 @@ class DifficultyScreen extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, + floatingActionButton: FloatingActionButton( + backgroundColor: Colors.red[900], + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const WolfRenderer( + difficulty: Difficulty.bringEmOn, + // isDemo: true, + showSpriteGallery: true, + ), + ), + ); + }, + child: const Icon(Icons.bug_report, color: Colors.white), + ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/features/renderer/renderer.dart b/lib/features/renderer/renderer.dart index c343127..e5633ee 100644 --- a/lib/features/renderer/renderer.dart +++ b/lib/features/renderer/renderer.dart @@ -118,8 +118,9 @@ class _WolfRendererState extends State Entity( x: x + 0.5, y: y + 0.5, - spriteIndex: 50, // Front-facing Brown Guard + spriteIndex: 50, // Will be overridden dynamically in tick! state: EntityState.idle, + angle: _getGuardAngle(objId), // NEW! mapId: objId, ), ); @@ -280,6 +281,35 @@ class _WolfRendererState extends State } _spaceWasPressed = isSpacePressed; + // --- 4. UPDATE ENTITY SPRITES (8-WAY DIRECTIONAL) --- + for (Entity entity in entities) { + if (entity.state == EntityState.idle) { + // Find angle from the guard TO the player + 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; + } + while (diff > math.pi) { + 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 + entity.spriteIndex = 50 + octant; + } + } + setState(() {}); } @@ -298,6 +328,27 @@ class _WolfRendererState extends State } } + // Decodes the Map ID to figure out which way the guard is facing + double _getGuardAngle(int objId) { + // Normalizes the ID across the 4 difficulty tiers + int normalizedId = (objId - 108) % 36; + int direction = normalizedId % 4; // 0=East, 1=North, 2=West, 3=South + + // Matches the player spawn angles you already set up + switch (direction) { + case 0: + return 0.0; // East + case 1: + return 3 * math.pi / 2; // North + case 2: + return math.pi; // West + case 3: + return math.pi / 2; // South + default: + return 0.0; + } + } + @override Widget build(BuildContext context) { if (_isLoading) { diff --git a/lib/sprite_gallery.dart b/lib/sprite_gallery.dart index 903c164..3b3631a 100644 --- a/lib/sprite_gallery.dart +++ b/lib/sprite_gallery.dart @@ -10,7 +10,10 @@ class SpriteGallery extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: const Text("VSWAP Sprite Gallery")), + appBar: AppBar( + title: const Text("VSWAP Sprite Gallery"), + automaticallyImplyLeading: true, + ), backgroundColor: Colors.black, body: GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(