Skip to content

Commit 8e15687

Browse files
authored
feat: 단어 자소 추리(Wordle) 게임 구현 및 모바일 개선 (#8)
1 parent 7ad7896 commit 8e15687

1 file changed

Lines changed: 23 additions & 10 deletions

File tree

src/app/wordle/page.tsx

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export default function WordleGame() {
2828
const [gameStatus, setGameStatus] = useState<'playing' | 'won' | 'lost'>('playing');
2929

3030
// UI 상태
31+
const [isMobile, setIsMobile] = useState(false);
3132
const [showGuide, setShowGuide] = useState(false);
3233
const [showResult, setShowResult] = useState(false);
3334
const [shakeRow, setShakeRow] = useState<number | null>(null);
@@ -36,6 +37,15 @@ export default function WordleGame() {
3637

3738
const inputRef = useRef<HTMLInputElement>(null);
3839

40+
// 모바일 터치 디바이스 체크
41+
useEffect(() => {
42+
const checkMobile = () => {
43+
const isTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
44+
setIsMobile(isTouch);
45+
};
46+
checkMobile();
47+
}, []);
48+
3949
// 게임 시작 시 단어 선정
4050
const startNewGame = () => {
4151
const { word, jasos } = getRandomWord();
@@ -51,21 +61,23 @@ export default function WordleGame() {
5161
setShowResult(false);
5262
setFlipRow(null);
5363

54-
// 약간의 딜레이 후 인풋 포커스
64+
// 약간의 딜레이 후 인풋 포커스 (모바일 제외)
5565
setTimeout(() => {
56-
inputRef.current?.focus();
66+
if (inputRef.current && !isMobile) {
67+
inputRef.current.focus();
68+
}
5769
}, 50);
5870
};
5971

6072
useEffect(() => {
6173
startNewGame();
6274
// 최초 실행 시 안내창 띄우기
6375
setShowGuide(true);
64-
}, []);
76+
}, [isMobile]); // isMobile 값 설정 후 새 게임 처리 재확인
6577

66-
// 화면 클릭 시 항상 인풋 포커스 유지
78+
// 화면 클릭 시 항상 인풋 포커스 유지 (모바일 제외)
6779
const keepFocus = () => {
68-
if (gameStatus === 'playing' && !showGuide && !showResult) {
80+
if (gameStatus === 'playing' && !showGuide && !showResult && !isMobile) {
6981
inputRef.current?.focus();
7082
}
7183
};
@@ -75,7 +87,7 @@ export default function WordleGame() {
7587
return () => {
7688
document.removeEventListener('click', keepFocus);
7789
};
78-
}, [gameStatus, showGuide, showResult]);
90+
}, [gameStatus, showGuide, showResult, isMobile]);
7991

8092
// 실제 물리 키보드 입력 동기화
8193
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -122,7 +134,7 @@ export default function WordleGame() {
122134
setInputValue(assembled);
123135
setCurrentGuess(nextGuess);
124136
}
125-
inputRef.current?.focus();
137+
if (!isMobile) inputRef.current?.focus();
126138
return;
127139
}
128140

@@ -133,7 +145,7 @@ export default function WordleGame() {
133145
setInputValue(assembled);
134146
setCurrentGuess(nextGuess);
135147
}
136-
inputRef.current?.focus();
148+
if (!isMobile) inputRef.current?.focus();
137149
};
138150

139151
// 단어 제출 로직
@@ -248,7 +260,7 @@ export default function WordleGame() {
248260

249261
return (
250262
<main className="min-h-screen bg-neutral-950 text-neutral-100 flex flex-col items-center justify-between p-4 font-sans select-none">
251-
{/* 투명 한글 입력 필드 (IME 완벽 연동용) */}
263+
{/* 투명 한글 입력 필드 (IME 완벽 연동용, 모바일은 가상키보드 팝업 방지) */}
252264
<input
253265
ref={inputRef}
254266
type="text"
@@ -257,7 +269,8 @@ export default function WordleGame() {
257269
onChange={handleInputChange}
258270
onKeyDown={handleKeyDown}
259271
disabled={gameStatus !== 'playing'}
260-
autoFocus
272+
autoFocus={!isMobile}
273+
inputMode={isMobile ? "none" : "text"}
261274
autoComplete="off"
262275
autoCorrect="off"
263276
autoCapitalize="off"

0 commit comments

Comments
 (0)