WIP fixing ASCII renderer

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-16 15:42:48 +01:00
parent fdfe5d336f
commit dd9bd5897e
7 changed files with 62 additions and 45 deletions

54
.gitignore vendored
View File

@@ -1,22 +1,22 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
**/*.class
**/*.log
**/*.pyc
**/*.swp
**/.DS_Store
**/.atom/
**/.build/
**/.buildlog/
**/.history
**/.svn/
**/.swiftpm/
**/migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
**/*.iml
**/*.ipr
**/*.iws
**/.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
@@ -26,20 +26,20 @@ migrate_working_dir/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/coverage/
**/.dart_tool/
**/.flutter-plugins-dependencies
**/.pub-cache/
**/.pub/
**/build/
**/coverage/
# Symbolication related
app.*.symbols
**/app.*.symbols
# Obfuscation related
app.*.map.json
**/app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
**/android/app/debug
**/android/app/profile
**/android/app/release

18
.vscode/launch.json vendored
View File

@@ -5,24 +5,30 @@
"version": "0.2.0",
"configurations": [
{
"name": "wolf_dart",
"name": "GUI",
"request": "launch",
"type": "dart",
"program": "lib/main.dart"
"program": "apps/wolf_3d_gui/lib/main.dart"
},
{
"name": "wolf_dart (profile mode)",
"name": "CLI",
"request": "launch",
"type": "dart",
"program": "apps/wolf_3d_cli/bin/main.dart"
},
{
"name": "GUI (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile",
"program": "lib/main.dart"
"program": "apps/wolf_3d_gui/lib/main.dart"
},
{
"name": "wolf_dart (release mode)",
"name": "GUI (release mode)",
"request": "launch",
"type": "dart",
"flutterMode": "release",
"program": "lib/main.dart"
"program": "apps/wolf_3d_gui/lib/main.dart"
}
]
}

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
import 'package:wolf_3d_flutter/wolf_3d.dart';
import 'package:wolf_3d_renderer/wolf_3d_ascii_renderer.dart';
import 'package:wolf_3d_renderer/wolf_3d_flutter_renderer.dart';
class DifficultyScreen extends StatefulWidget {
const DifficultyScreen({
@@ -26,7 +26,7 @@ class _DifficultyScreenState extends State<DifficultyScreen> {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (_) => WolfAsciiRenderer(
builder: (_) => WolfFlutterRenderer(
Wolf3d.I.activeGame,
difficulty: difficulty,
startingEpisode: Wolf3d.I.activeEpisode,

View File

@@ -55,7 +55,11 @@ class AsciiRasterizer extends Rasterizer {
// Terminal characters are usually twice as tall as they are wide.
// We override the base multiplier to squish sprites horizontally.
@override
double get aspectMultiplier => 0.6;
double get aspectMultiplier => 2.0;
// Squish the entire 3D projection vertically by 50% to counteract tall terminal fonts
@override
double get verticalStretch => 1.8;
// Intercept the base render call to initialize our text grid
@override

View File

@@ -15,6 +15,10 @@ abstract class Rasterizer {
/// ASCII renderers can override this (e.g., 0.6) to account for tall characters.
double get aspectMultiplier => 1.0;
/// A multiplier to counteract tall pixel formats (like 1:2 terminal fonts).
/// Defaults to 1.0 (no squish) for standard pixel rendering.
double get verticalStretch => 1.0;
/// The main entry point called by the game loop.
/// Orchestrates the mathematical rendering pipeline.
dynamic render(WolfEngine engine, FrameBuffer buffer) {
@@ -279,7 +283,8 @@ abstract class Rasterizer {
if (side == 1 && math.sin(player.angle) < 0) texX = 63 - texX;
// Calculate drawing dimensions
int columnHeight = (viewHeight / perpWallDist).toInt();
int columnHeight = ((viewHeight / perpWallDist) * verticalStretch)
.toInt();
int drawStart = (-columnHeight ~/ 2 + viewHeight ~/ 2).clamp(
0,
viewHeight,
@@ -330,10 +335,12 @@ abstract class Rasterizer {
if (transformY > 0) {
int spriteScreenX = ((width / 2) * (1 + transformX / transformY))
.toInt();
int spriteHeight = (viewHeight / transformY).abs().toInt();
int spriteHeight = ((viewHeight / transformY).abs() * verticalStretch)
.toInt();
// Scale width based on the aspectMultiplier (useful for ASCII)
int spriteWidth = (spriteHeight * aspectMultiplier).toInt();
int spriteWidth = (spriteHeight * aspectMultiplier / verticalStretch)
.toInt();
int drawStartY = -spriteHeight ~/ 2 + viewHeight ~/ 2;
int drawEndY = spriteHeight ~/ 2 + viewHeight ~/ 2;

View File

@@ -185,7 +185,7 @@ class WolfEngine {
}
if (input.isFiring) {
player.fire(elapsed.inMilliseconds);
player.fire(_timeAliveMs);
} else {
player.releaseTrigger();
}
@@ -271,7 +271,7 @@ class WolfEngine {
for (Entity entity in entities) {
if (entity is Enemy) {
final intent = entity.update(
elapsedMs: elapsed.inMilliseconds,
elapsedMs: _timeAliveMs,
playerPosition: player.position,
isWalkable: isWalkable,
tryOpenDoor: doorManager.tryOpenDoor,

View File

@@ -7,8 +7,8 @@ import 'package:wolf_3d_engine/wolf_3d_engine.dart';
import 'package:wolf_3d_flutter/wolf_3d_input_flutter.dart';
import 'package:wolf_3d_input/wolf_3d_input.dart';
class WolfRenderer extends StatefulWidget {
const WolfRenderer(
class WolfFlutterRenderer extends StatefulWidget {
const WolfFlutterRenderer(
this.data, {
required this.difficulty,
required this.startingEpisode,
@@ -22,10 +22,10 @@ class WolfRenderer extends StatefulWidget {
final EngineAudio audio;
@override
State<WolfRenderer> createState() => _WolfRendererState();
State<WolfFlutterRenderer> createState() => _WolfFlutterRendererState();
}
class _WolfRendererState extends State<WolfRenderer>
class _WolfFlutterRendererState extends State<WolfFlutterRenderer>
with SingleTickerProviderStateMixin {
final Wolf3dInput inputManager = Wolf3dFlutterInput();
late final WolfEngine engine;