@@ -192,49 +192,16 @@ class _WolfRendererState extends State<WolfRenderer>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _tick(Duration elapsed) {
|
void _tick(Duration elapsed) {
|
||||||
// * Process all inputs, first.
|
// 1. Process all hardware inputs and player intentions
|
||||||
inputManager.update();
|
_processInputs(elapsed);
|
||||||
|
|
||||||
const double moveSpeed = 0.12;
|
// 2. Animate weapon lowering/raising
|
||||||
const double turnSpeed = 0.08;
|
|
||||||
|
|
||||||
// Reset steps each tick before calculation
|
|
||||||
moveStepX = 0;
|
|
||||||
moveStepY = 0;
|
|
||||||
|
|
||||||
// Handle Manual Weapon Switching
|
|
||||||
if (inputManager.requestedWeapon != null) {
|
|
||||||
player.requestWeaponSwitch(inputManager.requestedWeapon!);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle Movement using InputManager
|
|
||||||
if (inputManager.isMovingForward) {
|
|
||||||
moveStepX += math.cos(player.angle) * moveSpeed;
|
|
||||||
moveStepY += math.sin(player.angle) * moveSpeed;
|
|
||||||
}
|
|
||||||
if (inputManager.isMovingBackward) {
|
|
||||||
moveStepX -= math.cos(player.angle) * moveSpeed;
|
|
||||||
moveStepY -= math.sin(player.angle) * moveSpeed;
|
|
||||||
}
|
|
||||||
if (inputManager.isTurningLeft) {
|
|
||||||
player.angle -= turnSpeed;
|
|
||||||
}
|
|
||||||
if (inputManager.isTurningRight) {
|
|
||||||
player.angle += turnSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep angle wrapped cleanly
|
|
||||||
if (player.angle < 0) player.angle += 2 * math.pi;
|
|
||||||
if (player.angle > 2 * math.pi) player.angle -= 2 * math.pi;
|
|
||||||
|
|
||||||
// UPDATE WEAPON ANIMATION (Lowering/Raising)
|
|
||||||
player.updateWeaponSwitch();
|
player.updateWeaponSwitch();
|
||||||
|
|
||||||
// 1. ANIMATE DOORS
|
// 3. Animate doors sliding
|
||||||
doorStates.forEach((key, state) {
|
doorStates.forEach((key, state) {
|
||||||
if (state == 1) {
|
if (state == 1) {
|
||||||
// If opening
|
doorOffsets[key] = (doorOffsets[key] ?? 0.0) + 0.02;
|
||||||
doorOffsets[key] = (doorOffsets[key] ?? 0.0) + 0.02; // Slide speed
|
|
||||||
if (doorOffsets[key]! >= 1.0) {
|
if (doorOffsets[key]! >= 1.0) {
|
||||||
doorOffsets[key] = 1.0;
|
doorOffsets[key] = 1.0;
|
||||||
doorStates[key] = 2; // Mark as fully open
|
doorStates[key] = 2; // Mark as fully open
|
||||||
@@ -242,13 +209,13 @@ class _WolfRendererState extends State<WolfRenderer>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. UPDATED WALL COLLISION
|
// 4. Process Wall Collision for Movement
|
||||||
const double margin = 0.3;
|
const double margin = 0.3;
|
||||||
|
|
||||||
double newX = player.x + moveStepX;
|
double newX = player.x + moveStepX;
|
||||||
int checkX = (moveStepX > 0)
|
int checkX = (moveStepX > 0)
|
||||||
? (newX + margin).toInt()
|
? (newX + margin).toInt()
|
||||||
: (newX - margin).toInt();
|
: (newX - margin).toInt();
|
||||||
|
|
||||||
if (_isWalkable(checkX, player.y.toInt())) {
|
if (_isWalkable(checkX, player.y.toInt())) {
|
||||||
player.x = newX;
|
player.x = newX;
|
||||||
}
|
}
|
||||||
@@ -257,32 +224,12 @@ class _WolfRendererState extends State<WolfRenderer>
|
|||||||
int checkY = (moveStepY > 0)
|
int checkY = (moveStepY > 0)
|
||||||
? (newY + margin).toInt()
|
? (newY + margin).toInt()
|
||||||
: (newY - margin).toInt();
|
: (newY - margin).toInt();
|
||||||
|
|
||||||
if (_isWalkable(player.x.toInt(), checkY)) {
|
if (_isWalkable(player.x.toInt(), checkY)) {
|
||||||
player.y = newY;
|
player.y = newY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. UPDATED DOOR INTERACTION (Using InputManager)
|
// 5. Update Entity Logic
|
||||||
if (inputManager.isInteracting) {
|
List<Entity> itemsToRemove = [];
|
||||||
int targetX = (player.x + math.cos(player.angle)).toInt();
|
|
||||||
int targetY = (player.y + math.sin(player.angle)).toInt();
|
|
||||||
|
|
||||||
if (targetY > 0 &&
|
|
||||||
targetY < currentLevel.length &&
|
|
||||||
targetX > 0 &&
|
|
||||||
targetX < currentLevel[0].length) {
|
|
||||||
if (currentLevel[targetY][targetX] >= 90) {
|
|
||||||
String key = '$targetX,$targetY';
|
|
||||||
// Start the animation if it isn't already opening!
|
|
||||||
if (!doorStates.containsKey(key) || doorStates[key] == 0) {
|
|
||||||
doorStates[key] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 4. UPDATE ENTITY LOGIC ---
|
|
||||||
List<Entity> itemsToRemove = []; // Collect items to delete after the loop
|
|
||||||
|
|
||||||
for (Entity entity in entities) {
|
for (Entity entity in entities) {
|
||||||
if (entity is Enemy) {
|
if (entity is Enemy) {
|
||||||
@@ -292,42 +239,25 @@ class _WolfRendererState extends State<WolfRenderer>
|
|||||||
isWalkable: _isWalkable,
|
isWalkable: _isWalkable,
|
||||||
onDamagePlayer: _takeDamage,
|
onDamagePlayer: _takeDamage,
|
||||||
);
|
);
|
||||||
}
|
} else if (entity is Collectible) {
|
||||||
// Collectible Interaction Logic
|
|
||||||
else if (entity is Collectible) {
|
|
||||||
double dx = player.x - entity.x;
|
double dx = player.x - entity.x;
|
||||||
double dy = player.y - entity.y;
|
double dy = player.y - entity.y;
|
||||||
double dist = math.sqrt(dx * dx + dy * dy);
|
if (math.sqrt(dx * dx + dy * dy) < 0.5) {
|
||||||
|
if (player.tryPickup(entity)) itemsToRemove.add(entity);
|
||||||
// If player is close enough to the item
|
|
||||||
if (dist < 0.5) {
|
|
||||||
if (player.tryPickup(entity)) {
|
|
||||||
itemsToRemove.add(entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the items that were successfully picked up
|
|
||||||
if (itemsToRemove.isNotEmpty) {
|
if (itemsToRemove.isNotEmpty) {
|
||||||
setState(() {
|
entities.removeWhere((e) => itemsToRemove.contains(e));
|
||||||
entities.removeWhere((e) => itemsToRemove.contains(e));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Weapon Raycast & Firing
|
// 6. Weapon Raycast & Attacking
|
||||||
bool shouldCheckHit = player.updateWeapon(elapsed.inMilliseconds);
|
if (player.updateWeapon(elapsed.inMilliseconds)) {
|
||||||
|
|
||||||
if (shouldCheckHit) {
|
|
||||||
_performRaycastAttack(elapsed);
|
_performRaycastAttack(elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input to trigger firing (Using InputManager)
|
// 7. Screen Effects
|
||||||
if (inputManager.isFiring) {
|
|
||||||
player.fire(elapsed.inMilliseconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fade out the damage flash smoothly
|
|
||||||
if (damageFlashOpacity > 0) {
|
if (damageFlashOpacity > 0) {
|
||||||
damageFlashOpacity = math.max(0.0, damageFlashOpacity - 0.05);
|
damageFlashOpacity = math.max(0.0, damageFlashOpacity - 0.05);
|
||||||
}
|
}
|
||||||
@@ -403,6 +333,64 @@ class _WolfRendererState extends State<WolfRenderer>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _processInputs(Duration elapsed) {
|
||||||
|
inputManager.update();
|
||||||
|
|
||||||
|
const double moveSpeed = 0.16;
|
||||||
|
const double turnSpeed = 0.12;
|
||||||
|
|
||||||
|
// Reset steps each tick
|
||||||
|
moveStepX = 0;
|
||||||
|
moveStepY = 0;
|
||||||
|
|
||||||
|
// 1. Weapon Switching
|
||||||
|
if (inputManager.requestedWeapon != null) {
|
||||||
|
player.requestWeaponSwitch(inputManager.requestedWeapon!);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Firing
|
||||||
|
if (inputManager.isFiring) {
|
||||||
|
player.fire(elapsed.inMilliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Movement
|
||||||
|
if (inputManager.isMovingForward) {
|
||||||
|
moveStepX += math.cos(player.angle) * moveSpeed;
|
||||||
|
moveStepY += math.sin(player.angle) * moveSpeed;
|
||||||
|
}
|
||||||
|
if (inputManager.isMovingBackward) {
|
||||||
|
moveStepX -= math.cos(player.angle) * moveSpeed;
|
||||||
|
moveStepY -= math.sin(player.angle) * moveSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Turning
|
||||||
|
if (inputManager.isTurningLeft) player.angle -= turnSpeed;
|
||||||
|
if (inputManager.isTurningRight) player.angle += turnSpeed;
|
||||||
|
|
||||||
|
// Keep angle wrapped cleanly
|
||||||
|
if (player.angle < 0) player.angle += 2 * math.pi;
|
||||||
|
if (player.angle > 2 * math.pi) player.angle -= 2 * math.pi;
|
||||||
|
|
||||||
|
// 5. Interaction (Doors)
|
||||||
|
if (inputManager.isInteracting) {
|
||||||
|
int targetX = (player.x + math.cos(player.angle)).toInt();
|
||||||
|
int targetY = (player.y + math.sin(player.angle)).toInt();
|
||||||
|
|
||||||
|
if (targetY > 0 &&
|
||||||
|
targetY < currentLevel.length &&
|
||||||
|
targetX > 0 &&
|
||||||
|
targetX < currentLevel[0].length) {
|
||||||
|
if (currentLevel[targetY][targetX] >= 90) {
|
||||||
|
String key = '$targetX,$targetY';
|
||||||
|
// Start the animation if it isn't already opening!
|
||||||
|
if (!doorStates.containsKey(key) || doorStates[key] == 0) {
|
||||||
|
doorStates[key] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (_isLoading) {
|
if (_isLoading) {
|
||||||
|
|||||||
Reference in New Issue
Block a user