Refactored ActionService, players state in frontend

This commit is contained in:
martin 2023-07-04 22:42:44 +02:00
parent eed4f50313
commit 45131efb37
4 changed files with 44 additions and 47 deletions

View File

@ -8,6 +8,7 @@ import {testMap} from "../game/map";
import {TileType} from "../game/tileType";
import Player, {State} from "../game/player";
import {Colour} from "../game/colour";
import PlayerStats from "../game/playerStats";
const wsService = new WebSocketService(import.meta.env.VITE_API);
@ -16,12 +17,10 @@ const ghosts = [
new Ghost({Colour: Colour.Purple}),
];
export const GameComponent: Component<{ player: Player }> = (
{
player
}) => {
export const GameComponent: Component<{ player: Player }> = ({player}) => {
// TODO find spawn points
const [characters, setCharacters] = useState<Character[]>();
const [players, setPlayers] = useState<Player[]>([player]);
const [dice, setDice] = useState<number[]>();
const [selectedDice, setSelectedDice] = useState<SelectedDice>();
@ -46,7 +45,7 @@ export const GameComponent: Component<{ player: Player }> = (
rollDice();
}
function doAction(message: MessageEvent<string>): void {
function doAction(message: MessageEvent<string>): void { // TODO move to Service
const parsed: ActionMessage = JSON.parse(message.data);
switch (parsed.Action) {
@ -59,9 +58,10 @@ export const GameComponent: Component<{ player: Player }> = (
removeEatenPellets(parsed);
break;
case GameAction.playerInfo:
const players = parsed.Data as PlayerProps[];
console.log(players);
const pacMen = players.filter(p => p.PacMan).map(p => new PacMan(p.PacMan!));
const playerProps = parsed.Data as PlayerProps[];
console.log(playerProps);
setPlayers(playerProps.map(p => new Player(p)));
const pacMen = playerProps.filter(p => p.PacMan).map(p => new PacMan(p.PacMan!));
console.log(pacMen);
// TODO find spawn points
setCharacters([...pacMen, ...ghosts]);
@ -69,10 +69,9 @@ export const GameComponent: Component<{ player: Player }> = (
case GameAction.ready:
const isReady = parsed.Data.AllReady as boolean;
if (isReady) {
setCurrentPlayer(parsed.Data.Starter as Player);
} else {
// TODO update player states
setCurrentPlayer(new Player(parsed.Data.Starter as PlayerProps));
}
setPlayers((parsed.Data.Players as PlayerProps[]).map(p => new Player(p)));
break;
}
}
@ -136,21 +135,13 @@ export const GameComponent: Component<{ player: Player }> = (
<>
<div className={"flex-center"}>
{
player.State === State.waitingForPlayers ?
currentPlayer === undefined || currentPlayer.State === State.waitingForPlayers ?
<button onClick={sendReady}>Ready</button> :
<button onClick={startGameLoop}>Roll dice</button>
}
</div>
<AllDice values={dice} onclick={handleDiceClick} selectedDiceIndex={selectedDice?.index}/>
{
(characters?.filter(c => c.isPacMan()) as PacMan[] | undefined)?.map(c =>
/*TODO use PlayerStats instead*/
<div key={c.Colour} className={"mx-auto w-fit m-2"}>
<p className={currentPlayer === player ? "underline" : ""}>Player: {player.Colour}</p>
<p>Pellets: {player.Box.count}</p>
<p>PowerPellets: {player.Box.countPowerPellets}</p>
</div>)
}
{players?.map(p => <PlayerStats key={p.Name} player={p} isCurrentPlayer={currentPlayer === p}/>)}
{characters &&
<GameBoard className={"mx-auto my-2"}
characters={characters}

View File

@ -15,6 +15,7 @@ const PlayerStats: Component<PlayerStatsProps> = (
}) => (
<div key={player.Colour} className={`mx-auto w-fit m-2 ${className}`} id={id}>
<p className={isCurrentPlayer ? "underline" : ""}>Player: {player.Name}</p>
<p>Colour: {player.Colour}</p>
{player.State === State.inGame ?
<>
<p>Pellets: {player.Box.count}</p>

View File

@ -9,9 +9,9 @@ namespace pacMan.Services;
public interface IActionService
{
void DoAction(ActionMessage message);
void RollDice(ActionMessage message);
void PlayerInfo(ActionMessage message);
void Ready(ActionMessage message);
List<int> RollDice(ActionMessage message);
List<IPlayer> PlayerInfo(ActionMessage message);
object Ready(ActionMessage message);
}
public class ActionService : IActionService // TODO tests
@ -32,54 +32,54 @@ public class ActionService : IActionService // TODO tests
public void DoAction(ActionMessage message)
{
switch (message.Action)
message.Data = message.Action switch
{
case GameAction.RollDice:
RollDice(message);
break;
case GameAction.PlayerInfo:
PlayerInfo(message);
break;
case GameAction.Ready:
Ready(message);
break;
case GameAction.MoveCharacter:
default:
_logger.Log(LogLevel.Information, "Forwarding message to all clients");
break;
}
GameAction.RollDice => RollDice(message),
GameAction.PlayerInfo => PlayerInfo(message),
GameAction.Ready => Ready(message),
_ => message.Data
};
}
public void RollDice(ActionMessage message)
public List<int> RollDice(ActionMessage message)
{
var rolls = _diceCup.Roll();
_logger.Log(LogLevel.Information, "Rolled [{}]", string.Join(", ", rolls));
message.Data = rolls;
return rolls;
}
public void PlayerInfo(ActionMessage message)
public List<IPlayer> PlayerInfo(ActionMessage message)
{
_player = JsonSerializer.Deserialize<Player>(message.Data);
_group = _wsService.AddPlayer(_player); // TODO missing some data?
message.Data = _group.Players;
return _group.Players;
}
public void Ready(ActionMessage message)
public object Ready(ActionMessage message)
{
object data;
if (_player != null)
{
var players = _group.SetReady(_player).ToArray();
if (players.All(p => p.State == State.Ready))
{
// TODO roll to start
message.Data = new { AllReady = true, Starter = _group.RandomPlayer };
_group.SetAllInGame();
data = new { AllReady = true, Players = players, Starter = _group.RandomPlayer };
}
else
message.Data = new { AllReady = false, players };
{
data = new { AllReady = false, Players = players };
}
}
else
{
message.Data = "Player not found, please create a new player";
data = "Player not found, please create a new player";
}
return data;
}
}

View File

@ -28,4 +28,9 @@ public class GameGroup // TODO tests
player.State = State.Ready;
return Players;
}
public void SetAllInGame()
{
foreach (var player in Players) player.State = State.InGame;
}
}