import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:wolf_3d_dart/wolf_3d_data_types.dart'; import 'package:wolf_3d_dart/wolf_3d_engine.dart'; import 'package:wolf_3d_flutter/wolf_3d_input_flutter.dart'; import 'package:wolf_3d_renderer/wolf_3d_ascii_renderer.dart'; import 'package:wolf_3d_renderer/wolf_3d_flutter_renderer.dart'; class GameScreen extends StatefulWidget { final WolfensteinData data; final Difficulty difficulty; final int startingEpisode; final EngineAudio audio; final Wolf3dFlutterInput input; const GameScreen({ required this.data, required this.difficulty, required this.startingEpisode, required this.audio, required this.input, super.key, }); @override State createState() => _GameScreenState(); } class _GameScreenState extends State { late final WolfEngine _engine; bool _useAsciiMode = false; @override void initState() { super.initState(); _engine = WolfEngine( data: widget.data, difficulty: widget.difficulty, startingEpisode: widget.startingEpisode, frameBuffer: FrameBuffer(320, 200), audio: widget.audio, input: widget.input, onGameWon: () => Navigator.of(context).pop(), ); _engine.init(); } @override Widget build(BuildContext context) { return Scaffold( body: Listener( onPointerDown: widget.input.onPointerDown, onPointerUp: widget.input.onPointerUp, onPointerMove: widget.input.onPointerMove, onPointerHover: widget.input.onPointerMove, child: Stack( children: [ _useAsciiMode ? WolfAsciiRenderer(engine: _engine) : WolfFlutterRenderer(engine: _engine), if (!_engine.isInitialized) Container( color: Colors.black, child: const Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator(color: Colors.teal), SizedBox(height: 20), Text( "GET PSYCHED!", style: TextStyle( color: Colors.teal, fontFamily: 'monospace', ), ), ], ), ), ), // TAB listener Focus( autofocus: true, onKeyEvent: (node, event) { if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.tab) { setState(() => _useAsciiMode = !_useAsciiMode); return KeyEventResult.handled; } return KeyEventResult.ignored; }, child: const SizedBox.shrink(), ), // Loading Overlay if (!_engine.isInitialized) Container( color: Colors.black, child: const Center( child: CircularProgressIndicator(color: Colors.teal), ), ), Positioned( top: 16, right: 16, child: Text( 'TAB: Swap Renderer', style: TextStyle(color: Colors.white.withValues(alpha: 0.5)), ), ), ], ), ), ); } }