Created "sign-up" form
This commit is contained in:
parent
d6a49dee6a
commit
dd21f82734
24
pac-man-board-game/ClientApp/src/components/dropdown.tsx
Normal file
24
pac-man-board-game/ClientApp/src/components/dropdown.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import React, {forwardRef, ReactEventHandler} from "react";
|
||||
|
||||
export interface DropdownProps extends ComponentProps {
|
||||
options?: string[],
|
||||
onSelect?: ReactEventHandler<HTMLSelectElement>,
|
||||
}
|
||||
|
||||
const Dropdown: FRComponent<DropdownProps, HTMLSelectElement> = forwardRef((
|
||||
{
|
||||
className,
|
||||
options,
|
||||
onSelect
|
||||
}, ref) => (
|
||||
<select ref={ref} className={"border-2 border-gray-300 rounded-md py-1 px-2 bg-white " + className}
|
||||
onSelect={onSelect}>
|
||||
{
|
||||
options?.map((option, index) => (
|
||||
<option key={index}>{option}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
));
|
||||
|
||||
export default Dropdown;
|
@ -7,12 +7,13 @@ import WebSocketService from "../websockets/WebSocketService";
|
||||
import {testMap} from "../game/map";
|
||||
import {TileType} from "../game/tileType";
|
||||
import Player, {State} from "../game/player";
|
||||
import {Colour} from "../game/colour";
|
||||
|
||||
const wsService = new WebSocketService(import.meta.env.VITE_API);
|
||||
|
||||
const ghosts = [
|
||||
new Ghost({Colour: "purple"}),
|
||||
new Ghost({Colour: "purple"})
|
||||
new Ghost({Colour: Colour.Purple}),
|
||||
new Ghost({Colour: Colour.Purple}),
|
||||
];
|
||||
|
||||
export const GameComponent: Component<{ player: Player }> = (
|
||||
@ -65,6 +66,14 @@ export const GameComponent: Component<{ player: Player }> = (
|
||||
// TODO find spawn points
|
||||
setCharacters([...pacMen, ...ghosts]);
|
||||
break;
|
||||
case GameAction.ready:
|
||||
const isReady = parsed.Data.AllReady as boolean;
|
||||
if (isReady) {
|
||||
setCurrentPlayer(parsed.Data.Starter as Player);
|
||||
} else {
|
||||
// TODO update player states
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,8 +133,7 @@ export const GameComponent: Component<{ player: Player }> = (
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className={"w-fit mx-auto"}>Pac-Man The Board Game</h1>
|
||||
<>
|
||||
<div className={"flex-center"}>
|
||||
{
|
||||
player.State === State.waitingForPlayers ?
|
||||
@ -136,6 +144,7 @@ export const GameComponent: Component<{ player: Player }> = (
|
||||
<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>
|
||||
@ -148,6 +157,6 @@ export const GameComponent: Component<{ player: Player }> = (
|
||||
selectedDice={selectedDice}
|
||||
onMove={onCharacterMove} map={testMap}/>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
19
pac-man-board-game/ClientApp/src/components/input.tsx
Normal file
19
pac-man-board-game/ClientApp/src/components/input.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import React, {forwardRef} from "react";
|
||||
|
||||
const Input: FRComponent<InputProps, HTMLInputElement> = forwardRef((
|
||||
{
|
||||
type = "text",
|
||||
className,
|
||||
id,
|
||||
placeholder,
|
||||
required = false,
|
||||
}, ref) => (
|
||||
<input type={type}
|
||||
ref={ref}
|
||||
id={id}
|
||||
className={"border-2 border-gray-300 rounded-md p-1 " + className}
|
||||
placeholder={placeholder}
|
||||
required={required}/>
|
||||
));
|
||||
|
||||
export default Input;
|
@ -1,4 +1,5 @@
|
||||
import Pellet from "./pellet";
|
||||
import {Colour} from "./colour";
|
||||
|
||||
export default class Box {
|
||||
public Pellets: Pellet[];
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {Direction} from "./direction";
|
||||
import {Colour} from "./colour";
|
||||
|
||||
export enum CharacterType {
|
||||
pacMan,
|
||||
@ -79,7 +80,7 @@ export class Dummy extends Character {
|
||||
|
||||
public constructor(position: Path) { // TODO see-through
|
||||
super({
|
||||
Colour: "grey",
|
||||
Colour: Colour.Grey,
|
||||
Position: position,
|
||||
IsEatable: false,
|
||||
SpawnPosition: {At: {x: 0, y: 0}, Direction: Direction.up},
|
||||
|
11
pac-man-board-game/ClientApp/src/game/colour.ts
Normal file
11
pac-man-board-game/ClientApp/src/game/colour.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export enum Colour {
|
||||
White = "white",
|
||||
Red = "red",
|
||||
Blue = "blue",
|
||||
Yellow = "yellow",
|
||||
Green = "green",
|
||||
Purple = "purple",
|
||||
Grey = "grey",
|
||||
}
|
||||
|
||||
export const getColours = (): Colour[] => Object.values(Colour);
|
@ -1,5 +1,6 @@
|
||||
import {Character, CharacterType} from "./character";
|
||||
import Box from "./box";
|
||||
import {Colour} from "./colour";
|
||||
|
||||
export enum State {
|
||||
waitingForPlayers,
|
||||
|
28
pac-man-board-game/ClientApp/src/game/playerStats.tsx
Normal file
28
pac-man-board-game/ClientApp/src/game/playerStats.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
import Player, {State} from "./player";
|
||||
|
||||
export interface PlayerStatsProps extends ComponentProps {
|
||||
player: Player,
|
||||
isCurrentPlayer?: boolean,
|
||||
}
|
||||
|
||||
const PlayerStats: Component<PlayerStatsProps> = (
|
||||
{
|
||||
player,
|
||||
isCurrentPlayer = false,
|
||||
className,
|
||||
id
|
||||
}) => (
|
||||
<div key={player.Colour} className={`mx-auto w-fit m-2 ${className}`} id={id}>
|
||||
<p className={isCurrentPlayer ? "underline" : ""}>Player: {player.Name}</p>
|
||||
{player.State === State.inGame ?
|
||||
<>
|
||||
<p>Pellets: {player.Box.count}</p>
|
||||
<p>PowerPellets: {player.Box.countPowerPellets}</p>
|
||||
</> :
|
||||
<p>{player.State === State.waitingForPlayers ? "Waiting" : "Ready"}</p>}
|
||||
|
||||
</div>
|
||||
);
|
||||
|
||||
export default PlayerStats;
|
@ -19,6 +19,10 @@ h1 {
|
||||
@apply text-4xl;
|
||||
}
|
||||
|
||||
button {
|
||||
br {
|
||||
@apply my-2;
|
||||
}
|
||||
|
||||
button, button[type=submit], input[type=button], input[type=submit] {
|
||||
@apply bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded;
|
||||
}
|
||||
|
@ -1,14 +1,44 @@
|
||||
import React from "react";
|
||||
import React, {FormEvent, useRef, useState} from "react";
|
||||
import {GameComponent} from "../components/gameComponent";
|
||||
import Player from "../game/player";
|
||||
import Input from "../components/input";
|
||||
import Dropdown from "../components/dropdown";
|
||||
import {Colour, getColours} from "../game/colour";
|
||||
|
||||
const Home: Component = () => (
|
||||
<div>
|
||||
<GameComponent player={new Player({
|
||||
Name: "Martin",
|
||||
Colour: "yellow",
|
||||
})}/>
|
||||
</div>
|
||||
);
|
||||
const Home: Component = () => {
|
||||
|
||||
const [player, setPlayer] = useState<Player>();
|
||||
const input = useRef<HTMLInputElement>(null);
|
||||
const dropdown = useRef<HTMLSelectElement>(null);
|
||||
|
||||
function formHandler(e: FormEvent): void {
|
||||
e.preventDefault();
|
||||
if (!input.current || !dropdown.current) return;
|
||||
setPlayer(new Player({
|
||||
Name: input.current.value,
|
||||
Colour: dropdown.current.value as Colour,
|
||||
}));
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className={"w-fit mx-auto"}>Pac-Man The Board Game</h1>
|
||||
{
|
||||
player ?
|
||||
/*TODO move to own page*/
|
||||
<GameComponent player={player}/>
|
||||
:
|
||||
<form className={"flex flex-col items-center"} onSubmit={formHandler}>
|
||||
<p>Enter your name:</p>
|
||||
<Input ref={input} required/>
|
||||
<p>Choose a colour:</p>
|
||||
<Dropdown ref={dropdown} options={getColours()}/>
|
||||
<br/>
|
||||
<button type={"submit"}>Find game</button>
|
||||
</form>
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
@ -1,5 +1,7 @@
|
||||
type Component<T = ComponentProps> = (props: T) => React.JSX.Element | null;
|
||||
|
||||
type FRComponent<T = ComponentProps, HTML extends HTMLElement = HTMLElement> = React.ForwardRefExoticComponent<React.PropsWithoutRef<T> & React.RefAttributes<HTML>>;
|
||||
|
||||
interface ComponentProps {
|
||||
className?: string,
|
||||
style?: React.CSSProperties,
|
||||
@ -11,8 +13,14 @@ interface ChildProps extends ComponentProps {
|
||||
children?: React.JSX.Element,
|
||||
}
|
||||
|
||||
interface InputProps extends ComponentProps {
|
||||
type?: string,
|
||||
placeholder?: string,
|
||||
required?: boolean,
|
||||
}
|
||||
|
||||
interface CharacterProps {
|
||||
Colour: Colour,
|
||||
Colour: import("../game/colour").Colour,
|
||||
Position?: Path | null,
|
||||
IsEatable?: boolean,
|
||||
SpawnPosition?: DirectionalPosition | null,
|
||||
@ -21,13 +29,13 @@ interface CharacterProps {
|
||||
|
||||
interface BoxProps {
|
||||
pellets?: import("../game/pellet").default[],
|
||||
readonly colour: Colour,
|
||||
readonly colour: import("../game/colour").Colour,
|
||||
}
|
||||
|
||||
interface PlayerProps {
|
||||
readonly Name: string,
|
||||
readonly PacMan?: CharacterProps,
|
||||
readonly Colour: Colour,
|
||||
readonly Colour: import("../game/colour").Colour,
|
||||
readonly Box?: BoxProps,
|
||||
State?: import("../game/player").State,
|
||||
}
|
||||
|
@ -34,5 +34,3 @@ type Path = {
|
||||
End: Position,
|
||||
Direction: import("../game/direction").Direction
|
||||
}
|
||||
|
||||
type Colour = "white" | "red" | "blue" | "yellow" | "green" | "purple" | "grey";
|
||||
|
Loading…
x
Reference in New Issue
Block a user