diff --git a/src/pages/games/SnackGame/game/SnackGameBase.tsx b/src/pages/games/SnackGame/game/SnackGameBase.tsx index 01a8bbfc..4aab0186 100644 --- a/src/pages/games/SnackGame/game/SnackGameBase.tsx +++ b/src/pages/games/SnackGame/game/SnackGameBase.tsx @@ -135,7 +135,7 @@ const SnackGameBase = ({ replaceErrorHandler }: Props) => { const handleStreak = async (streak: StreakWithMeta, isGolden: boolean) => { cumulativeStreaks = [...cumulativeStreaks, streak]; - if (isGolden || streak.isFever) { + if (isGolden) { session = await handleStreaksMove(); } return session!; diff --git a/src/pages/games/SnackGame/game/popup/PausePopup.ts b/src/pages/games/SnackGame/game/popup/PausePopup.ts index f1d3fb53..fd32d137 100644 --- a/src/pages/games/SnackGame/game/popup/PausePopup.ts +++ b/src/pages/games/SnackGame/game/popup/PausePopup.ts @@ -41,6 +41,7 @@ export class PausePopup extends BasePopup { try { this.setButtonsEnabled(false); await this.handleGameEnd(); + this.setButtonsEnabled(true); } catch (error) { this.app.setError(error); } @@ -50,6 +51,7 @@ export class PausePopup extends BasePopup { try { this.setButtonsEnabled(false); await this.handleGameResume(); + this.setButtonsEnabled(true); this.app.dismissPopup(); } catch (error) { this.app.setError(error); diff --git a/src/pages/games/SnackGame/game/screen/BizGameScreen.ts b/src/pages/games/SnackGame/game/screen/BizGameScreen.ts index a95a7f28..e16f96e4 100644 --- a/src/pages/games/SnackGame/game/screen/BizGameScreen.ts +++ b/src/pages/games/SnackGame/game/screen/BizGameScreen.ts @@ -17,6 +17,7 @@ import { SNACK_TYPE, SnackGameMode, Streak, + StreakWithMeta, snackGameGetConfig, } from '../snackGame/SnackGameUtil'; import { BeforeGameStart } from '../ui/BeforeGameStart'; @@ -55,7 +56,7 @@ export class BizGameScreen extends Container implements AppScreen { private app: SnackgameApplication, private getCurrentMode: () => SnackGameMode, private handleStreak: ( - streak: Streak, + streak: StreakWithMeta, isGolden: boolean, ) => Promise, private handleGameStart: () => Promise, @@ -94,6 +95,7 @@ export class BizGameScreen extends Container implements AppScreen { this.snackGame.onPop = this.onPop.bind(this); this.snackGame.onStreak = (data: Snack[]) => { let isGolden = false; + const occurredAt = new Date().toISOString(); const streak = data.reduce((acc: Streak, snack) => { if (snack.type === SNACK_TYPE.GOLDEN) isGolden = true; @@ -103,7 +105,10 @@ export class BizGameScreen extends Container implements AppScreen { return acc; }, []); - return this.handleStreak(streak, isGolden); + return this.handleStreak( + { coordinates: streak, isFever: false, occurredAt }, + isGolden, + ); }; this.snackGame.onSnackGameBoardReset = this.onSnackGameBoardReset.bind(this); diff --git a/src/pages/games/SnackGame/game/screen/GameScreen.ts b/src/pages/games/SnackGame/game/screen/GameScreen.ts index 510777bd..323a436b 100644 --- a/src/pages/games/SnackGame/game/screen/GameScreen.ts +++ b/src/pages/games/SnackGame/game/screen/GameScreen.ts @@ -2,7 +2,7 @@ import gsap from 'gsap'; import { Container, Rectangle, Ticker } from 'pixi.js'; import { ItemBar } from '@pages/games/SnackGame/game/ui/ItemBar'; -import { ItemResponse } from '@utils/types/item.type'; +import { ItemResponse, ItemType } from '@utils/types/item.type'; import { AppScreen, AppScreenConstructor } from './appScreen'; import { SnackgameApplication } from './SnackgameApplication'; @@ -114,15 +114,15 @@ export class GameScreen extends Container implements AppScreen { ); }; this.snackGame.onBomb = (position: SnackGamePosition, data: Snack[]) => { - this.snackGame.setSelectedItem(null); - this.itemBar.setItemsLocked(false); let isGolden = false; data.forEach((snack) => { if (snack.type === SNACK_TYPE.GOLDEN) isGolden = true; }); - return this.itemHandlers.bomb(position, isGolden); + const result = this.itemHandlers.bomb(position, isGolden); + this.releaseItem(); + return result; }; this.snackGame.onSnackGameBoardReset = this.onSnackGameBoardReset.bind(this); @@ -149,11 +149,12 @@ export class GameScreen extends Container implements AppScreen { return { ...item, onUse: async (type) => { - this.snackGame.setSelectedItem(type); + this.selectItem(type); + if (type === 'FEVER_TIME') { await this.itemHandlers.fever(); this.feverTimer.start(30, () => { - this.snackGame.setSelectedItem(null); + this.releaseItem(); }); } }, @@ -185,7 +186,7 @@ export class GameScreen extends Container implements AppScreen { gsap.killTweensOf(this.timer.scale); } - /** 화면 업테이트, 하위 컴포넌트의 update함수를 모두 실행합니다. */ + /** 화면 업데이트, 하위 컴포넌트의 update함수를 모두 실행합니다. */ public update(time: Ticker) { this.snackGame.update(time.deltaMS); this.timer.updateTime(this.snackGame.timer.getTimeRemaining()); @@ -193,6 +194,18 @@ export class GameScreen extends Container implements AppScreen { this.score.setScore(this.snackGame.stats.getScore()); } + /** 아이템 선택 */ + private selectItem(type: ItemType) { + this.snackGame.setSelectedItem(type); + this.itemBar.setItemsLocked(true); + } + + /** 아이템 선택 해제 */ + private releaseItem() { + this.snackGame.setSelectedItem(null); + this.itemBar.setItemsLocked(false); + } + private onSnackGameBoardReset() { for (const snack of this.snackGame.board.snacks) { this.vfx?.animationBeforeStart(snack); diff --git a/src/pages/games/SnackgameBiz/SnackGameBizBase.tsx b/src/pages/games/SnackgameBiz/SnackGameBizBase.tsx index ff14a17e..027489df 100644 --- a/src/pages/games/SnackgameBiz/SnackGameBizBase.tsx +++ b/src/pages/games/SnackgameBiz/SnackGameBizBase.tsx @@ -16,7 +16,7 @@ import { LobbyScreen } from '../SnackGame/game/screen/LobbyScreen'; import { SnackgameApplication } from '../SnackGame/game/screen/SnackgameApplication'; import { SnackGameMode, - Streak, + StreakWithMeta, } from '../SnackGame/game/snackGame/SnackGameUtil'; type Props = { @@ -68,7 +68,7 @@ const SnackGameBizBase = ({ replaceErrorHandler }: Props) => { // 게임 진행 관련 functions let session: SnackGameBizDefaultResponse | undefined; let sessionMode: SnackGameMode | undefined; - let cumulativeStreaks: Streak[] = []; + let cumulativeStreaks: StreakWithMeta[] = []; const handleGameStart = async () => { session = await gameApi.start(); @@ -85,7 +85,7 @@ const SnackGameBizBase = ({ replaceErrorHandler }: Props) => { }; // TODO: 지금은 인자로 숫자를 사용하지만, '스트릭' VO를 만들어 사용하면 더 좋겠네요. - const handleStreak = async (streak: Streak, isGolden: boolean) => { + const handleStreak = async (streak: StreakWithMeta, isGolden: boolean) => { cumulativeStreaks = [...cumulativeStreaks, streak]; if (isGolden) { diff --git a/src/pages/games/SnackgameBiz/util/api.ts b/src/pages/games/SnackgameBiz/util/api.ts index ec0001e5..21d71975 100644 --- a/src/pages/games/SnackgameBiz/util/api.ts +++ b/src/pages/games/SnackgameBiz/util/api.ts @@ -1,6 +1,6 @@ import axios from 'axios'; -import { Streak } from '@pages/games/SnackGame/game/snackGame/SnackGameUtil'; +import { StreakWithMeta } from '@pages/games/SnackGame/game/snackGame/SnackGameUtil'; import { SnackGameBizDefaultResponse, @@ -39,7 +39,7 @@ export const createGameApiClient = () => { }, verifyStreaks: async ( sessionId: number, - streaks: Streak[], + streaks: StreakWithMeta[], ): Promise => { const { data } = await api.post( `/games/${GAME_ID}/${sessionId}/streaks`,