types for client/server interaction
This commit is contained in:
@@ -6,37 +6,48 @@ import { socket } from "@/socket";
|
||||
|
||||
import Card from '@/components/Card';
|
||||
|
||||
import type { GameCard } from '@/types';
|
||||
import type { GameCard, GameUpdate, ClientUpdate } from '@/types';
|
||||
|
||||
export default function GamePage() {
|
||||
const { gameID } = useParams();
|
||||
const { gameID: gameIDParam } = useParams();
|
||||
|
||||
const [gameID, setGameID] = useState('');
|
||||
const [cards, setCards] = useState<GameCard[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (gameIDParam) {
|
||||
setGameID(Array.isArray(gameIDParam) ? gameIDParam[0] : gameIDParam);
|
||||
}
|
||||
}, [gameIDParam])
|
||||
|
||||
useEffect(() => {
|
||||
if (gameID) {
|
||||
socket.emit('join', gameID);
|
||||
|
||||
socket.on('init', data => {
|
||||
socket.on('init', (data: GameUpdate) => {
|
||||
console.log('init', data);
|
||||
setCards(data.cards);
|
||||
});
|
||||
|
||||
socket.on('card-flipped', (data) => {
|
||||
socket.on('card-flipped', (data: GameUpdate) => {
|
||||
console.log('>>>', data);
|
||||
setCards(data.cards);
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
return gameID ? () => {
|
||||
socket.off('init');
|
||||
socket.off('card-flipped');
|
||||
};
|
||||
}, []);
|
||||
} : undefined;
|
||||
}, [gameID]);
|
||||
|
||||
const flipCard = (cardID: string) => {
|
||||
socket.emit('flip-card', {
|
||||
cardID,
|
||||
const flip: ClientUpdate = {
|
||||
gameID,
|
||||
});
|
||||
cardID,
|
||||
};
|
||||
|
||||
socket.emit('flip-card', flip);
|
||||
};
|
||||
|
||||
return cards.length ? (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Cards from './Cards'
|
||||
|
||||
import { GameState } from '../types'
|
||||
import { GameState, GameUpdate } from '../types'
|
||||
|
||||
const deck = new Cards();
|
||||
|
||||
@@ -26,13 +26,13 @@ export default class GameStore {
|
||||
return newGame;
|
||||
}
|
||||
|
||||
joinGame(gameID: string, playerID: string): GameState {
|
||||
joinGame(gameID: string, playerID: string): GameUpdate {
|
||||
const game = this.games.get(gameID) || this.createGame(gameID);
|
||||
|
||||
game.players.add(playerID);
|
||||
game.lastUpdated = Date.now();
|
||||
|
||||
return game;
|
||||
return this.gameUpdate(game);
|
||||
}
|
||||
|
||||
leaveGame(gameID: string, playerID: string): GameState {
|
||||
@@ -44,7 +44,7 @@ export default class GameStore {
|
||||
return game;
|
||||
}
|
||||
|
||||
flipCard(gameID: string, cardID: string): GameState {
|
||||
flipCard(gameID: string, cardID: string): GameUpdate {
|
||||
const game = this.getGame(gameID);
|
||||
const card = game.cards.find(c => c.id === cardID);
|
||||
|
||||
@@ -53,7 +53,7 @@ export default class GameStore {
|
||||
card.flipped = !card.flipped;
|
||||
game.lastUpdated = Date.now();
|
||||
|
||||
return game;
|
||||
return this.gameUpdate(game);
|
||||
}
|
||||
|
||||
getGame(gameID: string): GameState {
|
||||
@@ -64,6 +64,11 @@ export default class GameStore {
|
||||
return game;
|
||||
}
|
||||
|
||||
gameUpdate(game: GameState): GameUpdate {
|
||||
const { id, cards } = game;
|
||||
return { id, cards };
|
||||
}
|
||||
|
||||
deleteGame(gameID: string): void {
|
||||
this.games.delete(gameID);
|
||||
}
|
||||
|
||||
13
server.ts
13
server.ts
@@ -3,6 +3,7 @@ import { createServer } from 'http';
|
||||
import { Server as SocketIOServer, type Socket } from 'socket.io';
|
||||
|
||||
import GameStore from './lib/GameStore';
|
||||
import type { ClientUpdate } from './types';
|
||||
|
||||
const dev = process.env.NODE_ENV !== 'production';
|
||||
const hostname = 'localhost';
|
||||
@@ -24,17 +25,19 @@ app.prepare().then(() => {
|
||||
|
||||
socket.on('join', (gameID) => {
|
||||
socket.join(gameID);
|
||||
const game = gameStore.joinGame(gameID, socket.id);
|
||||
const gameUpdate = gameStore.joinGame(gameID, socket.id);
|
||||
|
||||
console.log(`Socket ${socket.id} joined game ${gameID}`)
|
||||
|
||||
socket.emit('init', { cards: game.cards });
|
||||
socket.emit('init', gameUpdate);
|
||||
})
|
||||
|
||||
socket.on('flip-card', ({ gameID, cardID }) => {
|
||||
socket.on('flip-card', ({ gameID, cardID }: ClientUpdate) => {
|
||||
console.log('Card flipped:', { gameID, cardID });
|
||||
const game = gameStore.flipCard(gameID, cardID);
|
||||
io.to(gameID).emit('card-flipped', { gameID, cards: game.cards });
|
||||
|
||||
const gameUpdate = gameStore.flipCard(gameID, cardID);
|
||||
|
||||
io.to(gameID).emit('card-flipped', gameUpdate);
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"target": "ES2020",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
|
||||
@@ -17,3 +17,13 @@ export interface GameState {
|
||||
cards: GameCard[];
|
||||
lastUpdated: number;
|
||||
}
|
||||
|
||||
export interface GameUpdate {
|
||||
id: string;
|
||||
cards: GameCard[];
|
||||
}
|
||||
|
||||
export interface ClientUpdate {
|
||||
gameID: string;
|
||||
cardID: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user