Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hotfix] 레이싱 게임 스페이스 컨트롤을 useKeyBoardControl 커스텀 훅으로 리팩토링 후 게임 플레이 시간을 랜덤으로 작동하게 수정 #71

Merged
merged 10 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified Caecae/public/assets/audio/racingGamePlayingSound.wav
Binary file not shown.
4 changes: 2 additions & 2 deletions Caecae/public/assets/eventPeriodBackground.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 23 additions & 28 deletions Caecae/src/components/RacingGame/RacingGame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import { getRacingGameTopRateStory } from "../../stories/RacingGame/getRacingGam
import { useAudio } from "../../hooks/index.tsx";
import useSaga from "../../shared/Hyundux-saga/useSaga.tsx";
import getRacingGameShortUrl, { getRacingGameShortUrlBodyParameter } from "../../stories/RacingGame/getRacingGameShortUrl.tsx";
import useKeyBoardControl from "../../hooks/useKeyBoardControl.tsx";

const RacingGame: React.FC = () => {
const lottieRef = useRef<LottieRefCurrentProps | null>(null);
const frontRef = useRef<HTMLDivElement>(null);
const rearRef = useRef<HTMLDivElement>(null);
const durationRef = useRef<number>(7);
const [frontBackgroundWidth, setFrontImageWidth] = useState<number>(0);
const [rearBackgroundWidth, setRearBackgroundWidth] = useState<number>(0);
const state = useExistState(initRacingGameState);
Expand Down Expand Up @@ -46,15 +48,20 @@ const RacingGame: React.FC = () => {
const { playAudio: stopingMusicPlay, resetAudio: stopingMusicReset } =
useAudio("/assets/audio/racingGameStopSound.wav");

/* 5~10초 중 랜덤 */
const getRandomDuration = () => {
return Math.floor(Math.random() * (10 - 5 + 1)) + 5;
};

/** 이동한 km를 구하는 함수 */
const calculateDistance = (x: number) => {
const totalDistance = Math.abs(x);

store.dispatch(action.updateDistance(totalDistance));
};

const handleSmoothlyStop = () => {
const moveMoreDistance = 500;
const handleSmoothlyStop = (duration: number) => {
const moveMoreDistance = [700, 600, 500, 400, 300, 200]

if (endGameTimeoutRef.current) {
clearTimeout(endGameTimeoutRef.current);
Expand All @@ -68,12 +75,12 @@ const RacingGame: React.FC = () => {
const currentRearX = rearRef.current?.getBoundingClientRect().x || 0;

frontAnimationControls.start({
x: currentFrontX - moveMoreDistance,
x: currentFrontX - moveMoreDistance[duration - 5],
transition: { duration: 1, ease: "easeOut" },
});

rearAnimationControls.start({
x: currentRearX - moveMoreDistance,
x: currentRearX - moveMoreDistance[duration - 5],
transition: { duration: 1, ease: "easeOut" },
});

Expand All @@ -100,6 +107,8 @@ const RacingGame: React.FC = () => {
};

const handlePlayGame = () => {
durationRef.current = getRandomDuration();

stopingMusicReset();
playingMusicPlay();

Expand All @@ -114,17 +123,17 @@ const RacingGame: React.FC = () => {
frontAnimationControls
.start({
x: [0, -14000],
transition: { duration: 7, repeat: 0 },
transition: { duration: durationRef.current, repeat: 0 },
});

rearAnimationControls.start({
x: [0, -7000],
transition: { duration: 7, repeat: 0 },
transition: { duration: durationRef.current, repeat: 0 },
});

endGameTimeoutRef.current = setTimeout(() => {
handleSmoothlyStop();
}, 6000);
handleSmoothlyStop(durationRef.current);
}, durationRef.current * 1000 - 1000);
}
};

Expand Down Expand Up @@ -196,15 +205,6 @@ const RacingGame: React.FC = () => {
fetchData();
}

const handleSpacebar = (event: KeyboardEvent) => {
if (event.code === "Space" && state.gameStatus === "playing" && !animationCompletedRef.current) {
event.preventDefault();
document.removeEventListener("keydown", handleSpacebar);

handleSmoothlyStop();
}
};

useEffect(() => {
const frontBackgroundImg = new Image();
frontBackgroundImg.src = frontBackground;
Expand All @@ -227,17 +227,12 @@ const RacingGame: React.FC = () => {
};
}, []);

useEffect(() => {
const containerRef = useKeyBoardControl("Space", (event: KeyboardEvent) => {
if (state.gameStatus === "playing" && !animationCompletedRef.current) {
document.addEventListener("keydown", handleSpacebar);
} else {
document.removeEventListener("keydown", handleSpacebar);
}

return () => {
document.removeEventListener("keydown", handleSpacebar);
};
}, [state.gameStatus]);
event.preventDefault();
handleSmoothlyStop(durationRef.current);
}
});

/** 애니메이션의 움직인 거리(x좌표값)가 바뀔 때 마다 km를 계산 */
useEffect(() => {
Expand All @@ -249,7 +244,7 @@ const RacingGame: React.FC = () => {
}, [frontX]);

return (
<div className="relative w-screen h-screen overflow-hidden">
<div ref={containerRef} className="relative w-screen h-screen overflow-hidden focus:outline-none" tabIndex={-1}>
<motion.div
ref={rearRef}
className="absolute top-0 left-0 h-[700px] bg-[auto_100%] z-[1]"
Expand Down
2 changes: 1 addition & 1 deletion Caecae/src/features/FindingGameLanding/OpenEvent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const OpenEvent = forwardRef<HTMLDivElement, OpenEventProps>((props, ref) => {
<img
src="/assets/colon.svg"
alt="smileBage3D"
className="w-[15px] mx-[20px]"
className="w-[15px] mx-[20px] pb-12"
/>
<div className="flex flex-col items-center">
<div className="flex gap-[10px]">
Expand Down
5 changes: 2 additions & 3 deletions Caecae/src/features/RacingGameLanding/EventPeriod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ const EventPeriod:React.FC<EventPeriodProps> = ({isEventOpen}) => {
<InfoSection title="7일간 매일매일">
<div className="flex flex-col justify-center items-center py-[60px] px-[60px]">
<p className="text-white text-center text-[22px] line-[140%]">
참여 기간: 7.15 (월) - 7.21 (일)
참여 기간: 8.26 (월) - 9.1 (일)
<br />
당첨자 발표 날짜: 7.29 (월)부터 주말ㆍ공휴일 제외 순차적으로
발송
당첨자 발표 날짜: 9.2 (화)부터 주말ㆍ공휴일 제외 순차적으로 발송
</p>
<div className="my-16">
<img
Expand Down
2 changes: 2 additions & 0 deletions Caecae/src/features/RacingGameLanding/HowToEvent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const HowToEvent = () => {
에게 추첨하여 경품 증정!
</p>
<p className="text-white text-[16px] mt-5">
* 레이싱 속도는 게임을 플레이할 때 마다 <span className="text-[#00AAD2]">랜덤</span>으로 달라져요!
<br />
* 중복 응모 시 가장 높은 점수 1건만 추첨에 반영됩니다.
</p>
<div className="flex flex-row justify-center items-center gap-10 mt-14">
Expand Down
31 changes: 31 additions & 0 deletions Caecae/src/hooks/useKeyBoardControl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useEffect, useRef, RefObject } from "react";

const useKeyBoardControl = (
key: string,
callback: (event: KeyboardEvent) => void
): RefObject<HTMLDivElement> => {
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.code === key) {
callback(event);
}
};

if (ref.current) {
ref.current?.focus();
ref.current?.addEventListener("keydown", handleKeyDown);
}

return () => {
if (ref.current) {
ref.current.removeEventListener("keydown", handleKeyDown);
}
};
}, [key, callback]);

return ref;
};

export default useKeyBoardControl;
5 changes: 0 additions & 5 deletions Caecae/src/jobs/RacingGame/RacingGameWork.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@ export interface RacingGamePayLoad {
gameStatus: "previous" | "playing" | "end" | "enterEvent";
topRate: number;
distance: number;
// phoneNumber: string;
}

const initRacingGameState = createState<RacingGamePayLoad>(WORKFLOW_NAME, {
gameStatus: "previous",
topRate: 0,
distance: 0,
// phoneNumber: "",
});

// define reducer
Expand Down Expand Up @@ -83,9 +81,6 @@ const action = {
return {
type: WORKFLOW_NAME,
actionName: "enterEvent",
payload: {
// phoneNumber: phoneNumber,
}
};
},
};
Expand Down
10 changes: 5 additions & 5 deletions Caecae/src/pages/RacingGame/Enter/SelectCustom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,21 @@ export default SelectCustom;

const options: Option[] = [
{
id: 0,
id: 1,
imgSrc: "/assets/racingGameCase1Image.svg",
title: "Case 1. 공간활용의 기술",
description:
"캐스퍼 일렉트릭의 구석구석을\n활용해 많은 물건도 알차게 실을래요.",
},
{
id: 1,
id: 2,
imgSrc: "/assets/racingGameCase2Image.svg",
title: "Case 2. 레저의 정석",
description:
"캐스퍼 일렉트릭과 함께 방방곡곡\n누빌 레저 라이프가 기대되어요.",
},
{
id: 2,
id: 3,
imgSrc: "/assets/racingGameCase3Image.svg",
title: (
<span>
Expand All @@ -152,7 +152,7 @@ const options: Option[] = [
"캐스퍼 일렉트릭과 함께 아웃도어\n활동을 쉽고 편안하게 할래요.",
},
{
id: 3,
id: 4,
imgSrc: "/assets/racingGameCase4Image.svg",
title: (
<span>
Expand All @@ -162,7 +162,7 @@ const options: Option[] = [
description: "캐스퍼 일렉트릭과 함께하는 즐거운\n피크닉이 기대되어요.",
},
{
id: 4,
id: 5,
imgSrc: "/assets/racingGameCase5Image.svg",
title: "Case 5. 펫 프렌들리",
description:
Expand Down
Loading