feat(nds): add audio in all menus
This commit is contained in:
@@ -1,58 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
const { onRender } = useScreen();
|
||||
const { assets } = useAssets();
|
||||
|
||||
const app = useAppStore();
|
||||
const store = useHomeStore();
|
||||
const { assets } = useAssets();
|
||||
const tickClock = useClockTick();
|
||||
|
||||
const CENTER_X = 63;
|
||||
const CENTER_Y = 95;
|
||||
|
||||
function drawLine(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x0: number,
|
||||
y0: number,
|
||||
x1: number,
|
||||
y1: number,
|
||||
width: number,
|
||||
) {
|
||||
const dx = Math.abs(x1 - x0);
|
||||
const dy = Math.abs(y1 - y0);
|
||||
const sx = x0 < x1 ? 1 : -1;
|
||||
const sy = y0 < y1 ? 1 : -1;
|
||||
let err = dx - dy;
|
||||
|
||||
const drawThickPixel = (x: number, y: number) => {
|
||||
const isVertical = dy > dx;
|
||||
|
||||
if (width === 1) {
|
||||
ctx.fillRect(x, y, 1, 1);
|
||||
} else if (isVertical) {
|
||||
const offset = Math.floor((width - 1) / 2);
|
||||
ctx.fillRect(x - offset, y, width, 1);
|
||||
} else {
|
||||
const offset = Math.floor((width - 1) / 2);
|
||||
ctx.fillRect(x, y - offset, 1, width);
|
||||
}
|
||||
};
|
||||
|
||||
while (true) {
|
||||
drawThickPixel(x0, y0);
|
||||
|
||||
if (x0 === x1 && y0 === y1) break;
|
||||
|
||||
const e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if (e2 < dx) {
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onRender((ctx) => {
|
||||
ctx.globalAlpha = store.isIntro
|
||||
? store.intro.topScreenOpacity
|
||||
@@ -66,7 +22,9 @@ onRender((ctx) => {
|
||||
: store.isOutro && store.outro.animateTop
|
||||
? store.outro.stage2Opacity
|
||||
: 1;
|
||||
|
||||
const now = new Date();
|
||||
tickClock(now);
|
||||
|
||||
const renderHand = (
|
||||
value: number,
|
||||
|
||||
@@ -58,6 +58,8 @@ const BIG_CIRCLE_DURATION = 0.09;
|
||||
const POST_DURATION = 0.07;
|
||||
|
||||
const startButtonAnimation = (type: ButtonType) => {
|
||||
assets.audio.pkmnButton.play();
|
||||
|
||||
const anim: ButtonAnimation = {
|
||||
type,
|
||||
position: BUTTONS[type].position,
|
||||
|
||||
@@ -53,13 +53,20 @@ useKeyDown(({ key }) => {
|
||||
|
||||
switch (key) {
|
||||
case "NDS_UP":
|
||||
selectedOption = "yes";
|
||||
if (selectedOption !== "yes") {
|
||||
selectedOption = "yes";
|
||||
assets.audio.pkmnSelector.play();
|
||||
}
|
||||
break;
|
||||
case "NDS_DOWN":
|
||||
selectedOption = "no";
|
||||
if (selectedOption !== "no") {
|
||||
selectedOption = "no";
|
||||
assets.audio.pkmnSelector.play();
|
||||
}
|
||||
break;
|
||||
case "NDS_A":
|
||||
case "NDS_START":
|
||||
assets.audio.pkmnSelector.play();
|
||||
setTimeout(() => {
|
||||
if (selectedOption === "yes") store.visitProject();
|
||||
store.showConfirmationPopup = false;
|
||||
@@ -90,12 +97,14 @@ onClick((x, y) => {
|
||||
const ACTIVATION_DELAY = 50;
|
||||
|
||||
if (rectContains([198, 105, 50, 14], [x, y])) {
|
||||
assets.audio.pkmnSelector.play();
|
||||
selectedOption = "yes";
|
||||
setTimeout(() => {
|
||||
store.visitProject();
|
||||
store.showConfirmationPopup = false;
|
||||
}, ACTIVATION_DELAY);
|
||||
} else if (rectContains([198, 121, 50, 14], [x, y])) {
|
||||
assets.audio.pkmnSelector.play();
|
||||
selectedOption = "no";
|
||||
setTimeout(() => (store.showConfirmationPopup = false), ACTIVATION_DELAY);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ const handleReset = () => {
|
||||
|
||||
const handleVisitAll = () => {
|
||||
if (isAnimating.value) return;
|
||||
assets.audio.menuOpen.play();
|
||||
achievementsScreen.animateFadeToBlackIntro();
|
||||
};
|
||||
|
||||
|
||||
@@ -71,11 +71,17 @@ const { select, selected, pressed, selectorPosition } = useButtonNavigation({
|
||||
onActivate: (buttonName) => {
|
||||
if (isSubMenu(buttonName)) {
|
||||
store.openSubMenu(buttonName);
|
||||
} else if (buttonName === "touchScreen") {
|
||||
store.openSubMenu("touchScreenTapTap");
|
||||
} else {
|
||||
if (!store.menuExpanded) {
|
||||
assets.audio.settingsMenuOpen.play();
|
||||
} else {
|
||||
assets.audio.tinyClick.play(0.8);
|
||||
}
|
||||
if (buttonName === "options") select("optionsLanguage");
|
||||
if (buttonName === "clock") select("clockAchievements");
|
||||
if (buttonName === "user") select("userUserName");
|
||||
if (buttonName === "touchScreen") store.openSubMenu("touchScreenTapTap");
|
||||
}
|
||||
},
|
||||
navigation: {
|
||||
@@ -156,6 +162,21 @@ const { select, selected, pressed, selectorPosition } = useButtonNavigation({
|
||||
}
|
||||
return true;
|
||||
},
|
||||
onNavigate: (buttonName) => {
|
||||
if (isMainMenu(buttonName)) {
|
||||
if (store.menuExpanded) {
|
||||
assets.audio.settingsMenuClose.play();
|
||||
} else {
|
||||
assets.audio.tinyClick.play(0.8);
|
||||
}
|
||||
} else {
|
||||
if (!store.menuExpanded) {
|
||||
assets.audio.settingsMenuOpen.play();
|
||||
} else {
|
||||
assets.audio.tinyClick.play(0.8);
|
||||
}
|
||||
}
|
||||
},
|
||||
disabled: computed(
|
||||
() =>
|
||||
store.currentSubMenu !== null ||
|
||||
@@ -256,12 +277,17 @@ const handleActivateA = () => {
|
||||
|
||||
if (isSubMenu(selected.value)) {
|
||||
store.openSubMenu(selected.value);
|
||||
} else if (selected.value === "touchScreen") {
|
||||
store.openSubMenu("touchScreenTapTap");
|
||||
} else {
|
||||
if (!store.menuExpanded) {
|
||||
assets.audio.settingsMenuOpen.play();
|
||||
} else {
|
||||
assets.audio.tinyClick.play(0.8);
|
||||
}
|
||||
if (selected.value === "options") select("optionsLanguage");
|
||||
if (selected.value === "clock") select("clockAchievements");
|
||||
if (selected.value === "user") select("userUserName");
|
||||
if (selected.value === "touchScreen")
|
||||
store.openSubMenu("touchScreenTapTap");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -270,6 +296,7 @@ const handleActivateB = () => {
|
||||
return;
|
||||
|
||||
if (isSubmenuSelected.value) {
|
||||
assets.audio.settingsMenuClose.play();
|
||||
select(getParentMenu(selected.value));
|
||||
} else {
|
||||
store.animateOutro();
|
||||
|
||||
@@ -17,7 +17,7 @@ const handleActivateB = () => {
|
||||
onClosed: async (choice) => {
|
||||
if (choice === "A") {
|
||||
await animateOutro();
|
||||
store.closeSubMenu();
|
||||
store.closeSubMenu(true);
|
||||
}
|
||||
},
|
||||
keepButtonsDown: (choice) => choice === "A",
|
||||
@@ -460,6 +460,8 @@ const slide = (rowDir: number, colDir: number) => {
|
||||
);
|
||||
if (!changed) return;
|
||||
|
||||
assets.audio.type.play(0.35);
|
||||
|
||||
if (board.some((r) => r.some((c) => c >= 512))) {
|
||||
achievements.unlock("2048_score_512");
|
||||
}
|
||||
@@ -534,11 +536,20 @@ const slide = (rowDir: number, colDir: number) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (mergePairs.length > 0) {
|
||||
const highestMerge = Math.max(...mergePairs.map((p) => p.mergedValue));
|
||||
const boardMax = Math.max(0, ...beforeTiles.map((t) => t.value));
|
||||
if (highestMerge > boardMax) {
|
||||
assets.audio.duplicate.play(0.35);
|
||||
}
|
||||
}
|
||||
|
||||
const spawned = spawnTile();
|
||||
saveState();
|
||||
|
||||
if (isDead()) {
|
||||
buildTilesFromBoard();
|
||||
assets.audio.invalid.play();
|
||||
showRestartModal();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ const handleActivateA = () => {
|
||||
),
|
||||
onClosed: async () => {
|
||||
await animateOutro();
|
||||
store.closeSubMenu();
|
||||
store.closeSubMenu(true);
|
||||
},
|
||||
keepButtonsDown: true,
|
||||
timeout: 2000,
|
||||
|
||||
@@ -120,7 +120,7 @@ const handleActivateA = () => {
|
||||
: $t("settings.options.renderingMode.confirmation2d"),
|
||||
onClosed: async () => {
|
||||
await animateOutro();
|
||||
store.closeSubMenu();
|
||||
store.closeSubMenu(true);
|
||||
},
|
||||
keepButtonsDown: true,
|
||||
timeout: 2000,
|
||||
|
||||
@@ -6,6 +6,7 @@ const app = useAppStore();
|
||||
const store = useSettingsStore();
|
||||
const achievements = useAchievementsStore();
|
||||
const confirmationModal = useConfirmationModal();
|
||||
const { assets } = useAssets();
|
||||
|
||||
const { onRender, onClick } = useScreen();
|
||||
|
||||
@@ -161,7 +162,7 @@ const handleActivateB = () => {
|
||||
onClosed: async (choice) => {
|
||||
if (choice === "A") {
|
||||
await animateOutro();
|
||||
store.closeSubMenu();
|
||||
store.closeSubMenu(true);
|
||||
} else {
|
||||
state.value = "playing";
|
||||
}
|
||||
@@ -190,6 +191,7 @@ const handleActivateA = async () => {
|
||||
},
|
||||
});
|
||||
} else if (state.value === "waiting") {
|
||||
assets.audio.menuConfirmed.play();
|
||||
await gsap.to(animation, {
|
||||
areaOpacity: 0,
|
||||
duration: AREA_FADE_DURATION,
|
||||
@@ -264,7 +266,7 @@ const showDeathScreen = () => {
|
||||
resetGame();
|
||||
} else {
|
||||
await animateOutro();
|
||||
store.closeSubMenu();
|
||||
store.closeSubMenu(true);
|
||||
}
|
||||
},
|
||||
keepButtonsDown: (choice) => choice === "B",
|
||||
@@ -286,6 +288,7 @@ onClick((mx, my) => {
|
||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (distance <= circle.radius) {
|
||||
assets.audio.type.play(0.35);
|
||||
rings.push({
|
||||
x: circle.x,
|
||||
y: circle.y,
|
||||
@@ -336,7 +339,10 @@ onRender((ctx, deltaTime) => {
|
||||
lives--;
|
||||
if (lives <= 0) {
|
||||
state.value = "ended";
|
||||
assets.audio.invalid.play();
|
||||
showDeathScreen();
|
||||
} else {
|
||||
assets.audio.eraser.play();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ const handleActivateA = () => {
|
||||
text,
|
||||
onClosed: async () => {
|
||||
await animateOutro();
|
||||
store.closeSubMenu();
|
||||
store.closeSubMenu(true);
|
||||
},
|
||||
keepButtonsDown: true,
|
||||
timeout: 2000,
|
||||
|
||||
@@ -156,16 +156,16 @@ useKeyDown(({ key }) => {
|
||||
|
||||
switch (key) {
|
||||
case "NDS_UP":
|
||||
if (selectedRow > 0) select(selectedCol, selectedRow - 1);
|
||||
if (selectedRow > 0) { assets.audio.tinyClick.play(0.8); select(selectedCol, selectedRow - 1); }
|
||||
break;
|
||||
case "NDS_RIGHT":
|
||||
if (selectedCol < GRID_SIZE - 1) select(selectedCol + 1, selectedRow);
|
||||
if (selectedCol < GRID_SIZE - 1) { assets.audio.tinyClick.play(0.8); select(selectedCol + 1, selectedRow); }
|
||||
break;
|
||||
case "NDS_DOWN":
|
||||
if (selectedRow < GRID_SIZE - 1) select(selectedCol, selectedRow + 1);
|
||||
if (selectedRow < GRID_SIZE - 1) { assets.audio.tinyClick.play(0.8); select(selectedCol, selectedRow + 1); }
|
||||
break;
|
||||
case "NDS_LEFT":
|
||||
if (selectedCol > 0) select(selectedCol - 1, selectedRow);
|
||||
if (selectedCol > 0) { assets.audio.tinyClick.play(0.8); select(selectedCol - 1, selectedRow); }
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -186,6 +186,7 @@ onClick((x, y) => {
|
||||
rectContains([0, 0, GRID_SIZE - 1, GRID_SIZE - 1], [col, row]) &&
|
||||
rectContains([0, 0, CELL_SIZE + 1, CELL_SIZE + 1], [cellLocalX, cellLocalY])
|
||||
) {
|
||||
assets.audio.tinyClick.play(0.8);
|
||||
select(col, row);
|
||||
}
|
||||
});
|
||||
@@ -288,7 +289,7 @@ const handleActivateA = () => {
|
||||
text: $t("settings.user.color.confirmation"),
|
||||
onClosed: async () => {
|
||||
await animateOutro();
|
||||
store.closeSubMenu();
|
||||
store.closeSubMenu(true);
|
||||
},
|
||||
keepButtonsDown: true,
|
||||
timeout: 2000,
|
||||
|
||||
@@ -120,7 +120,7 @@ const handleActivateB = async () => {
|
||||
onClosed: async (choice) => {
|
||||
if (choice === "A") {
|
||||
await animateOutro();
|
||||
store.closeSubMenu();
|
||||
store.closeSubMenu(true);
|
||||
} else {
|
||||
state.value = "alive";
|
||||
}
|
||||
@@ -160,6 +160,7 @@ const handleActivateA = () => {
|
||||
}
|
||||
|
||||
case "waiting": {
|
||||
atlas.audio.menuConfirmed.play();
|
||||
spawn();
|
||||
break;
|
||||
}
|
||||
@@ -207,6 +208,8 @@ const eat = () => {
|
||||
food.copy(randomFoodPos());
|
||||
score += 1;
|
||||
|
||||
atlas.audio.duplicate.play(0.35);
|
||||
|
||||
if (score === 40) {
|
||||
achievements.unlock("snake_score_25");
|
||||
}
|
||||
@@ -214,6 +217,7 @@ const eat = () => {
|
||||
|
||||
const die = () => {
|
||||
state.value = "dead";
|
||||
atlas.audio.invalid.play();
|
||||
};
|
||||
|
||||
const spawn = () => {
|
||||
@@ -351,6 +355,7 @@ useKeyDown(({ key }) => {
|
||||
|
||||
if (newDirection.clone().dot(direction) === 0) {
|
||||
nextDirection.copy(newDirection);
|
||||
atlas.audio.type.play(0.35);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,64 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
const { onRender } = useScreen();
|
||||
const { assets } = useAssets();
|
||||
|
||||
const app = useAppStore();
|
||||
const store = useSettingsStore();
|
||||
const { assets } = useAssets();
|
||||
const tickClock = useClockTick();
|
||||
|
||||
const CENTER_X = 63;
|
||||
const CENTER_Y = 95;
|
||||
|
||||
function drawLine(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x0: number,
|
||||
y0: number,
|
||||
x1: number,
|
||||
y1: number,
|
||||
width: number,
|
||||
) {
|
||||
const dx = Math.abs(x1 - x0);
|
||||
const dy = Math.abs(y1 - y0);
|
||||
const sx = x0 < x1 ? 1 : -1;
|
||||
const sy = y0 < y1 ? 1 : -1;
|
||||
let err = dx - dy;
|
||||
|
||||
const drawThickPixel = (x: number, y: number) => {
|
||||
const isVertical = dy > dx;
|
||||
|
||||
if (width === 1) {
|
||||
ctx.fillRect(x, y, 1, 1);
|
||||
} else if (isVertical) {
|
||||
const offset = Math.floor((width - 1) / 2);
|
||||
ctx.fillRect(x - offset, y, width, 1);
|
||||
} else {
|
||||
const offset = Math.floor((width - 1) / 2);
|
||||
ctx.fillRect(x, y - offset, 1, width);
|
||||
}
|
||||
};
|
||||
|
||||
while (true) {
|
||||
drawThickPixel(x0, y0);
|
||||
|
||||
if (x0 === x1 && y0 === y1) break;
|
||||
|
||||
const e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if (e2 < dx) {
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onRender((ctx) => {
|
||||
ctx.translate(0, -16 + store.notificationYOffset / 3);
|
||||
|
||||
assets.images.home.topScreen.clock.draw(ctx, 13, 45);
|
||||
|
||||
const now = new Date();
|
||||
tickClock(now);
|
||||
|
||||
const renderHand = (
|
||||
value: number,
|
||||
|
||||
Reference in New Issue
Block a user