Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 취미
- 천등
- LeetCode
- 뜨아거
- 밥먹고
- 발더스게이트
- javascript
- 하스스톤
- 맛집
- 송리단
- 발더스모드
- 알고리즘테스트
- 누룽지소금빵
- 버즈2프로
- 3d퍼즐
- 서울제빵소
- 눈알빠지겠네
- DIY
- 발더스3
- 코테
- 노노그램
- 미앤아이
- 나쫌
- 바질토마토뭐시기
- 메일우유
- 잠실새내
- 코딩테스트
- 게임
- 토이프로젝트
- 메탈퍼즐
Archives
- Today
- Total
.Zzumbong
[DEV] react/typescript로 노노그램 만들어보기 - 2 본문
노노그램 토이프로젝트는 기획이나 정리 없이 머릿 속 순서대로 하고 있다!
정신 없이 흘러가기도 한다.
1편에 이어서 노노그램 게임을 만들어보자~
1. 정답지를 받고 내가 푸는 노노 그램을 일단 만들자
const Nonogram: React.FC<NonogramProps> = ({ answer }) => {
const [nonogram, setNonogram] = useState<Array<Array<number>>>(
Array(answer.length).fill(Array(answer.length).fill(0))
);
return (
<NonoBox>
{nonogram &&
nonogram.map((row, indexY) => (
<Row key={indexY}>
{row.map((cell, indexX) => (
<NonoItem
key={indexX}
type={cell}/>
))}
</Row>
))}
</NonoBox>
);
};
빈 노노 그램 박스가 완성된다.
2. 클릭 이벤트 만들기
노노그램 클릭은 2가지로 정했다.
- 왼쪽 클릭 시 체크 되고 체크된 cell을 클릭 시 다시 풀린다.
만약 X를 클릭시 체크된다. - 오른쪽 클릭 시 X로 표기하고 다시 클릭 시 빈칸으로 돌아간다.
만약 Cecked 상태라면 X로 바꾼다.
const updateNoNogram = (y: number, x: number, value: number) => {
setNonogram((nonogram) => {
const tempNonogram = nonogram.map((row) => [...row]);
tempNonogram[y][x] = value;
return tempNonogram;
});
};
const onclick = (y: number, x: number) => {
updateNoNogram(y, x, nonogram[y][x] === 1 ? 0 : 1);
};
const onRightClick = (e: MouseEvent, y: number, x: number) => {
e.preventDefault();
updateNoNogram(y, x, nonogram[y][x] === 2 ? 0 : 2);
};
//를 추가하고
// 아래처럼 이벤트를 받는다.
return (
<NonoBox>
{nonogram &&
nonogram.map((row, indexY) => (
<Row key={indexY}>
{row.map((cell, indexX) => (
<NonoItem
key={indexX}
type={cell}
onClick={() => onclick(indexY, indexX)}
onContextMenu={(e) =>
onRightClick(e, indexY, indexX)
}></NonoItem>
))}
</Row>
))}
</NonoBox>
);
보다보니 0, 1, 2처럼 나만 알아볼 수 있는 숫자보단 상수로 정의해보자
// 상수 정의
const CELL_STATE = {
NONE: 0, // 셀이 체크되지 않은 상태
CHECK: 1, // 셀이 체크된 상태
CROSS: 2 // 셀이 크로스된 상태
};
3. 드래그 이벤트 만들기
노노그램에서는 CHECK, CROSS, NONE을 선택하고 드래그하면 그 state로 바꾸는 기능이 있다.
없으면 매우 불편.
이런 기능을 만들려면 2가지 이벤트가 필요할 것 같다.
mouseDown, mouseEnter 정도 쓰면 될 것 같은데
다운 시 이벤트를 트리거해서 enter된 cell에서 좌표를 받아서 스테이트를 바꾸는 작업을 할 수 있을 것 같다.
const CELL_STATE = {
NONE: 0, // 셀이 체크되지 않은 상태
CHECK: 1, // 셀이 체크된 상태
CROSS: 2, // 셀이 크로스된 상태
} as const;
type CellState = (typeof CELL_STATE)[keyof typeof CELL_STATE];
const Nonogram: React.FC<NonogramProps> = ({ answer }) => {
const [nonogram, setNonogram] = useState<Array<Array<number>>>(
Array(answer.length).fill(Array(answer.length).fill(0))
);
const [dragState, setDragState] = useState<CellState>(0);
const [isDrag, setIsDrag] = useState<boolean>(false);
useEffect(() => {
if (nonogram.flat().join('') === answer.flat().join('')) {
console.log('정답이야.');
}
document.addEventListener('mouseup', onMouseUp);
return () => {
document.removeEventListener('mouseup', onMouseUp);
};
}, [nonogram, answer]);
const updateNoNogram = (y: number, x: number, value: number) => {
setNonogram((nonogram) => {
const tempNonogram = nonogram.map((row) => [...row]);
tempNonogram[y][x] = value;
return tempNonogram;
});
};
const onclick = (y: number, x: number) => {
updateNoNogram(
y,
x,
nonogram[y][x] === CELL_STATE.CHECK ? CELL_STATE.NONE : CELL_STATE.CHECK
);
};
const onRightClick = (e: MouseEvent, y: number, x: number) => {
e.preventDefault();
updateNoNogram(
y,
x,
nonogram[y][x] === CELL_STATE.CROSS ? CELL_STATE.NONE : CELL_STATE.CROSS
);
};
const onMouseDown = () => {
setIsDrag(true);
};
const onMouseUp = () => {
setIsDrag(false);
};
const onMouseEnter = (y: number, x: number) => {
if (isDrag) updateNoNogram(y, x, dragState);
};
return (
<div>
<NonoBox>
{nonogram &&
nonogram.map((row, indexY) => (
<Row key={indexY}>
{row.map((cell, indexX) => (
<NonoItem
key={indexX}
state={cell}
onMouseDown={() => onMouseDown()}
onClick={() => onclick(indexY, indexX)}
onContextMenu={(e) => onRightClick(e, indexY, indexX)}
onMouseEnter={() => onMouseEnter(indexY, indexX)}
/>
))}
</Row>
))}
</NonoBox>
current isDrag : {JSON.stringify(isDrag)} <br />
current drag state : {dragState} <br />
<button onClick={() => setDragState(CELL_STATE.NONE)}>None</button>
<button onClick={() => setDragState(CELL_STATE.CHECK)}>Check</button>
<button onClick={() => setDragState(CELL_STATE.CROSS)}>Cross</button>
</div>
);
};
export default Nonogram;
MouseDown 시 Enter된 셀에서 state를 바꾸도록 이벤트를 추가하고 실행
문제 1. 이미 엔터된 셀은 이벤트가 일어나지 않는다.
문제 2. 노노그램을 해본 사람들은 알겠지만 클릭 후 바꿀때는 가로 세로 만 바뀌어야한다. 대각선 불가!
다음은 이 문제를 해결하고 좀 더 게임으로 만들어보자
'Dev' 카테고리의 다른 글
[DEV] react/typescript로 노노그램 만들어보기 (0) | 2024.03.22 |
---|---|
[DEV] 프론트엔드 개발자 포트폴리오 Intro 리뷰 (1) | 2024.03.20 |
[TIP] 쉬운 디버깅을 위한 console 메소드 알아보기 (0) | 2024.02.15 |
[15~22] 8년차 Front-End 개발자의 개발 인생 회고록 (0) | 2022.11.23 |
Comments