69 lines
1.5 KiB
Dart
69 lines
1.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:wolf_3d_engine/wolf_3d_engine.dart';
|
|
|
|
// 1. The widget now only requires the engine!
|
|
abstract class BaseWolfRenderer extends StatefulWidget {
|
|
final WolfEngine engine;
|
|
|
|
const BaseWolfRenderer({
|
|
required this.engine,
|
|
super.key,
|
|
});
|
|
}
|
|
|
|
abstract class BaseWolfRendererState<T extends BaseWolfRenderer>
|
|
extends State<T>
|
|
with SingleTickerProviderStateMixin {
|
|
late final Ticker gameLoop;
|
|
final FocusNode focusNode = FocusNode();
|
|
|
|
Duration _lastTick = Duration.zero;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
// DO NOT initialize the engine here. Just start the loop!
|
|
gameLoop = createTicker(_tick)..start();
|
|
focusNode.requestFocus();
|
|
}
|
|
|
|
void _tick(Duration elapsed) {
|
|
if (!widget.engine.isInitialized) return;
|
|
|
|
Duration delta = elapsed - _lastTick;
|
|
_lastTick = elapsed;
|
|
|
|
// Tick the shared engine
|
|
widget.engine.tick(delta);
|
|
|
|
performRender();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
gameLoop.dispose();
|
|
focusNode.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
void performRender();
|
|
Widget buildViewport(BuildContext context);
|
|
Color get scaffoldColor;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: scaffoldColor,
|
|
body: KeyboardListener(
|
|
focusNode: focusNode,
|
|
autofocus: true,
|
|
onKeyEvent: (_) {},
|
|
child: Center(
|
|
child: buildViewport(context),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|