Updated deps, find spawnpoints, other refactoring

This commit is contained in:
martin 2023-07-09 17:10:39 +02:00
parent 920a941156
commit c0a35fc298
7 changed files with 573 additions and 518 deletions

File diff suppressed because it is too large Load Diff

View File

@ -3,29 +3,29 @@
"version": "0.1.1",
"private": true,
"dependencies": {
"@headlessui/react": "^1.7.14",
"@headlessui/react": "^1.7.15",
"@heroicons/react": "^2.0.18",
"jotai": "^2.2.2",
"oidc-client": "^1.11.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.11.2",
"react-router-dom": "^6.14.1",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"@types/react": "^18.2.7",
"@types/react-dom": "^18.2.4",
"@vitejs/plugin-react": "^4.0.0",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@vitejs/plugin-react": "^4.0.2",
"autoprefixer": "^10.4.14",
"cross-env": "^7.0.3",
"happy-dom": "^9.20.3",
"postcss": "^8.4.24",
"postcss": "^8.4.25",
"tailwindcss": "^3.3.2",
"typescript": "^5.0.4",
"vite": "^4.3.9",
"typescript": "^5.1.6",
"vite": "^4.4.2",
"vite-plugin-svgr": "^3.2.0",
"vite-tsconfig-paths": "^4.2.0",
"vitest": "^0.31.1"
"vitest": "^0.31.4"
},
"resolutions": {
"css-what": "^5.0.1",

View File

@ -1,4 +1,6 @@
import React from "react";
import {useSetAtom} from "jotai";
import {selectedDiceAtom} from "../utils/state";
interface AllDiceProps extends ComponentProps {
values?: number[],
@ -10,14 +12,13 @@ export const AllDice: Component<AllDiceProps> = (
{
className,
values,
onclick,
selectedDiceIndex
}) => {
function handleClick(index: SelectedDice) {
if (onclick) {
onclick(index);
}
const setSelectedDice = useSetAtom(selectedDiceAtom);
function handleClick(dice: SelectedDice): void {
setSelectedDice(dice);
}
return (

View File

@ -20,23 +20,11 @@ export const GameComponent: Component<{ player: Player }> = ({player}) => {
const [selectedDice, setSelectedDice] = useAtom(selectedDiceAtom);
const [currentPlayer] = useAtom(currentPlayerAtom);
function handleDiceClick(selected: SelectedDice): void {
setSelectedDice(selected);
}
function rollDice(): void {
wsService.send({Action: GameAction.rollDice});
}
function startGameLoop(): void {
if (currentPlayer !== player) return;
if (currentPlayer?.Name !== player.Name) return;
if (!wsService.isOpen()) {
setTimeout(startGameLoop, 50);
return;
}
setSelectedDice(undefined);
rollDice();
wsService.send({Action: GameAction.rollDice});
}
function onCharacterMove(eatenPellets: Position[]): void {
@ -56,7 +44,6 @@ export const GameComponent: Component<{ player: Player }> = ({player}) => {
}
async function sendPlayer(): Promise<void> {
await wsService.waitForOpen();
wsService.send({Action: GameAction.playerInfo, Data: player});
}
@ -64,7 +51,7 @@ export const GameComponent: Component<{ player: Player }> = ({player}) => {
wsService.onReceive = doAction;
wsService.open();
void sendPlayer();
wsService.waitForOpen().then(() => void sendPlayer());
return () => wsService.close();
}, []);
@ -82,7 +69,7 @@ export const GameComponent: Component<{ player: Player }> = ({player}) => {
<button onClick={startGameLoop}>Roll dice</button>
}
</div>
<AllDice values={dice} onclick={handleDiceClick} selectedDiceIndex={selectedDice?.index}/>
<AllDice values={dice} selectedDiceIndex={selectedDice?.index}/>
{players?.map(p => <PlayerStats key={p.Name} player={p} isCurrentPlayer={currentPlayer === p}/>)}
{characters &&
<GameBoard className={"mx-auto my-2"}

View File

@ -1,3 +1,6 @@
import {CharacterType} from "./character";
import {Direction} from "./direction";
/**
* 0 = empty
* 1 = wall
@ -6,16 +9,35 @@
* 4 = ghost spawn
* 5 = pacman spawn
*/
export const testMap: GameMap = [
export const testMap: GameMap = [ // TODO create map class object using tile type enum
[1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
[1, 2, 0, 0, 0, 2, 0, 0, 0, 2, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 5, 1, 0, 1, 4, 1, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 0],
[1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 4, 1, 0, 1, 5, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 2, 0, 0, 0, 2, 0, 0, 0, 2, 1],
[1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
];
];
export function getCharacterSpawns(map: GameMap): { type: CharacterType, position: DirectionalPosition }[] {
const result: { type: CharacterType, position: DirectionalPosition }[] = [];
for (let row = 0; row < map.length; row++) {
for (let col = 0; col < map.length; col++) {
// TODO find direction
if (map[row][col] === 4) {
result.push({type: CharacterType.ghost, position: {At: {x: col, y: row}, Direction: Direction.up}});
} else if (map[row][col] === 5) {
result.push({
type: CharacterType.pacMan, position: {At: {x: col, y: row}, Direction: Direction.up}
});
}
}
}
return result;
}

View File

@ -1,6 +1,6 @@
import Player from "../game/player";
import {Character, Ghost, PacMan} from "../game/character";
import {testMap} from "../game/map";
import {Character, CharacterType, Ghost, PacMan} from "../game/character";
import {getCharacterSpawns, testMap} from "../game/map";
import {TileType} from "../game/tileType";
import {getDefaultStore} from "jotai";
import {charactersAtom, currentPlayerAtom, diceAtom, playersAtom} from "./state";
@ -13,15 +13,23 @@ export enum GameAction {
ready,
}
const ghosts = [
new Ghost({Colour: Colour.Purple}),
new Ghost({Colour: Colour.Purple}),
const ghostsProps: CharacterProps[] = [
{Colour: Colour.Purple},
{Colour: Colour.Purple},
];
let spawns = getCharacterSpawns(testMap).filter(spawn => spawn.type === CharacterType.ghost);
ghostsProps.forEach(ghost => {
ghost.SpawnPosition = spawns.pop()?.position;
});
const ghosts = ghostsProps.map(props => new Ghost(props));
const store = getDefaultStore();
export const doAction: MessageEventFunction<string> = (event): void => { // TODO divide into smaller functions
const message: ActionMessage = JSON.parse(event.data);
console.debug("Received message:", message);
switch (message.Action as GameAction) {
case GameAction.rollDice:
@ -73,14 +81,20 @@ function removeEatenPellets(data?: MoveCharacterData): void {
function playerInfo(data?: PlayerProps[]): void {
const playerProps = data ?? [];
console.log(playerProps);
store.set(playersAtom, 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
spawns = getCharacterSpawns(testMap).filter(spawn => spawn.type === CharacterType.pacMan);
const pacMen = playerProps.filter(p => p.PacMan).map(p => {
if (!p.PacMan!.SpawnPosition) {
p.PacMan!.SpawnPosition = spawns.pop()?.position;
}
return new PacMan(p.PacMan!);
});
store.set(charactersAtom, [...pacMen, ...ghosts]);
}
type ReadyData =
| { AllReady: true, Starter: PlayerProps, Players: PlayerProps[] }
| { AllReady: false, Players: PlayerProps[] }
@ -92,6 +106,6 @@ function ready(data?: ReadyData): void {
if (isReady) {
store.set(currentPlayerAtom, new Player(data.Starter));
}
store.set(playersAtom, (data.Players).map(p => new Player(p)));
store.set(playersAtom, data.Players.map(p => new Player(p)));
}
}

View File

@ -16,8 +16,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SpaProxy" Version="7.0.5" />
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="5.0.4">
<PackageReference Include="Microsoft.AspNetCore.SpaProxy" Version="7.0.8" />
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="5.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>