Slide doors open

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-13 17:24:35 +01:00
parent de643b7cdc
commit 630f027b68
2 changed files with 78 additions and 21 deletions

View File

@@ -30,6 +30,11 @@ class _WolfRendererState extends State<WolfRenderer>
bool _isLoading = true;
bool _spaceWasPressed = false;
// Track door animations
// Key is "X,Y" coordinate. Value is how far open it is (0.0 to 1.0)
Map<String, double> doorOffsets = {};
Map<String, int> doorStates = {}; // 1 = opening, 2 = fully open
@override
void initState() {
super.initState();
@@ -131,16 +136,38 @@ class _WolfRendererState extends State<WolfRenderer>
}
}
bool _isWalkable(int x, int y) {
if (currentLevel[y][x] == 0) return true; // Empty space
if (currentLevel[y][x] >= 90) {
String key = '$x,$y';
// Allow the player to walk through if the door is > 70% open
if (doorOffsets[key] != null && doorOffsets[key]! > 0.7) {
return true;
}
}
return false;
}
void _tick(Duration elapsed) {
const double moveSpeed = 0.12;
const double turnSpeed = 0.08;
// 1. ANIMATE DOORS
doorStates.forEach((key, state) {
if (state == 1) {
// If opening
doorOffsets[key] = (doorOffsets[key] ?? 0.0) + 0.02; // Slide speed
if (doorOffsets[key]! >= 1.0) {
doorOffsets[key] = 1.0;
doorStates[key] = 2; // Mark as fully open
}
}
});
double moveStepX = 0;
double moveStepY = 0;
final pressedKeys = HardwareKeyboard.instance.logicalKeysPressed;
// 1. Calculate intended movement amounts
if (pressedKeys.contains(LogicalKeyboardKey.keyW)) {
moveStepX += math.cos(playerAngle) * moveSpeed;
moveStepY += math.sin(playerAngle) * moveSpeed;
@@ -149,8 +176,6 @@ class _WolfRendererState extends State<WolfRenderer>
moveStepX -= math.cos(playerAngle) * moveSpeed;
moveStepY -= math.sin(playerAngle) * moveSpeed;
}
// 2. Handle Turning
if (pressedKeys.contains(LogicalKeyboardKey.keyA)) {
playerAngle -= turnSpeed;
}
@@ -160,18 +185,14 @@ class _WolfRendererState extends State<WolfRenderer>
if (playerAngle < 0) playerAngle += 2 * math.pi;
if (playerAngle > 2 * math.pi) playerAngle -= 2 * math.pi;
// 3. Wall Sliding Collision (with Hitbox Margin!)
// A 0.3 margin keeps the camera plane safely out of the walls
// 2. UPDATED WALL COLLISION
const double margin = 0.3;
double newX = player.x + moveStepX;
// Check the edge of our hitbox, not just the center point
int checkX = (moveStepX > 0)
? (newX + margin).toInt()
: (newX - margin).toInt();
// Try to move along the X axis
if (currentLevel[player.y.toInt()][checkX] == 0) {
if (_isWalkable(checkX, player.y.toInt())) {
player = (x: newX, y: player.y);
}
@@ -180,12 +201,11 @@ class _WolfRendererState extends State<WolfRenderer>
? (newY + margin).toInt()
: (newY - margin).toInt();
// Try to move along the Y axis
if (currentLevel[checkY][player.x.toInt()] == 0) {
if (_isWalkable(player.x.toInt(), checkY)) {
player = (x: player.x, y: newY);
}
// 4. DOOR INTERACTION LOGIC
// 3. UPDATED DOOR INTERACTION
bool isSpacePressed = pressedKeys.contains(LogicalKeyboardKey.space);
if (isSpacePressed && !_spaceWasPressed) {
@@ -196,10 +216,12 @@ class _WolfRendererState extends State<WolfRenderer>
targetY < currentLevel.length &&
targetX > 0 &&
targetX < currentLevel[0].length) {
int targetBlock = currentLevel[targetY][targetX];
if (targetBlock >= 90) {
currentLevel[targetY][targetX] = 0;
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;
}
}
}
}
@@ -230,6 +252,7 @@ class _WolfRendererState extends State<WolfRenderer>
player: player,
playerAngle: playerAngle,
fov: fov,
doorOffsets: doorOffsets,
),
);
},