Files
pihkaal-me/app/components/Achievements/BottomScreen.vue

86 lines
2.2 KiB
Vue

<script setup lang="ts">
const { onRender, onClick } = useScreen();
const store = useAchievementsScreen();
const achievementsStore = useAchievementsStore();
const { assets } = useAssets();
const QUIT_SIZE = assets.images.achievements.quit.rect.width;
const QUIT_X = Math.floor(LOGICAL_WIDTH / 2 - QUIT_SIZE / 2);
const QUIT_Y = 135;
useKeyDown((key) => {
if (store.isIntro || store.isOutro) return;
switch (key) {
case "NDS_B":
case "NDS_A":
case "NDS_START": {
store.animateOutro();
}
}
});
onClick((x, y) => {
if (store.isIntro || store.isOutro) return;
if (rectContains([QUIT_X, QUIT_Y, QUIT_SIZE, QUIT_SIZE], [x, y])) {
store.animateOutro();
}
});
onRender((ctx) => {
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, LOGICAL_WIDTH, LOGICAL_HEIGHT);
// achievement list (reversed iteration because they appear in cascade)
ctx.globalAlpha = store.isIntro
? store.intro.stage1Opacity
: store.isOutro
? store.outro.stage1Opacity
: 1;
ctx.font = "7px NDS7";
ctx.textBaseline = "top";
for (
let i = ACHIEVEMENTS.length - 1;
i >= ACHIEVEMENTS_TOP_SCREEN_COUNT;
i--
) {
const achievement = ACHIEVEMENTS[i]!;
const isUnlocked = achievementsStore.isUnlocked(achievement.id);
const offset = store.getItemOffset(i);
if (offset === -ACHIEVEMENTS_LINE_HEIGHT) continue;
const baseY =
ACHIEVEMENTS_BOTTOM_START_Y +
(i - ACHIEVEMENTS_TOP_SCREEN_COUNT) * ACHIEVEMENTS_LINE_HEIGHT;
const y = baseY + offset;
// needed for the sliding animation
ctx.fillStyle = "#000000";
ctx.fillRect(0, y, LOGICAL_WIDTH, ACHIEVEMENTS_LINE_HEIGHT);
ctx.fillStyle = isUnlocked ? "#ffffff" : "#666666";
drawCheckbox(ctx, ACHIEVEMENTS_X, y, isUnlocked);
ctx.fillText(
achievement.secret && !isUnlocked
? "???"
: $t(`achievements.${achievement.id}`).replace("\n", " "),
ACHIEVEMENTS_X + CHECKBOX_SIZE + CHECKBOX_TEXT_GAP,
y,
);
}
ctx.globalAlpha = store.isIntro
? store.intro.stage1Opacity
: store.isOutro
? store.outro.stage2Opacity
: 1;
assets.images.achievements.quit.draw(ctx, QUIT_X, QUIT_Y);
});
defineOptions({
render: () => null,
});
</script>