developmaunt #5

Merged
DTieman merged 3 commits from developmaunt into mauster 2024-05-25 21:44:25 +00:00
8 changed files with 49 additions and 48 deletions
Showing only changes of commit 4ae1538552 - Show all commits

View File

@@ -1,13 +1,13 @@
import React, {FunctionComponent} from "react"; import React, {FunctionComponent} from "react";
import {NoButton} from "./Button";
interface Props { interface Props {
cardString: string; cardString: string;
handleClick?: (cardString: string) => void; handleClick?: (cardString: string) => void;
isHidden?: boolean; isHidden?: boolean;
isClickable?: boolean;
} }
const Card: FunctionComponent<Props> = ({cardString, handleClick, isHidden, isClickable}) => { const Card: FunctionComponent<Props> = ({cardString, handleClick, isHidden}) => {
const cardType = cardString.split(' ')[0].toLowerCase(); const cardType = cardString.split(' ')[0].toLowerCase();
const cardValue = cardString.split(' ')[1].toLowerCase(); const cardValue = cardString.split(' ')[1].toLowerCase();
@@ -30,9 +30,17 @@ const Card: FunctionComponent<Props> = ({cardString, handleClick, isHidden, isCl
} }
} }
if (handleClick) {
return ( return (
<div className={`card ${isClickable && 'card-clickable'}`}> <NoButton className={"card"} onClick={handleCardClick}>
<img className="card__texture" src={cardSource()} alt={cardName} onClick={handleCardClick}/> <img className="card__texture" src={cardSource()} alt={cardName}/>
</NoButton>
)
}
return (
<div className={"card"}>
<img className="card__texture" src={cardSource()} alt={cardName}/>
</div> </div>
) )
} }

View File

