De-coupled remaining aspects of game into packages
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
7
packages/wolf_3d_engine/lib/src/engine_audio.dart
Normal file
7
packages/wolf_3d_engine/lib/src/engine_audio.dart
Normal file
@@ -0,0 +1,7 @@
|
||||
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
||||
|
||||
abstract class EngineAudio {
|
||||
void playLevelMusic(WolfLevel level);
|
||||
void stopMusic();
|
||||
// You can easily add things like void playSoundEffect(SoundId id); later!
|
||||
}
|
||||
11
packages/wolf_3d_engine/lib/src/engine_input.dart
Normal file
11
packages/wolf_3d_engine/lib/src/engine_input.dart
Normal file
@@ -0,0 +1,11 @@
|
||||
import 'package:wolf_3d_entities/wolf_3d_entities.dart';
|
||||
|
||||
class EngineInput {
|
||||
bool isMovingForward = false;
|
||||
bool isMovingBackward = false;
|
||||
bool isTurningLeft = false;
|
||||
bool isTurningRight = false;
|
||||
bool isInteracting = false;
|
||||
bool isFiring = false;
|
||||
WeaponType? requestedWeapon;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:wolf_3d_entities/wolf_3d_entities.dart';
|
||||
|
||||
class InputManager {
|
||||
Set<LogicalKeyboardKey> _previousKeys = {};
|
||||
|
||||
bool isMovingForward = false;
|
||||
bool isMovingBackward = false;
|
||||
bool isTurningLeft = false;
|
||||
bool isTurningRight = false;
|
||||
|
||||
// Discrete (triggers once per press)
|
||||
bool isInteracting = false;
|
||||
|
||||
// Continuous
|
||||
bool isFiring = false;
|
||||
|
||||
WeaponType? requestedWeapon;
|
||||
|
||||
void update() {
|
||||
final pressedKeys = HardwareKeyboard.instance.logicalKeysPressed;
|
||||
|
||||
// Calculate all keys that were pressed exactly on this frame
|
||||
final newlyPressedKeys = pressedKeys.difference(_previousKeys);
|
||||
|
||||
// * Movement
|
||||
isMovingForward = pressedKeys.contains(LogicalKeyboardKey.keyW);
|
||||
isMovingBackward = pressedKeys.contains(LogicalKeyboardKey.keyS);
|
||||
isTurningLeft = pressedKeys.contains(LogicalKeyboardKey.keyA);
|
||||
isTurningRight = pressedKeys.contains(LogicalKeyboardKey.keyD);
|
||||
|
||||
// * Interaction (Space)
|
||||
// Much simpler now using the newlyPressedKeys set
|
||||
isInteracting = newlyPressedKeys.contains(LogicalKeyboardKey.space);
|
||||
|
||||
// * Firing (Left Control)
|
||||
// - Keeping this continuous for machine guns
|
||||
isFiring =
|
||||
pressedKeys.contains(LogicalKeyboardKey.controlLeft) &&
|
||||
!pressedKeys.contains(LogicalKeyboardKey.space);
|
||||
|
||||
// * Manual Weapon Switching
|
||||
requestedWeapon = null;
|
||||
|
||||
// Iterate through newly pressed keys and switch on them
|
||||
for (final LogicalKeyboardKey key in newlyPressedKeys) {
|
||||
switch (key) {
|
||||
case LogicalKeyboardKey.digit1:
|
||||
requestedWeapon = WeaponType.knife;
|
||||
case LogicalKeyboardKey.digit2:
|
||||
requestedWeapon = WeaponType.pistol;
|
||||
case LogicalKeyboardKey.digit3:
|
||||
requestedWeapon = WeaponType.machineGun;
|
||||
case LogicalKeyboardKey.digit4:
|
||||
requestedWeapon = WeaponType.chainGun;
|
||||
}
|
||||
}
|
||||
|
||||
// * Save state for next tick
|
||||
_previousKeys = Set.from(pressedKeys);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// No flutter imports allowed!
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
||||
@@ -11,17 +10,19 @@ class WolfEngine {
|
||||
required this.difficulty,
|
||||
required this.startingEpisode,
|
||||
required this.onGameWon,
|
||||
required this.audio,
|
||||
});
|
||||
|
||||
final WolfensteinData data;
|
||||
final Difficulty difficulty;
|
||||
final int startingEpisode;
|
||||
|
||||
final EngineAudio audio;
|
||||
|
||||
// Standard Dart function instead of Flutter's VoidCallback
|
||||
final void Function() onGameWon;
|
||||
|
||||
// Managers
|
||||
final InputManager inputManager = InputManager();
|
||||
final DoorManager doorManager = DoorManager();
|
||||
final PushwallManager pushwallManager = PushwallManager();
|
||||
|
||||
@@ -46,10 +47,10 @@ class WolfEngine {
|
||||
}
|
||||
|
||||
// Expect standard Dart Duration. The host app is responsible for the loop.
|
||||
void tick(Duration elapsed) {
|
||||
void tick(Duration elapsed, EngineInput input) {
|
||||
if (!isInitialized) return;
|
||||
|
||||
final inputResult = _processInputs(elapsed);
|
||||
final inputResult = _processInputs(elapsed, input);
|
||||
|
||||
doorManager.update(elapsed);
|
||||
pushwallManager.update(elapsed, currentLevel);
|
||||
@@ -94,8 +95,7 @@ class WolfEngine {
|
||||
doorManager.initDoors(currentLevel);
|
||||
pushwallManager.initPushwalls(currentLevel, objectLevel);
|
||||
|
||||
// TODO: Consider abstracting audio so the engine doesn't depend on Wolf3d singleton
|
||||
Wolf3d.I.audio.playLevelMusic(activeLevel);
|
||||
audio.playLevelMusic(activeLevel);
|
||||
|
||||
for (int y = 0; y < 64; y++) {
|
||||
for (int x = 0; x < 64; x++) {
|
||||
@@ -144,7 +144,7 @@ class WolfEngine {
|
||||
}
|
||||
|
||||
void _onLevelCompleted({bool isSecretExit = false}) {
|
||||
Wolf3d.I.audio.stopMusic();
|
||||
audio.stopMusic();
|
||||
|
||||
final currentEpisode = data.episodes[_currentEpisodeIndex];
|
||||
|
||||
@@ -169,37 +169,39 @@ class WolfEngine {
|
||||
}
|
||||
}
|
||||
|
||||
({Coordinate2D movement, double dAngle}) _processInputs(Duration elapsed) {
|
||||
inputManager.update();
|
||||
|
||||
({Coordinate2D movement, double dAngle}) _processInputs(
|
||||
Duration elapsed,
|
||||
EngineInput input,
|
||||
) {
|
||||
const double moveSpeed = 0.14;
|
||||
const double turnSpeed = 0.10;
|
||||
|
||||
Coordinate2D movement = const Coordinate2D(0, 0);
|
||||
double dAngle = 0.0;
|
||||
|
||||
if (inputManager.requestedWeapon != null) {
|
||||
player.requestWeaponSwitch(inputManager.requestedWeapon!);
|
||||
// Read directly from the passed-in EngineInput object
|
||||
if (input.requestedWeapon != null) {
|
||||
player.requestWeaponSwitch(input.requestedWeapon!);
|
||||
}
|
||||
|
||||
if (inputManager.isFiring) {
|
||||
if (input.isFiring) {
|
||||
player.fire(elapsed.inMilliseconds);
|
||||
} else {
|
||||
player.releaseTrigger();
|
||||
}
|
||||
|
||||
if (inputManager.isTurningLeft) dAngle -= turnSpeed;
|
||||
if (inputManager.isTurningRight) dAngle += turnSpeed;
|
||||
if (input.isTurningLeft) dAngle -= turnSpeed;
|
||||
if (input.isTurningRight) dAngle += turnSpeed;
|
||||
|
||||
Coordinate2D forwardVec = Coordinate2D(
|
||||
math.cos(player.angle),
|
||||
math.sin(player.angle),
|
||||
);
|
||||
|
||||
if (inputManager.isMovingForward) movement += forwardVec * moveSpeed;
|
||||
if (inputManager.isMovingBackward) movement -= forwardVec * moveSpeed;
|
||||
if (input.isMovingForward) movement += forwardVec * moveSpeed;
|
||||
if (input.isMovingBackward) movement -= forwardVec * moveSpeed;
|
||||
|
||||
if (inputManager.isInteracting) {
|
||||
if (input.isInteracting) {
|
||||
int targetX = (player.x + math.cos(player.angle)).toInt();
|
||||
int targetY = (player.y + math.sin(player.angle)).toInt();
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
/// More dartdocs go here.
|
||||
library;
|
||||
|
||||
export 'src/engine_audio.dart';
|
||||
export 'src/engine_input.dart';
|
||||
export 'src/managers/door_manager.dart';
|
||||
export 'src/managers/pushwall_manager.dart';
|
||||
export 'src/player/player.dart';
|
||||
|
||||
@@ -11,6 +11,7 @@ resolution: workspace
|
||||
dependencies:
|
||||
wolf_3d_data_types: any
|
||||
wolf_3d_entities: any
|
||||
wolf_3d_input: any
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^6.0.0
|
||||
|
||||
Reference in New Issue
Block a user