Skip to content

Commit

Permalink
feat(renderer): auto-center level in viewport on load
Browse files Browse the repository at this point in the history
  • Loading branch information
MilanFox committed Dec 2, 2024
1 parent 0554dfd commit 7e71f3e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
16 changes: 13 additions & 3 deletions src/stores/renderer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineStore } from 'pinia';
import type { Reactive } from 'vue';
import { computed, reactive, ref } from 'vue';
import type { LevelMapBlueprint } from '@lib/level/level.types';

export enum CanvasLayerIDs {
BACKGROUND = 'canvas-background',
Expand Down Expand Up @@ -30,10 +31,19 @@ export const useRendererStore = defineStore('renderer', () => {
const camOffset = reactive({ x: baseTileSize.value / 2, y: baseTileSize.value / 2 });
const gameCanvasDimensions = reactive({ width: 0, height: 0 });

const recenterView = () => {
const recenterView = (map: LevelMapBlueprint) => {
zoomLevel.value = 1;
camOffset.x = baseTileSize.value / 2;
camOffset.y = baseTileSize.value / 2;
const mapWidth = Math.max(...map.map(row => row.length));
const mapHeight = map.length;
const mapPixelWidth = mapWidth * tileSize.value;
const mapPixelHeight = mapHeight * tileSize.value;
if (mapPixelWidth <= gameCanvasDimensions.width && mapPixelHeight <= gameCanvasDimensions.height) {
camOffset.x = (gameCanvasDimensions.width - mapPixelWidth) / 2;
camOffset.y = (gameCanvasDimensions.height - mapPixelHeight) / 2;
} else {
camOffset.x = baseTileSize.value / 2;
camOffset.y = baseTileSize.value / 2;
}
};

return {
Expand Down
8 changes: 6 additions & 2 deletions src/views/GameView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@
import GameCanvas from '@molecules/GameCanvas/GameCanvas.vue';
import useLevel, { levelData } from '@composables/useLevel';
import CodeEditor from '@atoms/CodeEditor/CodeEditor.vue';
import { ref } from 'vue';
import { onMounted, ref } from 'vue';
import type { IconButtonProps } from '@atoms/IconButton/IconButton.types';
import { useRendererStore } from '@stores/renderer';
import GameControls from '@molecules/GameControls/GameControls.vue';
import useUserLogic from '@composables/useUserLogic';
import DoublePageLayout from '@layouts/DoublePage/DoublePageLayout.vue';
import { useRoute } from 'vue-router';
import levels from '@/levels';
const { params: { id } } = useRoute();
const levelID = parseInt(id.toString(), 10);
Expand All @@ -55,6 +56,8 @@ const runProgram = () => {
useUserLogic().runUserCode();
};
const tryCenterView = () => renderStore.recenterView(levels[levelID - 1].blueprint);
const tabs = [
{ text: 'Intro', src: '/images/deco/signpost.png' },
];
Expand All @@ -68,9 +71,10 @@ const controls: IconButtonProps[] = [
{ text: 'Validate', icon: 'validate', onClick: () => { /* TODO */ } },
{ text: 'Zoom In', icon: 'zoom-in', onClick: renderStore.zoomIn },
{ text: 'Zoom Out', icon: 'zoom-out', onClick: renderStore.zoomOut },
{ text: 'Recenter View', icon: 'center-view', onClick: renderStore.recenterView },
{ text: 'Recenter View', icon: 'center-view', onClick: tryCenterView },
];
onMounted(tryCenterView);
</script>

<style lang="scss">
Expand Down

0 comments on commit 7e71f3e

Please sign in to comment.