@@ -15,12 +15,10 @@ const Deck: FunctionComponent<Props> = ({currentCard, actionOnClick}) => {
return ( return (
<div className="deck-container"> <div className="deck-container">
<div className="used-cards"> <div className="used-cards">
<p></p>
<Card cardString={currentCard}/> <Card cardString={currentCard}/>
</div> </div>
<div className="deck"> <div className="deck">
<p></p> <Card cardString={"AA BB"} handleClick={handleClick} isHidden/>
<Card cardString={"AA BB"} handleClick={handleClick} isHidden isClickable/>
</div> </div>
</div> </div>
); );

View File

@@ -2,11 +2,11 @@ import React, {FunctionComponent} from "react";
import Deck from "./Deck"; import Deck from "./Deck";
import Hand from "./Hand"; import Hand from "./Hand";
import {GHButton} from "./Button"; import {GHButton} from "./Button";
import {GameAction, Player} from "../pages/Room"; import {Player, SocketMessage} from "../pages/Room";
export interface GameState { export interface GameState {
Me: Player; Me: Player;
CurrentState: string; MyState: string;
Hand: string[]; Hand: string[];
CurrentCard: string; CurrentCard: string;
CurrentPlayer: Player; CurrentPlayer: Player;
@@ -15,7 +15,7 @@ export interface GameState {
interface Props { interface Props {
gameState: GameState gameState: GameState
handleGameAction: (action: GameAction) => void; handleGameAction: (message: SocketMessage) => void;
} }
const CHOICES = ['SPADES', 'HEARTS', 'DIAMONDS', 'CLUBS']; const CHOICES = ['SPADES', 'HEARTS', 'DIAMONDS', 'CLUBS'];
@@ -23,15 +23,15 @@ const CHOICES = ['SPADES', 'HEARTS', 'DIAMONDS', 'CLUBS'];
const Game: FunctionComponent<Props> = ({gameState, handleGameAction}) => { const Game: FunctionComponent<Props> = ({gameState, handleGameAction}) => {
const handleChoice = (choice: string) => { const handleChoice = (choice: string) => {
handleGameAction({Action: 'CHOOSE', Data: choice}); handleGameAction({Type: 'CHOOSE', Data: choice});
} }
const handleDraw = () => { const handleDraw = () => {
handleGameAction({Action: 'DRAW', Data: ""}); handleGameAction({Type: 'DRAW', Data: ""});
} }
const handleCardSend = (cardString: string) => { const handleCardSend = (cardString: string) => {
handleGameAction({Action: "PLAYCARD", Data: JSON.stringify({ handleGameAction({Type: "PLAY", Data: JSON.stringify({
CardType: cardString.split(' ')[0], CardType: cardString.split(' ')[0],
CardValue: cardString.split(' ')[1] CardValue: cardString.split(' ')[1]
})}) })})
@@ -70,7 +70,7 @@ const Game: FunctionComponent<Props> = ({gameState, handleGameAction}) => {
<Hand hand={gameState.Hand} actionOnClick={handleCardSend}/> <Hand hand={gameState.Hand} actionOnClick={handleCardSend}/>
} }
{ {
gameState.CurrentState === 'CHOOSE' && gameState.MyState === 'CHOOSE' &&
CHOICES.map(choice => <GHButton key={choice} onClick={() => handleChoice(choice)}>{choice}</GHButton>) CHOICES.map(choice => <GHButton key={choice} onClick={() => handleChoice(choice)}>{choice}</GHButton>)
} }
</div> </div>

View File

@@ -3,25 +3,24 @@ import Card from "./Card";
interface Props { interface Props {
hand: string[]; hand: string[];
actionOnClick: (cardString: string) => void; actionOnClick?: (cardString: string) => void;
isHidden?: boolean; isHidden?: boolean;
} }
const Hand: FunctionComponent<Props> = ({hand, actionOnClick, isHidden}) => { const Hand: FunctionComponent<Props> = ({hand, actionOnClick, isHidden}) => {
const isMyHand = !isHidden;
return ( return (
<div className="hand"> <ul className="hand">
{ {
hand.map((card, index) => { hand.map((card, index) => {
return ( return (
<Card key={index} cardString={card} handleClick={actionOnClick} isHidden={!isMyHand} <li key={card} className={"hand__item"}>
isClickable={isMyHand}/> <Card cardString={card} handleClick={actionOnClick} isHidden={isHidden}/>
</li>
) )
}) })
} }
</div> </ul>
) )
} }

View File

@@ -37,11 +37,11 @@ const MainLobby = () => {
<div className={"main-lobby__container"}> <div className={"main-lobby__container"}>
<NoButton className={"main-lobby__container-button"} onClick={handleCreateRoom}> <NoButton className={"main-lobby__container-button"} onClick={handleCreateRoom}>
<h2 className={"mau"}>Host Game</h2> <h2 className={"mau"}>Host Game</h2>
<Card cardString={'SPADES ACE'} isClickable/> <Card cardString={'SPADES ACE'}/>
</NoButton> </NoButton>
<NoButton className={"main-lobby__container-button"} onClick={() => navigateTo('/rooms')}> <NoButton className={"main-lobby__container-button"} onClick={() => navigateTo('/rooms')}>
<h2 className={"mau"}>Join Game</h2> <h2 className={"mau"}>Join Game</h2>
<Card cardString={'SPADES ACE'} isHidden isClickable/> <Card cardString={'SPADES ACE'} isHidden/>
</NoButton> </NoButton>
</div> </div>
</div> </div>

View File

@@ -13,14 +13,13 @@ export interface Player {
CardsLeft: number; CardsLeft: number;
} }
interface SocketMessage { export interface SocketMessage {
Type: string; Type: string;
Payload: any; Data: string;
} }
export interface GameAction { interface JoinLeaveMessage {
Action: string; ChatMessage: string;
Data: string;
} }
const Room = () => { const Room = () => {
@@ -35,7 +34,6 @@ const Room = () => {
const WS_URL = `${process.env.REACT_APP_WEBSOCKET_URL}/room/${roomId}/${playerName}`; const WS_URL = `${process.env.REACT_APP_WEBSOCKET_URL}/room/${roomId}/${playerName}`;
const [gameState, setGameState] = React.useState<GameState | undefined>(undefined); const [gameState, setGameState] = React.useState<GameState | undefined>(undefined);
const [lobbyState, setLobbyState] = React.useState<string>("");
const [winner, setWinner] = React.useState<string | undefined>(undefined); const [winner, setWinner] = React.useState<string | undefined>(undefined);
const chatRef = React.useRef<HTMLOListElement>(null); const chatRef = React.useRef<HTMLOListElement>(null);
@@ -59,15 +57,11 @@ const Room = () => {
onOpen: () => { onOpen: () => {
console.log('WebSocket connection established.'); console.log('WebSocket connection established.');
}, },
onMessage: (event) => { onMessage: (messageEvent) => {
const data = JSON.parse(event.data); const data: SocketMessage = JSON.parse(messageEvent.data);
const payload = JSON.parse(data.Payload); const payload = JSON.parse(data.Data);
switch (data.Type) { switch (data.Type) {
case 'LOBBY':
setLobbyState(data.Type);
break;
case 'GAME': case 'GAME':
setLobbyState(data.Type);
setGameState(payload); setGameState(payload);
break; break;
case 'CHAT': case 'CHAT':
@@ -77,6 +71,12 @@ const Room = () => {
setWinner(payload.Name) setWinner(payload.Name)
setGameState(undefined); setGameState(undefined);
break; break;
case "JOIN":
addChatMessage({Sender: "System", Message: (JSON.parse(data.Data) as JoinLeaveMessage).ChatMessage});
break;
case "LEAVE":
addChatMessage({Sender: "System", Message: (JSON.parse(data.Data) as JoinLeaveMessage).ChatMessage});
break;
default: default:
console.log('Unknown message type:', data.Type); console.log('Unknown message type:', data.Type);
} }
@@ -91,18 +91,14 @@ const Room = () => {
websocket.sendMessage(JSON.stringify(message)); websocket.sendMessage(JSON.stringify(message));
} }
const handleGameAction = (action: GameAction) => {
handleSend({Type: "GAME", Payload: JSON.stringify(action)});
}
const handleLobbyAction = (action: string) => { const handleLobbyAction = (action: string) => {
handleSend({Type: "LOBBY", Payload: JSON.stringify(action)}); handleSend({Type: "LOBBY", Data: JSON.stringify(action)});
} }
const handleChatMessage = (chatMessage: string) => { const handleChatMessage = (chatMessage: string) => {
handleSend({ handleSend({
Type: "CHAT", Type: "CHAT",
Payload: chatMessage Data: chatMessage
}); });
} }
@@ -130,8 +126,8 @@ const Room = () => {
<main className={"room-main"}> <main className={"room-main"}>
{ {
gameState ? gameState ?
<Game gameState={gameState} handleGameAction={handleGameAction}/> <Game gameState={gameState} handleGameAction={handleSend}/>
: lobbyState === 'LOBBY' && :
<Lobby winner={winner} handleLobbyAction={handleLobbyAction}/> <Lobby winner={winner} handleLobbyAction={handleLobbyAction}/>
} }
</main> </main>

View File

@@ -2,10 +2,6 @@
width: 100px; width: 100px;
min-width: 100px; min-width: 100px;
&-clickable {
cursor: pointer;
}
&__texture { &__texture {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@@ -5,4 +5,8 @@
overflow-x: scroll; overflow-x: scroll;
padding: 0.5rem; padding: 0.5rem;
gap: 0.5rem; gap: 0.5rem;
&__item {
list-style: none;
}
} }