diff --git a/src/components/utilities/Controls.vue b/src/components/utilities/Controls.vue
index aab9c81..83a3345 100644
--- a/src/components/utilities/Controls.vue
+++ b/src/components/utilities/Controls.vue
@@ -8,14 +8,59 @@ import { onBeforeUnmount, ref } from 'vue'
 import { usePointerHandlers } from '@/composables/usePointerHandlers'
 import { useCameraControls } from '@/composables/useCameraControls'
 
+// Types
+type WayPoint = { visible: boolean; x: number; y: number }
+
+// Props
 const props = defineProps<{ layer: Phaser.Tilemaps.TilemapLayer }>()
+
+// Constants
+const ZOOM_SETTINGS = {
+  WHEEL_FACTOR: 0.005,
+  KEY_FACTOR: 0.3,
+  MIN: 1,
+  MAX: 3
+} as const
+
+// Setup
 const scene = useScene()
-
-const waypoint = ref({ visible: false, x: 0, y: 0 })
-
+const waypoint = ref<WayPoint>({ visible: false, x: 0, y: 0 })
 const { camera } = useCameraControls(scene)
 const { setupPointerHandlers, cleanupPointerHandlers } = usePointerHandlers(scene, props.layer, waypoint, camera)
 
+// Handlers
+function handleScrollZoom(pointer: Phaser.Input.Pointer) {
+  if (!(pointer.event instanceof WheelEvent && pointer.event.shiftKey)) return
+
+  const zoomLevel = Phaser.Math.Clamp(
+    camera.zoom - pointer.event.deltaY * ZOOM_SETTINGS.WHEEL_FACTOR,
+    ZOOM_SETTINGS.MIN,
+    ZOOM_SETTINGS.MAX
+  )
+  camera.setZoom(zoomLevel)
+}
+
+function handleKeyComboZoom(event: { keyCodes: number[] }) {
+  const deltaY = event.keyCodes[1] === 38 ? 1 : -1 // 38 is Up, 40 is Down
+  const zoomLevel = Phaser.Math.Clamp(
+    camera.zoom + deltaY * ZOOM_SETTINGS.KEY_FACTOR,
+    ZOOM_SETTINGS.MIN,
+    ZOOM_SETTINGS.MAX
+  )
+  camera.setZoom(zoomLevel)
+}
+
+// Event setup
 setupPointerHandlers()
-onBeforeUnmount(cleanupPointerHandlers)
-</script>
+scene.input.keyboard?.createCombo([16, 38], { resetOnMatch: true }) // Shift + Up
+scene.input.keyboard?.createCombo([16, 40], { resetOnMatch: true }) // Shift + Down
+scene.input.keyboard?.on('keycombomatch', handleKeyComboZoom)
+scene.input.on(Phaser.Input.Events.POINTER_WHEEL, handleScrollZoom)
+
+// Cleanup
+onBeforeUnmount(() => {
+  cleanupPointerHandlers()
+  scene.input.keyboard?.off('keycombomatch')
+  scene.input.off(Phaser.Input.Events.POINTER_WHEEL, handleScrollZoom)
+})
+</script>
\ No newline at end of file
diff --git a/src/composables/pointerHandlers/useGamePointerHandlers.ts b/src/composables/pointerHandlers/useGamePointerHandlers.ts
index 14e9c1a..2e90413 100644
--- a/src/composables/pointerHandlers/useGamePointerHandlers.ts
+++ b/src/composables/pointerHandlers/useGamePointerHandlers.ts
@@ -58,27 +58,16 @@ export function useGamePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilema
     gameStore.setPlayerDraggingCamera(false)
   }
 
-  function handleZoom(pointer: Phaser.Input.Pointer) {
-    if (pointer.event instanceof WheelEvent && pointer.event.shiftKey) {
-      const deltaY = pointer.event.deltaY
-      let zoomLevel = camera.zoom - deltaY * 0.005
-      zoomLevel = Phaser.Math.Clamp(zoomLevel, 1, 3)
-      camera.setZoom(zoomLevel)
-    }
-  }
-
   const setupPointerHandlers = () => {
     scene.input.on(Phaser.Input.Events.POINTER_DOWN, handlePointerDown)
     scene.input.on(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
     scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp)
-    scene.input.on(Phaser.Input.Events.POINTER_WHEEL, handleZoom)
   }
 
   const cleanupPointerHandlers = () => {
     scene.input.off(Phaser.Input.Events.POINTER_DOWN, handlePointerDown)
     scene.input.off(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
     scene.input.off(Phaser.Input.Events.POINTER_UP, handlePointerUp)
-    scene.input.off(Phaser.Input.Events.POINTER_WHEEL, handleZoom)
   }
 
   return { setupPointerHandlers, cleanupPointerHandlers }