import 'package:flame/components.dart'; import 'package:flame/events.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:shitman/game/shitman_game.dart'; import 'package:shitman/game/components/poop_bag.dart'; import 'package:shitman/game/components/neighborhood.dart'; class Player extends RectangleComponent with HasGameReference { static const double speed = 100.0; static const double playerSize = 32.0; Vector2 velocity = Vector2.zero(); bool hasPoopBag = true; bool isHidden = false; double stealthLevel = 0.0; // 0.0 = fully visible, 1.0 = completely hidden PoopBag? placedPoopBag; @override Future onLoad() async { await super.onLoad(); // Create a simple colored rectangle as player size = Vector2.all(playerSize); position = Vector2(400, 300); // Start in center // Set player color paint = Paint()..color = const Color(0xFF0000FF); // Blue player } void handleInput(Set keysPressed) { velocity = Vector2.zero(); // Movement controls if (keysPressed.contains(LogicalKeyboardKey.arrowUp) || keysPressed.contains(LogicalKeyboardKey.keyW)) { velocity.y -= speed; } if (keysPressed.contains(LogicalKeyboardKey.arrowDown) || keysPressed.contains(LogicalKeyboardKey.keyS)) { velocity.y += speed; } if (keysPressed.contains(LogicalKeyboardKey.arrowLeft) || keysPressed.contains(LogicalKeyboardKey.keyA)) { velocity.x -= speed; } if (keysPressed.contains(LogicalKeyboardKey.arrowRight) || keysPressed.contains(LogicalKeyboardKey.keyD)) { velocity.x += speed; } } void handleAction(LogicalKeyboardKey key) { // Action controls if (key == LogicalKeyboardKey.space) { placePoop(); } if (key == LogicalKeyboardKey.keyE) { ringDoorbell(); } } void updateStealthLevel(double dt) { // Simple stealth calculation - can be enhanced later // For now, player is more hidden when moving slowly or not at all if (velocity.length < 50) { stealthLevel = (stealthLevel + dt * 0.5).clamp(0.0, 1.0); } else { stealthLevel = (stealthLevel - dt * 1.5).clamp(0.0, 1.0); } isHidden = stealthLevel > 0.7; } void placePoop() { if (!hasPoopBag) return; debugPrint('Placing poop bag at $position'); // Create and place the poop bag placedPoopBag = PoopBag(); placedPoopBag!.position = position + Vector2(playerSize / 2, playerSize + 10); game.world.add(placedPoopBag!); hasPoopBag = false; // Check if near target house checkMissionProgress(); } void ringDoorbell() { debugPrint('Attempting to ring doorbell'); // Check if near target house door if (game.targetHouse.isPlayerNearTarget(position)) { if (placedPoopBag != null) { // Light the poop bag on fire placedPoopBag!.lightOnFire(); debugPrint('Ding dong! Poop bag is lit! RUN!'); // Start escape timer - player has limited time to escape startEscapeSequence(); } else { debugPrint('Need to place poop bag first!'); } } else { debugPrint('Not near target house door'); } } void startEscapeSequence() { // TODO: Implement escape mechanics // For now, automatically complete mission after a delay Future.delayed(Duration(seconds: 3), () { if (game.gameState == GameState.playing) { game.completeCurrentMission(); } }); } void checkMissionProgress() { // Check if near target house and has placed poop bag final targetPos = game.targetHouse.getTargetPosition(); if (targetPos != null && placedPoopBag != null) { final distance = (position - targetPos).length; if (distance < 80) { debugPrint('Near target house with poop bag placed!'); } } } void getDetected() { debugPrint('Player detected! Mission failed!'); game.failMission(); } @override void update(double dt) { super.update(dt); // Apply movement if (velocity.length > 0) { velocity = velocity.normalized() * speed; position += velocity * dt; // Keep player on screen (basic bounds checking) position.x = position.x.clamp(0, 800 - size.x); position.y = position.y.clamp(0, 600 - size.y); } // Update stealth level based on environment updateStealthLevel(dt); // Check for detection by houses checkForDetection(); } void checkForDetection() { final neighborhood = game.world.children.whereType().firstOrNull; if (neighborhood == null) return; for (final house in neighborhood.houses) { if (house.canDetectPlayer(position, stealthLevel)) { getDetected(); break; } } } @override void render(Canvas canvas) { // Update paint color based on stealth level paint = Paint() ..color = isHidden ? const Color(0xFF00FF00).withOpacity(0.7) : // Green when hidden const Color(0xFF0000FF).withOpacity(0.9); // Blue when visible super.render(canvas); // Draw stealth indicator in debug mode if (game.debugMode) { final stealthPaint = Paint() ..color = Color.lerp(const Color(0xFFFF0000), const Color(0xFF00FF00), stealthLevel)!; canvas.drawRect( Rect.fromLTWH(-5, -10, size.x + 10, 5), stealthPaint, ); } } }