feat(settings/options/2048): allow faster movements and show restart modal when trying to move on an lost game
This commit is contained in:
@@ -28,33 +28,31 @@ const handleActivateA = () => {
|
|||||||
resetBoard();
|
resetBoard();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onCancel: () => {
|
|
||||||
confirmationModal.close();
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: one color scheme per app color
|
||||||
const TILE_COLORS: Record<number, { bg: string; fg: string }> = {
|
const TILE_COLORS: Record<number, { bg: string; fg: string }> = {
|
||||||
[0]: { bg: "#ccc0b4", fg: "#776e65" },
|
[0]: { bg: "#f7f7f7", fg: "#776e65" },
|
||||||
[2]: { bg: "#eee4db", fg: "#776e65" },
|
[2]: { bg: "#ebebf3", fg: "#292929" },
|
||||||
[4]: { bg: "#eee0cb", fg: "#776e65" },
|
[4]: { bg: "#d3dbe3", fg: "#292929" },
|
||||||
[8]: { bg: "#f3b27a", fg: "#f9f6f2" },
|
[8]: { bg: "#bacbd3", fg: "#292929" },
|
||||||
[16]: { bg: "#f69664", fg: "#f9f6f2" },
|
[16]: { bg: "#a2bac3", fg: "#f9f6f2" },
|
||||||
[32]: { bg: "#f67c5f", fg: "#f9f6f2" },
|
[32]: { bg: "#8aa2b2", fg: "#f9f6f2" },
|
||||||
[64]: { bg: "#f7603c", fg: "#f9f6f2" },
|
[64]: { bg: "#7192a2", fg: "#f9f6f2" },
|
||||||
[128]: { bg: "#ecd072", fg: "#f9f6f2" },
|
[128]: { bg: "#698aa2", fg: "#f9f6f2" },
|
||||||
[256]: { bg: "#eecc62", fg: "#f9f6f2" },
|
[256]: { bg: "#61829a", fg: "#f9f6f2" },
|
||||||
[512]: { bg: "#eec950", fg: "#f9f6f2" },
|
[512]: { bg: "#5c7b92", fg: "#f9f6f2" },
|
||||||
[1024]: { bg: "#edc53f", fg: "#f9f6f2" },
|
[1024]: { bg: "#57758a", fg: "#f9f6f2" }, // -2.5L, -0.8C
|
||||||
[2048]: { bg: "#edc12e", fg: "#f9f6f2" },
|
[2048]: { bg: "#476277", fg: "#f9f6f2" },
|
||||||
[4046]: { bg: "#3c3a33", fg: "#f9f6f2" },
|
[4046]: { bg: "#173446", fg: "#f9f6f2" },
|
||||||
};
|
};
|
||||||
const LAST_TILE_COLOR =
|
const LAST_TILE_COLOR =
|
||||||
Object.values(TILE_COLORS)[Object.values(TILE_COLORS).length - 1]!;
|
Object.values(TILE_COLORS)[Object.values(TILE_COLORS).length - 1]!;
|
||||||
const TILE_SIZE = 28;
|
const TILE_SIZE = 28;
|
||||||
const ANIM_DURATION = 0.1;
|
const ANIM_DURATION = 0.1;
|
||||||
|
|
||||||
const BORDER_COLOR = "#bbada0";
|
const BORDER_COLOR = "#d7d7d7";
|
||||||
const BORDER_SIZE = 3;
|
const BORDER_SIZE = 3;
|
||||||
|
|
||||||
const BOARD_X = 64;
|
const BOARD_X = 64;
|
||||||
@@ -81,6 +79,21 @@ const cellY = (row: number) => BORDER_SIZE + row * (TILE_SIZE + BORDER_SIZE);
|
|||||||
let tiles: VisualTile[] = [];
|
let tiles: VisualTile[] = [];
|
||||||
let animating = false;
|
let animating = false;
|
||||||
|
|
||||||
|
const showRestartModal = () => {
|
||||||
|
let confirmed = false;
|
||||||
|
confirmationModal.open({
|
||||||
|
text: "Game Over!\nRestart?",
|
||||||
|
onConfirm: () => {
|
||||||
|
confirmed = true;
|
||||||
|
},
|
||||||
|
onClosed: () => {
|
||||||
|
if (confirmed) {
|
||||||
|
resetBoard();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const buildTilesFromBoard = () => {
|
const buildTilesFromBoard = () => {
|
||||||
tiles = [];
|
tiles = [];
|
||||||
for (let row = 0; row < BOARD_SIZE; row += 1) {
|
for (let row = 0; row < BOARD_SIZE; row += 1) {
|
||||||
@@ -104,6 +117,8 @@ onRender((ctx) => {
|
|||||||
ctx.textBaseline = "top";
|
ctx.textBaseline = "top";
|
||||||
ctx.translate(BOARD_X, BOARD_Y);
|
ctx.translate(BOARD_X, BOARD_Y);
|
||||||
|
|
||||||
|
assets.images.settings.bottomScreen.options._2048.frame.draw(ctx, -3, -3);
|
||||||
|
|
||||||
ctx.fillStyle = BORDER_COLOR;
|
ctx.fillStyle = BORDER_COLOR;
|
||||||
ctx.fillRect(
|
ctx.fillRect(
|
||||||
0,
|
0,
|
||||||
@@ -251,7 +266,16 @@ if (board.every((r) => r.every((c) => c === 0))) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const slide = (rowDir: number, colDir: number) => {
|
const slide = (rowDir: number, colDir: number) => {
|
||||||
if (animating) return;
|
if (isDead() && !confirmationModal.isOpen) {
|
||||||
|
showRestartModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animating) {
|
||||||
|
gsap.globalTimeline.clear();
|
||||||
|
animating = false;
|
||||||
|
buildTilesFromBoard();
|
||||||
|
}
|
||||||
|
|
||||||
const beforeTiles: { row: number; col: number; value: number }[] = [];
|
const beforeTiles: { row: number; col: number; value: number }[] = [];
|
||||||
for (let row = 0; row < BOARD_SIZE; row += 1) {
|
for (let row = 0; row < BOARD_SIZE; row += 1) {
|
||||||
@@ -358,6 +382,12 @@ const slide = (rowDir: number, colDir: number) => {
|
|||||||
const spawned = spawnTile();
|
const spawned = spawnTile();
|
||||||
saveBoard();
|
saveBoard();
|
||||||
|
|
||||||
|
if (isDead()) {
|
||||||
|
buildTilesFromBoard();
|
||||||
|
showRestartModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tiles = animTiles;
|
tiles = animTiles;
|
||||||
animating = true;
|
animating = true;
|
||||||
|
|
||||||
@@ -365,27 +395,11 @@ const slide = (rowDir: number, colDir: number) => {
|
|||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
animating = false;
|
animating = false;
|
||||||
buildTilesFromBoard();
|
buildTilesFromBoard();
|
||||||
if (isDead()) {
|
|
||||||
confirmationModal.open({
|
|
||||||
text: "Game Over!\nRestart?",
|
|
||||||
onConfirm: () => {
|
|
||||||
resetBoard();
|
|
||||||
confirmationModal.close();
|
|
||||||
},
|
|
||||||
onCancel: () => {
|
|
||||||
confirmationModal.close();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const { tile, toX, toY } of tweens) {
|
for (const { tile, toX, toY } of tweens) {
|
||||||
tl.to(
|
tl.to(tile, { x: toX, y: toY, duration: ANIM_DURATION, ease: "none" }, 0);
|
||||||
tile,
|
|
||||||
{ x: toX, y: toY, duration: ANIM_DURATION, ease: "power1.out" },
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mergePairs.length > 0) {
|
if (mergePairs.length > 0) {
|
||||||
@@ -399,7 +413,7 @@ const slide = (rowDir: number, colDir: number) => {
|
|||||||
tl.fromTo(
|
tl.fromTo(
|
||||||
keep,
|
keep,
|
||||||
{ scale: 1.1 },
|
{ scale: 1.1 },
|
||||||
{ scale: 1, duration: ANIM_DURATION, ease: "power1.out" },
|
{ scale: 1, duration: ANIM_DURATION, ease: "none" },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,6 +438,15 @@ const slide = (rowDir: number, colDir: number) => {
|
|||||||
|
|
||||||
useKeyDown((key) => {
|
useKeyDown((key) => {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
|
// TODO: remove this, testing only
|
||||||
|
case "n":
|
||||||
|
savedBoard.value = [
|
||||||
|
[0, 0, 2, 4],
|
||||||
|
[8, 16, 32, 64],
|
||||||
|
[128, 256, 512, 1024],
|
||||||
|
[2048, 4096, 8192, 16384],
|
||||||
|
];
|
||||||
|
break;
|
||||||
case "NDS_UP":
|
case "NDS_UP":
|
||||||
slide(-1, 0);
|
slide(-1, 0);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user