[로데시] 개발
[대학전쟁3] 양면빙고 웹 개발 02 - 타일 list 내 이동 본문
반응형
0️⃣ 들어가기 전에..
대학전쟁에 나온 '양면빙고 (double sided bingo)' 게임을 보고 ☰ 양면빙고 (double-sided-bingo) 개발 과정
1️⃣ @dnd-kit 설치
📌 npm install @dnd-kit2️⃣ 코드 작성 - 타일 이동
설치가 끝났으면 코드를 작성해준다.📌 TileList.js 코드
// import 추가
import { DndContext, closestCenter, PointerSensor, useSensor, useSensors } from "@dnd-kit/core";
import { arrayMove, SortableContext } from "@dnd-kit/sortable";
// initialTiles에 key 값 추가
{ id: 1, key: "rb1" }, { id: 1, key: "rb2" }, { id: 1, key: "rb3" },
{ id: 3, key: "by1" }, { id: 3, key: "by2" }, { id: 3, key: "by3" },
{ id: 5, key: "yr1" }, { id: 5, key: "yr2" }, { id: 5, key: "yr3" },
const TileList = () => {
// [tiles, setTiles] 추가 -변경될 list update
const [tiles, setTiles] = useState(initialTiles);
...
// index -> key
const handleFlip = (key) => {
setFlippedMap((prev) => ({
...prev,
[key]: !prev[key],
}));
};
// sensors 추가 - 타일list 내 타일 이동 감지
const sensors = useSensors(
useSensor(PointerSensor, { activationConstraint: { distance : 5 } })
)
// handleDragEnd - 이동 감지 -> 새로운 list로 update
const handleDragEnd = (event) => {
const { active, over } = event;
if (!over || active.id === over.id) return;
const oldIndex = tiles.findIndex((t) => t.key === active.id);
const newIndex = tiles.findIndex((t) => t.key === over.id);
setTiles((items) => arrayMove(items, oldIndex, newIndex));
};
return (
{/* DndContext 추가 - 전반적인 드래그 제어 */}
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
>
{/* DSortableContext - 순서 정렬 */}
<SortableContext items={tiles}>
<div className="TileListWrapper">
<div className="TileList">
{tiles.map((tile) => (
<TileItem
key={tile.key}
tile={tile}
isFlipped={!!flippedMap[tile.key]}
onClick={() => handleFlip(tile.key)}
/>
))}
</div>
</div>
</SortableContext>
</DndContext>
);
};
📌 TileItem.js 코드
// import문 추가
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
// props 변경
const TileItem = ({ tile, isFlipped, onClick }) => {
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: tile.key });
// tile 움직임을 보여줌
const style = {
transform: CSS.Transform.toString(transform),
transition,
};
const displayId = isFlipped ? getPairedTileId(tile.id) : tile.id;
return (
<div ref={setNodeRef} style={style} {...attributes} {...listeners}>
<div className="TileItem" onClick={onClick}>
<img
className="tile_img"
src={getTileImgById(displayId)}
alt={`tile-${displayId}`}
/>
</div>
</div>
);
};
export default React.memo(TileItem);
3️⃣ 문제
❓ 문제 - 이동 중인 타일이 보이지 않고, 이동 결과만 보여주기 때문에 부자연스럽다.4️⃣ 코드 작성 - 타일 이동 (동적 / 애니메이션)
📌 TileList.js 코드
// import DragOverlay 추가
import { ..., DragOverlay } from "@dnd-kit/core";
...
const TileList = () => {
const [activeTile, setActiveTile] = useState(null); // 이동중인 타일
...
// 이동 시작 -> 이동 타일 저장 (보여주기 위함)
const handleDragStart = (event) => {
const { active } = event;
const tile = tiles.find((t) => t.key === active.id);
setActiveTile(tile);
};
// 이동 종료 -> 새로운 list로 update
const handleDragEnd = (event) => {
const { active, over } = event;
if (over && active.id !== over.id) {
const oldIndex = tiles.findIndex((t) => t.key === active.id);
const newIndex = tiles.findIndex((t) => t.key === over.id);
setTiles((items) => arrayMove(items, oldIndex, newIndex));
}
setActiveTile(null);
};
...
return (
<DndContext
...
onDragStart={handleDragStart} {/* DndContext에 onDragStart 추가 */}
>
<SortableContext items={tiles.map((t) => t.key)}> {/* id를 넘기도록 수정 */}
...
</SortableContext>
{/* DragOverlay 추가 */}
<DragOverlay>
{activeTile ? (
<TileItem
tile={activeTile.id}
isFlipped={!!flippedMap[activeTile.key]}
/>
) : null}
</DragOverlay>
</DndContext>
);
};
5️⃣ 앞으로...
양면 빙고지만 빙고판은 만들지도 않았다..
반응형
'개인 개발 > 대학전쟁' 카테고리의 다른 글
| [대학전쟁] 양면빙고 웹 개발 05 - 빙고 판단, player 2명 (0) | 2026.01.20 |
|---|---|
| [대학전쟁] 양면빙고 웹 개발 04 - 타일 뒤집기 (flip), 이동 (move) (1) | 2026.01.18 |
| [대학전쟁3] 양면빙고 웹 개발 03 - 타일 착수 (place) (0) | 2026.01.16 |
| [대학전쟁3] 양면빙고 웹 개발 01 - 타일 list, 타일 뒤집기 (0) | 2026.01.12 |
| [JAVA] 123을 도레미로 변환해서 헌트릭스의 골든 Golden 악보 만들기 (무료) (0) | 2025.11.08 |