@@ -11,6 +11,7 @@ class RaycasterPainter extends CustomPainter {
|
||||
final LinearCoordinates player;
|
||||
final double playerAngle;
|
||||
final double fov;
|
||||
final Map<String, double> doorOffsets;
|
||||
|
||||
RaycasterPainter({
|
||||
required this.map,
|
||||
@@ -18,6 +19,7 @@ class RaycasterPainter extends CustomPainter {
|
||||
required this.player,
|
||||
required this.playerAngle,
|
||||
required this.fov,
|
||||
required this.doorOffsets,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -61,6 +63,11 @@ class RaycasterPainter extends CustomPainter {
|
||||
bool hitOutOfBounds = false;
|
||||
int side = 0;
|
||||
int hitWallId = 0;
|
||||
double doorOffset =
|
||||
0.0; // Track the slide amount to pass to the texture drawer
|
||||
|
||||
Set<String> ignoredDoors =
|
||||
{}; // Prevent the ray from checking the same door gap twice
|
||||
|
||||
if (rayDirX < 0) {
|
||||
stepX = -1;
|
||||
@@ -94,8 +101,33 @@ class RaycasterPainter extends CustomPainter {
|
||||
mapX < 0 ||
|
||||
mapX >= map[0].length) {
|
||||
hit = true;
|
||||
hitOutOfBounds = true; // Safely abort if we clip out of bounds
|
||||
hitOutOfBounds = true;
|
||||
} else if (map[mapY][mapX] > 0) {
|
||||
// NEW: DOOR PASS-THROUGH LOGIC
|
||||
String doorKey = '$mapX,$mapY';
|
||||
if (map[mapY][mapX] >= 90 && !ignoredDoors.contains(doorKey)) {
|
||||
double currentOffset = doorOffsets[doorKey] ?? 0.0;
|
||||
|
||||
if (currentOffset > 0.0) {
|
||||
// Calculate exactly where the ray hit the block
|
||||
double perpWallDistTemp = (side == 0)
|
||||
? (sideDistX - deltaDistX)
|
||||
: (sideDistY - deltaDistY);
|
||||
double wallXTemp = (side == 0)
|
||||
? player.y + perpWallDistTemp * rayDirY
|
||||
: player.x + perpWallDistTemp * rayDirX;
|
||||
wallXTemp -= wallXTemp.floor();
|
||||
|
||||
// If the hit coordinate is less than the open amount, the ray passes through!
|
||||
if (wallXTemp < currentOffset) {
|
||||
ignoredDoors.add(doorKey);
|
||||
continue; // Skip the rest of this loop iteration and keep raycasting!
|
||||
}
|
||||
}
|
||||
doorOffset =
|
||||
currentOffset; // Save the offset so we can slide the texture
|
||||
}
|
||||
|
||||
hit = true;
|
||||
hitWallId = map[mapY][mapX];
|
||||
}
|
||||
@@ -127,6 +159,7 @@ class RaycasterPainter extends CustomPainter {
|
||||
size,
|
||||
hitWallId,
|
||||
textures,
|
||||
doorOffset,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -140,28 +173,29 @@ class RaycasterPainter extends CustomPainter {
|
||||
Size size,
|
||||
int hitWallId,
|
||||
List<Matrix<int>> textures,
|
||||
double doorOffset,
|
||||
) {
|
||||
if (distance <= 0.01) distance = 0.01;
|
||||
|
||||
double wallHeight = size.height / distance;
|
||||
int drawStart = ((size.height / 2) - (wallHeight / 2)).toInt();
|
||||
|
||||
// 1. PERFECT TEXTURE MAPPING
|
||||
// TEXTURE MAPPING
|
||||
// Wolf3D stores textures in pairs. Even = N/S (Light), Odd = E/W (Dark).
|
||||
int texNum = ((hitWallId - 1) * 2).clamp(0, textures.length - 2);
|
||||
int texX = (wallX * 64).toInt().clamp(0, 63);
|
||||
|
||||
// INTERCEPT DOORS
|
||||
if (hitWallId >= 90) {
|
||||
// Safely clamp the door texture index so it never crashes the paint loop!
|
||||
texNum = 98.clamp(0, textures.length - 1);
|
||||
texX = ((wallX - doorOffset) * 64).toInt().clamp(0, 63);
|
||||
} else {
|
||||
// Standard wall texture pairing
|
||||
texNum = ((hitWallId - 1) * 2).clamp(0, textures.length - 2);
|
||||
if (side == 1) texNum += 1;
|
||||
}
|
||||
|
||||
int texX = (wallX * 64).toInt().clamp(0, 63);
|
||||
|
||||
if (side == 0 && math.cos(playerAngle) > 0) texX = 63 - texX;
|
||||
if (side == 1 && math.sin(playerAngle) < 0) texX = 63 - texX;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user