Refactor rendering architecture and replace rasterizer with renderer
- Introduced SoftwareRenderer as a pixel-accurate software rendering backend. - Removed the obsolete wolf_3d_rasterizer.dart file. - Created a new wolf_3d_renderer.dart file to centralize rendering exports. - Updated tests to accommodate the new rendering structure, including pushwall and projection sampling tests. - Modified the WolfAsciiRenderer and WolfFlutterRenderer to utilize the new SoftwareRenderer. - Enhanced enemy spawn tests to include new enemy states. Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -9,13 +9,15 @@ import 'package:wolf_3d_dart/wolf_3d_entities.dart';
|
||||
/// door's state changes (e.g., starts closing), the appropriate global
|
||||
/// game events (like sound effects) are triggered.
|
||||
class DoorManager {
|
||||
/// A lookup table for doors, keyed by their grid coordinates: "$x,$y".
|
||||
final Map<String, Door> doors = {};
|
||||
/// A lookup table for doors, keyed by packed grid coordinates.
|
||||
final Map<int, Door> doors = {};
|
||||
|
||||
/// Callback used to trigger sound effects without tight coupling
|
||||
/// to a specific audio engine implementation.
|
||||
final void Function(int sfxId) onPlaySound;
|
||||
|
||||
static int _key(int x, int y) => ((y & 0xFFFF) << 16) | (x & 0xFFFF);
|
||||
|
||||
DoorManager({required this.onPlaySound});
|
||||
|
||||
/// Scans the [wallGrid] for tile IDs >= 90 and initializes [Door] instances.
|
||||
@@ -25,7 +27,7 @@ class DoorManager {
|
||||
for (int x = 0; x < wallGrid[y].length; x++) {
|
||||
int id = wallGrid[y][x];
|
||||
if (id >= 90) {
|
||||
doors['$x,$y'] = Door(x: x, y: y, mapId: id);
|
||||
doors[_key(x, y)] = Door(x: x, y: y, mapId: id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +50,7 @@ class DoorManager {
|
||||
int targetX = (playerX + math.cos(playerAngle)).toInt();
|
||||
int targetY = (playerY + math.sin(playerAngle)).toInt();
|
||||
|
||||
String key = '$targetX,$targetY';
|
||||
final int key = _key(targetX, targetY);
|
||||
if (doors.containsKey(key)) {
|
||||
if (doors[key]!.interact()) {
|
||||
onPlaySound(WolfSound.openDoor);
|
||||
@@ -58,7 +60,7 @@ class DoorManager {
|
||||
|
||||
/// Attempted by AI entities to open a door blocking their path.
|
||||
void tryOpenDoor(int x, int y) {
|
||||
String key = '$x,$y';
|
||||
final int key = _key(x, y);
|
||||
// AI only interacts if the door is currently fully closed (offset == 0).
|
||||
if (doors.containsKey(key) && doors[key]!.offset == 0.0) {
|
||||
if (doors[key]!.interact()) {
|
||||
@@ -67,21 +69,16 @@ class DoorManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method for the raycaster
|
||||
Map<String, double> getOffsetsForRenderer() {
|
||||
Map<String, double> offsets = {};
|
||||
for (var entry in doors.entries) {
|
||||
if (entry.value.offset > 0.0) {
|
||||
offsets[entry.key] = entry.value.offset;
|
||||
}
|
||||
}
|
||||
return offsets;
|
||||
/// Returns the current open offset for the door at [x],[y].
|
||||
/// Returns 0.0 when there is no active/opening door at that tile.
|
||||
double doorOffsetAt(int x, int y) {
|
||||
return doors[_key(x, y)]?.offset ?? 0.0;
|
||||
}
|
||||
|
||||
/// Returns true if the door at [x], [y] is sufficiently open for
|
||||
/// an entity (player or enemy) to walk through.
|
||||
bool isDoorOpenEnough(int x, int y) {
|
||||
String key = '$x,$y';
|
||||
final int key = _key(x, y);
|
||||
if (doors.containsKey(key)) {
|
||||
// 0.7 (70% open) is the standard collision threshold.
|
||||
return doors[key]!.offset > 0.7;
|
||||
|
||||
Reference in New Issue
Block a user