Added colors and textures

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-13 16:46:20 +01:00
parent 8ecc8e2fd4
commit 464a22e1f3
8 changed files with 388 additions and 66 deletions

View File

@@ -3,15 +3,18 @@ import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:wolf_dart/classes/linear_coordinates.dart';
import 'package:wolf_dart/classes/matrix.dart';
import 'package:wolf_dart/features/renderer/color_palette.dart';
class RaycasterPainter extends CustomPainter {
final Matrix<int> map;
final List<Matrix<int>> textures;
final LinearCoordinates player;
final double playerAngle;
final double fov;
RaycasterPainter({
required this.map,
required this.textures,
required this.player,
required this.playerAngle,
required this.fov,
@@ -139,6 +142,7 @@ class RaycasterPainter extends CustomPainter {
side,
size,
hitWallId,
textures,
);
}
}
@@ -151,77 +155,47 @@ class RaycasterPainter extends CustomPainter {
int side,
Size size,
int hitWallId,
List<Matrix<int>> textures,
) {
if (distance <= 0.01) distance = 0.01;
double wallHeight = size.height / distance;
double drawStart = (size.height / 2) - (wallHeight / 2);
double drawEnd = (size.height / 2) + (wallHeight / 2);
int drawStart = ((size.height / 2) - (wallHeight / 2)).toInt();
// --- PROCEDURAL TEXTURE LOGIC ---
Color baseColor;
// 1. PERFECT 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);
if (side == 1) texNum += 1; // Instantly use the native dark texture!
// Draw a dark edge on the sides of the block to create "tiles"
if (wallX < 0.05 || wallX > 0.95) {
baseColor = Colors.black87;
} else {
switch (hitWallId) {
case 1:
case 2:
case 3:
baseColor = Colors.grey[600]!; // Standard Grey Stone
break;
case 7:
case 8:
case 19:
baseColor = Colors.brown[600]!; // Wood Paneling
break;
case 9:
case 10:
baseColor = Colors.indigo[800]!; // Blue Stone
break;
case 17:
baseColor = Colors.red[900]!; // Red Brick
break;
case 41:
case 42:
baseColor = Colors.blueGrey; // Elevator walls
break;
default:
baseColor = Colors.teal; // Fallback for unknown IDs
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;
double startY = drawStart.toDouble();
double stepY = wallHeight / 64.0;
for (int ty = 0; ty < 64; ty++) {
int colorByte = textures[texNum][texX][ty];
// 2. NO MORE SHADOW MATH
// Because we selected the correct dark texture above, we just draw the raw color!
Color pixelColor = ColorPalette.vga[colorByte];
double endY = startY + stepY;
if (endY > 0 && startY < size.height) {
canvas.drawLine(
Offset(x.toDouble(), startY),
Offset(x.toDouble(), endY),
Paint()
..color = pixelColor
..strokeWidth = 1.1,
);
}
startY += stepY;
}
// Faux-Lighting: Darken East/West walls to give a 3D pop to corners
if (side == 1) {
baseColor = Color.fromARGB(
255,
((baseColor.r * 255).round().clamp(0, 255) * 0.7).toInt(),
((baseColor.g * 255).round().clamp(0, 255) * 0.7).toInt(),
((baseColor.b * 255).round().clamp(0, 255) * 0.7).toInt(),
);
}
// Depth cueing: Dim colors as they get further away
double dimFactor = (1.0 - (distance / 15)).clamp(0.0, 1.0);
Color finalColor = Color.fromARGB(
255,
((baseColor.r * 255).round().clamp(0, 255) * dimFactor).toInt(),
((baseColor.g * 255).round().clamp(0, 255) * dimFactor).toInt(),
((baseColor.b * 255).round().clamp(0, 255) * dimFactor).toInt(),
);
final paint = Paint()
..color = finalColor
..strokeWidth =
1.1 // Prevent transparent gaps between line strokes
..style = PaintingStyle.stroke;
canvas.drawLine(
Offset(x.toDouble(), drawStart),
Offset(x.toDouble(), drawEnd),
paint,
);
}
@override