타일을 이동시키는 것까지 구현했고, 이제 두 타일이 숫자가 같은 경우 병합시키는 부분을 구현할 차례다.
먼저 nextPosition
라는 변수를 만들어준다. 이 변수는 두 타일이 병합되어 하나의 타일이 되었을 때 그 타일의 위치가 될 것이다.
기본 로직은 현재 타일과 이전 타일이 같은 줄에 있다면
isOnSameLine
변수는 현재 타일과 이전 타일이 같은 행/열에 있는지 확인하고 true/false를 가진다.
x
값을 가지는지) 확인하고, y
값을 가지는지) 확인한다. 만약 nextPosition
이 0이 아니고, 두 타일이 같은 줄에 있다면,
y
값을 nextPosition
으로 변경한다.x
값을 nextPosition
으로 변경한다.nextPosition
의 값을 1씩 증감시킬 건데, 위/왼쪽 이동이라면 + 1을, 아래/오른쪽 이동이라면 -1을 해준다.export function slideTile(x, y, { tileList, setTileList }) {
// 생략..
let nextPosition = 0;
const newTileList = [...sortedTileList]; // `sortedTileList`를 복사해 `newTileList`를 만들어준다.
for (let i = 0; i < newTileList.length; i++) {
const currentTile = newTileList[i]; // 현재 타일
const prevTile = newTileList[i - 1]; // 이전 타일
const nextTile = newTileList[i + 1]; // 다음 타일
const isOnSameLine = isVerticalMove ? currentTile.x === prevTile?.x : currentTile.y === prevTile?.y;
if (nextPosition && isOnSameLine) {
if (isVerticalMove) {
currentTile.y = nextPosition;
} else {
currentTile.x = nextPosition;
}
isMinus ? nextPosition += 1 : nextPosition -=1;
} else {
nextPosition = 0;
}
// ...
isMergable
변수는 현재 타일과 다음 타일의 value
를 비교해 같은 값인지 확인하고, 두 타일이 같은 줄에 있는지 확인한다.
isMergable
이 true
라면, 새로운 타일을 만들어 현재 타일과 같은 위치에(같은 x
, y
할당) 현재 타일의 value
를 2배로 하여 새로운 타일리스트에 푸쉬해준다.
그리고 기존의 두 타일은 isDisabled
속성을 true
로 바꿔주어 화면에 렌더링되지 않도록 해준다.
그리고 두 타일이 병합될 때, nextPosition
의 값을 업데이트해줘야 한다.
nextPosition
을 다음 타일의 y
값으로,y
값을 현재 타일의 y
값으로 변경해준다.nextPosition
의 값을 다음 타일의 x
값으로 업데이트해준다.x
값도 현재 타일의 x
값으로 변경해준다. // ...
const isMergable =
currentTile.value === nextTile?.value &&
isVerticalMove ? currentTile.x === nextTile?.x : currentTile.y === nextTile?.y;
if (isMergable) {
const tile = makeTile(newTileList);
tile.x = currentTile.x;
tile.y = currentTile.y;
tile.value = currentTile.value * 2;
newTileList.push(tile);
currentTile.isDisabled = true;
nextTile.isDisabled = true;
}
if (isVerticalMove) {
nextPosition = nextTile.y;
nextTile.y = currentTile.y;
} else {
nextPosition = nextTile.x;
nextTile.x = currentTile.x;
}
}
setTileList(newTileList);
}
마지막으로 유저가 타일을 이동할 때마다 새로운 타일이 추가되게 해야 한다.
기존의 useHandleKeyboard
훅을 아래처럼 변경하여 slide한 후에 새로운 타일을 만들어 setTileList 함수에 전달했다.
function moveUp() {
slideAndAdd({ x: 0, y: -1 });
}
function moveDown() {
slideAndAdd({ x: 0, y: 1 });
}
function moveLeft() {
slideAndAdd({ x: -1, y: 0 });
}
function moveRight() {
slideAndAdd({ x: 1, y: 0 });
}
function slideAndAdd({ x, y }) {
const slidedTileList = slideTile({ x, y, tileList });
const newTile = makeTile(slidedTileList);
slidedTileList.push(newTile);
setTileList(slidedTileList);
}
기대가 됩니다 ~~