feat: Enhance rendering with pushwall and enemy color support in ASCII, Sixel, and Software renderers
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import 'package:wolf_3d_dart/src/menu/menu_manager.dart';
|
||||
import 'package:wolf_3d_dart/src/rendering/fizzle_fade.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_entities.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_menu.dart';
|
||||
|
||||
import 'cli_renderer_backend.dart';
|
||||
@@ -416,8 +417,10 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
|
||||
final int floorColor = ColorPalette.vga32Bit[8];
|
||||
final int wallColor = ColorPalette.vga32Bit[7];
|
||||
final int doorColor = ColorPalette.vga32Bit[14];
|
||||
final int pushwallColor = ColorPalette.vga32Bit[6];
|
||||
final int enemyColor = ColorPalette.vga32Bit[12];
|
||||
final int playerColor = ColorPalette.vga32Bit[10];
|
||||
final int facingColor = ColorPalette.vga32Bit[12];
|
||||
final int facingColor = ColorPalette.vga32Bit[15];
|
||||
|
||||
if (_usesTerminalLayout) {
|
||||
_fillTerminalRect(
|
||||
@@ -460,9 +463,14 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
|
||||
for (int y = 0; y < 64; y++) {
|
||||
for (int x = 0; x < 64; x++) {
|
||||
final int tileId = engine.currentLevel[y][x];
|
||||
final int color = tileId == 0
|
||||
? floorColor
|
||||
: (tileId >= 90 ? doorColor : wallColor);
|
||||
final bool isPushwall = engine.pushwallManager.pushwalls.containsKey(
|
||||
'$x,$y',
|
||||
);
|
||||
final int color = isPushwall
|
||||
? pushwallColor
|
||||
: (tileId == 0
|
||||
? floorColor
|
||||
: (tileId >= 90 ? doorColor : wallColor));
|
||||
_fillMapRect(
|
||||
mapStartX + (x * tileSize),
|
||||
mapStartY + (y * tileSize),
|
||||
@@ -473,6 +481,23 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
|
||||
}
|
||||
}
|
||||
|
||||
final int enemyRadius = math.max(0, tileSize ~/ 3);
|
||||
final int enemySize = (enemyRadius * 2) + 1;
|
||||
for (final entity in engine.entities) {
|
||||
if (entity is! Enemy || entity.state == EntityState.dead) {
|
||||
continue;
|
||||
}
|
||||
final int enemyX = (mapStartX + (entity.x * tileSize)).floor();
|
||||
final int enemyY = (mapStartY + (entity.y * tileSize)).floor();
|
||||
_fillMapRect(
|
||||
enemyX - enemyRadius,
|
||||
enemyY - enemyRadius,
|
||||
enemySize,
|
||||
enemySize,
|
||||
enemyColor,
|
||||
);
|
||||
}
|
||||
|
||||
final int playerX = (mapStartX + (engine.player.x * tileSize)).floor();
|
||||
final int playerY = (mapStartY + (engine.player.y * tileSize)).floor();
|
||||
final int markerRadius = math.max(1, tileSize ~/ 2);
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:wolf_3d_dart/src/menu/menu_manager.dart';
|
||||
import 'package:wolf_3d_dart/src/rendering/fizzle_fade.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_entities.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_menu.dart';
|
||||
|
||||
import 'cli_renderer_backend.dart';
|
||||
@@ -370,8 +371,10 @@ class SixelRenderer extends CliRendererBackend<String> {
|
||||
const int floorColor = 8;
|
||||
const int wallColor = 7;
|
||||
const int doorColor = 14;
|
||||
const int pushwallColor = 6;
|
||||
const int enemyColor = 12;
|
||||
const int playerColor = 10;
|
||||
const int facingColor = 12;
|
||||
const int facingColor = 15;
|
||||
|
||||
for (int i = 0; i < _screen.length; i++) {
|
||||
_screen[i] = mapBgColor;
|
||||
@@ -392,9 +395,14 @@ class SixelRenderer extends CliRendererBackend<String> {
|
||||
for (int y = 0; y < 64; y++) {
|
||||
for (int x = 0; x < 64; x++) {
|
||||
final int tileId = engine.currentLevel[y][x];
|
||||
final int color = tileId == 0
|
||||
? floorColor
|
||||
: (tileId >= 90 ? doorColor : wallColor);
|
||||
final bool isPushwall = engine.pushwallManager.pushwalls.containsKey(
|
||||
'$x,$y',
|
||||
);
|
||||
final int color = isPushwall
|
||||
? pushwallColor
|
||||
: (tileId == 0
|
||||
? floorColor
|
||||
: (tileId >= 90 ? doorColor : wallColor));
|
||||
_fillMapRect(
|
||||
mapStartX + (x * tileSize),
|
||||
mapStartY + (y * tileSize),
|
||||
@@ -405,6 +413,23 @@ class SixelRenderer extends CliRendererBackend<String> {
|
||||
}
|
||||
}
|
||||
|
||||
final int enemyRadius = math.max(0, tileSize ~/ 3);
|
||||
final int enemySize = (enemyRadius * 2) + 1;
|
||||
for (final entity in engine.entities) {
|
||||
if (entity is! Enemy || entity.state == EntityState.dead) {
|
||||
continue;
|
||||
}
|
||||
final int enemyX = (mapStartX + (entity.x * tileSize)).floor();
|
||||
final int enemyY = (mapStartY + (entity.y * tileSize)).floor();
|
||||
_fillMapRect(
|
||||
enemyX - enemyRadius,
|
||||
enemyY - enemyRadius,
|
||||
enemySize,
|
||||
enemySize,
|
||||
enemyColor,
|
||||
);
|
||||
}
|
||||
|
||||
final int playerX = (mapStartX + (engine.player.x * tileSize)).floor();
|
||||
final int playerY = (mapStartY + (engine.player.y * tileSize)).floor();
|
||||
final int markerRadius = math.max(1, tileSize ~/ 2);
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:wolf_3d_dart/src/rendering/menu_font.dart';
|
||||
import 'package:wolf_3d_dart/src/rendering/renderer_backend.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_entities.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_menu.dart';
|
||||
|
||||
/// Pixel-accurate software renderer that writes directly into [FrameBuffer].
|
||||
@@ -150,8 +151,10 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
|
||||
final int floorColor = ColorPalette.vga32Bit[8];
|
||||
final int wallColor = ColorPalette.vga32Bit[7];
|
||||
final int doorColor = ColorPalette.vga32Bit[14];
|
||||
final int pushwallColor = ColorPalette.vga32Bit[6];
|
||||
final int enemyColor = ColorPalette.vga32Bit[12];
|
||||
final int playerColor = ColorPalette.vga32Bit[10];
|
||||
final int facingColor = ColorPalette.vga32Bit[12];
|
||||
final int facingColor = ColorPalette.vga32Bit[15];
|
||||
|
||||
_fillMenuPanel(0, 0, width, height, mapBgColor);
|
||||
|
||||
@@ -170,9 +173,14 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
|
||||
for (int y = 0; y < 64; y++) {
|
||||
for (int x = 0; x < 64; x++) {
|
||||
final int tileId = engine.currentLevel[y][x];
|
||||
final int color = tileId == 0
|
||||
? floorColor
|
||||
: (tileId >= 90 ? doorColor : wallColor);
|
||||
final bool isPushwall = engine.pushwallManager.pushwalls.containsKey(
|
||||
'$x,$y',
|
||||
);
|
||||
final int color = isPushwall
|
||||
? pushwallColor
|
||||
: (tileId == 0
|
||||
? floorColor
|
||||
: (tileId >= 90 ? doorColor : wallColor));
|
||||
_fillMenuPanel(
|
||||
mapStartX + (x * tileSize),
|
||||
mapStartY + (y * tileSize),
|
||||
@@ -183,6 +191,23 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
|
||||
}
|
||||
}
|
||||
|
||||
final int enemyRadius = math.max(0, tileSize ~/ 3);
|
||||
final int enemySize = (enemyRadius * 2) + 1;
|
||||
for (final entity in engine.entities) {
|
||||
if (entity is! Enemy || entity.state == EntityState.dead) {
|
||||
continue;
|
||||
}
|
||||
final int enemyX = (mapStartX + (entity.x * tileSize)).floor();
|
||||
final int enemyY = (mapStartY + (entity.y * tileSize)).floor();
|
||||
_fillMenuPanel(
|
||||
enemyX - enemyRadius,
|
||||
enemyY - enemyRadius,
|
||||
enemySize,
|
||||
enemySize,
|
||||
enemyColor,
|
||||
);
|
||||
}
|
||||
|
||||
final int playerX = (mapStartX + (engine.player.x * tileSize)).floor();
|
||||
final int playerY = (mapStartY + (engine.player.y * tileSize)).floor();
|
||||
final int markerRadius = math.max(1, tileSize ~/ 2);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:wolf_3d_dart/src/entities/entities/enemies/guard.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_input.dart';
|
||||
@@ -11,6 +12,16 @@ void main() {
|
||||
test('software renderer draws fullscreen map overlay when enabled', () {
|
||||
final engine = _buildEngine();
|
||||
engine.init();
|
||||
expect(engine.pushwallManager.pushwalls.containsKey('5,5'), isTrue);
|
||||
engine.entities.add(
|
||||
Guard(
|
||||
x: 8.5,
|
||||
y: 8.5,
|
||||
angle: 0,
|
||||
mapId: MapObject.guardStart,
|
||||
difficulty: Difficulty.medium,
|
||||
),
|
||||
);
|
||||
|
||||
final renderer = SoftwareRenderer();
|
||||
final frameNormal = renderer.render(engine);
|
||||
@@ -28,6 +39,8 @@ void main() {
|
||||
}
|
||||
|
||||
expect(changedPixels, greaterThan(mapPixels.length ~/ 5));
|
||||
expect(mapPixels.contains(ColorPalette.vga32Bit[6]), isTrue);
|
||||
expect(mapPixels.contains(ColorPalette.vga32Bit[12]), isTrue);
|
||||
expect(mapPixels.contains(ColorPalette.vga32Bit[10]), isTrue);
|
||||
});
|
||||
});
|
||||
@@ -57,7 +70,9 @@ WolfEngine _buildEngine() {
|
||||
_fillBoundaries(wallGrid, 2);
|
||||
wallGrid[2][4] = 1;
|
||||
wallGrid[2][5] = 90;
|
||||
wallGrid[5][5] = 1;
|
||||
objectGrid[2][2] = MapObject.playerEast;
|
||||
objectGrid[5][5] = MapObject.pushwallTrigger;
|
||||
|
||||
return WolfEngine(
|
||||
data: WolfensteinData(
|
||||
|
||||
Reference in New Issue
Block a user