From 98bfb742044b63a355b99d30a4a27d00372c550a Mon Sep 17 00:00:00 2001 From: yongsik Date: Thu, 8 Jan 2026 15:22:24 +0900 Subject: [PATCH] (fix) update RSP --- src/components/RpsGame.tsx | 163 +++++++++++++++++++----------------- src/pages/EventMainPage.tsx | 18 ++-- 2 files changed, 94 insertions(+), 87 deletions(-) diff --git a/src/components/RpsGame.tsx b/src/components/RpsGame.tsx index bb19139..2e7543c 100644 --- a/src/components/RpsGame.tsx +++ b/src/components/RpsGame.tsx @@ -25,50 +25,48 @@ export default function RpsGame({ }: Props) { const [client, setClient] = useState(null); - const [started, setStarted] = useState(false); - const [leader, setLeader] = useState(null); - const [players, setPlayers] = useState([]); - const [gameId, setGameId] = useState(null); + const [started, setStarted] = useState(false); + const [leader, setLeader] = useState(null); + const [players, setPlayers] = useState([]); + const [gameId, setGameId] = useState(null); - const [myChoice, setMyChoice] = useState(null); - const [isAlive, setIsAlive] = useState(true); + const [myChoice, setMyChoice] = useState(null); + const [isAlive, setIsAlive] = useState(true); /* =========================== WebSocket 연결 =========================== */ useEffect(() => { const socket = new SockJS(`${apiUrl}/ws`); - const stomp = Stomp.over(socket); - - stomp.connect({}, () => { - // 게임 시작 (목록용) - stomp.subscribe(`/sub/game/${eventId}/start`, (msg) => { - const data: StartGameDto = JSON.parse(msg.body); - - setStarted(true); - setLeader(data.leader); - setPlayers(data.players); - setGameId(null); - setMyChoice(null); - setIsAlive(true); - }); - - // 라운드 결과 - stomp.subscribe(`/sub/game/${eventId}/round`, (msg) => { - const data: GamePlayDto = JSON.parse(msg.body); - - setLeader(data.leader); - setPlayers(data.players); - setGameId(data.gameId); - - const me = data.players.find( - (p) => p.memberId === myMemberId - ); - setIsAlive(!!me); - }); + const stomp = Stomp.over(socket); + + stomp.connect({}, () => { + // 게임 시작 결과 + stomp.subscribe(`/sub/game/${eventId}/start`, (msg) => { + const data: StartGameDto = JSON.parse(msg.body); + + setStarted(true); + setLeader(data.leader); + setPlayers(data.players); + setGameId(null); + setMyChoice(null); + setIsAlive(true); }); - setClient(stomp); + // 라운드 결과 + stomp.subscribe(`/sub/game/${eventId}/round`, (msg) => { + const data: GamePlayDto = JSON.parse(msg.body); + + setLeader(data.leader); + setPlayers(data.players); + setGameId(data.gameId); + + const me = data.players.find( + (p) => p.memberId === myMemberId + ); + setIsAlive(!!me); + }); + }); return () => { if (client) { try { @@ -83,34 +81,46 @@ export default function RpsGame({ /* =========================== 선택 전송 =========================== */ - const play = (type: RPSType) => { - if (!client || !gameId) return; - - setMyChoice(type); - - client.send( - `/pub/game/${eventId}/play`, - {}, - JSON.stringify({ - memberId: myMemberId, - nickname: myNickname, - type, - }) - ); - }; + const play = async (type: RPSType) => { + if (!isAlive) return; + + setMyChoice(type); + + await fetch(`${apiUrl}/api/v1/game/rsp/round`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + leader: { + ...leader, + type: leader?.memberId === myMemberId ? type : leader?.type, + }, + players: players.map((p) => + p.memberId === myMemberId ? { ...p, type } : p + ), + gameId, + eventId, + }), + }); +}; /* =========================== 게임 시작 (사회자) =========================== */ - const startGame = () => { - if (!client) return; - - client.send( - `/pub/game/${eventId}/start`, - {}, - JSON.stringify({ eventId }) - ); - }; + const startGame = async (winnerCnt: number) => { + await fetch(`${apiUrl}/api/v1/game/rsp/start`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + eventId, + winnerCnt, + leader: { + memberId: myMemberId, + nickname: myNickname, + }, + players, // 이미 알고 있거나 서버에서 채워도 됨 + }), + }); +}; /* =========================== UI @@ -120,10 +130,13 @@ export default function RpsGame({

✊✌️✋ 가위바위보

{!started && ( - - 가위바위보 시작 - - )} + startGame(1)} // winnerCnt + > + 가위바위보 시작 + + )} {started && ( <> @@ -142,20 +155,20 @@ export default function RpsGame({ )} - {/* 선택 UI */} - {gameId && isAlive && ( -
- - - -
- )} + {/* ② 생존자만 선택 */} + {started && gameId && isAlive && ( +
+ + + +
+ )} - {!isAlive && gameId && ( -

- ❌ 탈락 + {started && gameId && !isAlive && ( +

+ ❌ 탈락

- )} + )} ); } diff --git a/src/pages/EventMainPage.tsx b/src/pages/EventMainPage.tsx index 484a9bb..f3b47ed 100644 --- a/src/pages/EventMainPage.tsx +++ b/src/pages/EventMainPage.tsx @@ -1009,6 +1009,12 @@ export default function EventMainPage() { > {cannonLoading ? "대포 중..." : "대포쏘기"} +