Support player names and online join flow

Move SignalR group join into GameManager and add support for player names and improved online join flow.

- Moved Groups.AddToGroupAsync call out of GameHubSocket into GameManager (hubContext.Groups.AddToGroupAsync) so group membership is handled when adding players to a game.
- GUI: added player name input to GameJoinMenu and updated JoinGameObject to include playerName and use string gameCode.
- OnlineMode & LocalMode: constructors updated to instantiate games without passing settings; removed WaitingForOpponent state and cleaned up event bindings.
- OnlineGame: rewrote to handle onGameCreated/onGameJoined/onGameStarted/onFieldUpdated/onGameEnded/onError, added joinGame validation (expects 6-digit code), join flow (connect + join), state updates, drop forwarding to player.drop(gameId, index) and place description updates.
- LocalGame: constructor signature simplified to no-arg.

These changes centralize group management, add player identification, validate join codes, and improve game state/event handling for online play.
This commit is contained in:
2026-03-08 21:45:05 +01:00
committed by Jonas
parent acae815a2a
commit 4826760d73
8 changed files with 100 additions and 17 deletions
+21 -7
View File
@@ -1,5 +1,7 @@
<script setup lang="ts">
import CreateOrJoinMenu from '@/components/CreateOrJoinMenu.vue';
import Field from '@/components/game/Field.vue';
import InfoField from '@/components/game/InfoField.vue';
import GameCreationMenu from '@/components/GameCreationMenu.vue';
import GameEndedMenu from '@/components/GameEndedMenu.vue';
import GameJoinMenu from '@/components/GameJoinMenu.vue';
@@ -13,7 +15,6 @@ enum CurrentState {
CreateOrJoinSelection,
CreatingGame,
JoiningGame,
WaitingForOpponent,
Game,
EndScreen,
}
@@ -24,11 +25,12 @@ let settings = ref<GameSettings>({
});
let joiningModel = ref<JoinGameObject>({
playerName: 'Spieler 2',
failed: false,
});
var currentState = ref<CurrentState>(CurrentState.CreateOrJoinSelection);
const game = ref<OnlineGame>(new OnlineGame(settings.value));
const game = ref<OnlineGame>(new OnlineGame());
const gameField = ref<number[][]>([]);
const currentSelectionIndex = ref<number | null>(null);
const gameEndedInformation = ref<GameEnded | null>(null);
@@ -46,11 +48,21 @@ game.value.onGameCreated = (gameCode: string) => {
settings.value.message = `Das Spiel ist erstellt, deine Freund kann über folgendem Code Beitreten: ${gameCode}`;
};
game.value.onGameStarted = () => {
currentState.value = CurrentState.Game;
};
game.value.onGameJoinedFailed = () => {
joiningModel.value.failed = true;
};
async function createGame() {
await game.value.createGame(settings.value);
await game.value.createGame(settings.value);
}
async function tryToJoin() {}
async function tryToJoin() {
await game.value.joinGame(joiningModel.value);
}
</script>
<template>
@@ -62,14 +74,16 @@ async function tryToJoin() {}
<GameCreationMenu
v-model:settings="settings"
@create-game="createGame()"
v-else-if="currentState === CurrentState.CreatingGame || currentState === CurrentState.WaitingForOpponent"
@create-game="createGame"
v-else-if="
currentState === CurrentState.CreatingGame
"
/>
<GameJoinMenu
:joinGameObject="joiningModel"
v-else-if="currentState === CurrentState.JoiningGame"
@join="tryToJoin()"
@join="tryToJoin"
/>
<GameEndedMenu