shitman/lib/game/components/player.dart
zeyus bc128cef3d
Some checks are pending
/ build-web (push) Waiting to run
just a concept.
2025-07-21 22:52:31 +02:00

193 lines
No EOL
5.5 KiB
Dart

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<ShitmanGame> {
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<void> 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<LogicalKeyboardKey> 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<Neighborhood>().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,
);
}
}
}