From 016b8e082fcf6da662b57718aa8d7cea9c44ee2d Mon Sep 17 00:00:00 2001 From: Dennis Postma <dennis@directonline.io> Date: Sun, 21 Jul 2024 23:29:47 +0200 Subject: [PATCH] Fixed controls issues --- src/components/sprites/Character.vue | 24 ++++----- src/components/utilities/Controls.vue | 74 +++++++++++++++++++-------- src/stores/zoneEditor.ts | 8 +-- 3 files changed, 69 insertions(+), 37 deletions(-) diff --git a/src/components/sprites/Character.vue b/src/components/sprites/Character.vue index 9f50363..6754e7b 100644 --- a/src/components/sprites/Character.vue +++ b/src/components/sprites/Character.vue @@ -1,7 +1,7 @@ <template> <Container> - <Rectangle :x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)" :y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)" :origin-x="0.5" :origin-y="10.5" :fillColor="0xffffff" :width="74" :height="8"> - <Rectangle :x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)" :y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)" :origin-x="0.5" :origin-y="20.5" :fillColor="0x09ad19" :width="70" :height="4" /> + <Rectangle :x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)" :y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)" :origin-x="0.5" :origin-y="16" :fillColor="0xffffff" :width="74" :height="8"> + <Rectangle :x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)" :y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)" :origin-x="0.5" :origin-y="31.5" :fillColor="0x09ad19" :width="70" :height="4" /> </Rectangle> <Text @create="createText" @@ -9,20 +9,20 @@ :x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)" :y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)" :origin-x="0.5" - :origin-y="4.5" + :origin-y="7.5" :style="{ fontFamily: 'Helvetica, Arial', color: '#FFF', fontSize: '14px' }" /> - <Sprite ref="sprite" :x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)" :y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)" play="walk" /> + <Sprite ref="sprite" :x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)" :y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)" :origin-y="1" play="walk" /> </Container> </template> <script lang="ts" setup> import { Container, Rectangle, Sprite, Text, useScene } from 'phavuer' -import { onBeforeMount, onMounted, ref } from 'vue' +import { onBeforeMount, onBeforeUnmount, onMounted, ref } from 'vue' import { useGameStore } from '@/stores/game' import { type Character as CharacterT } from '@/types' import { getTile, tileToWorldX, tileToWorldXY, tileToWorldY } from '@/services/zone' @@ -50,7 +50,7 @@ function setupSelf() { } function onPointerClick(pointer: Phaser.Input.Pointer) { - if (!isSelf) return + if (!isSelf || gameStore.isMovingCamera) return const px = scene.cameras.main.worldView.x + pointer.x const py = scene.cameras.main.worldView.y + pointer.y @@ -62,7 +62,7 @@ function onPointerClick(pointer: Phaser.Input.Pointer) { gameStore.connection?.emit('character:move', { position_x: pointer_tile.x, position_y: pointer_tile.y }) - //Directions for player sprite + animations + // Directions for player sprite + animations if (px < 0 && py > 0) { console.log('down left') } else if (px < 0 && py < 0) { @@ -74,10 +74,8 @@ function onPointerClick(pointer: Phaser.Input.Pointer) { } } -/** - * Resources: - * https://www.youtube.com/watch?v=9sWrGohw9qo - * https://jsfiddle.net/juwalbose/pu0gt7nc/ - * - */ +onBeforeUnmount(() => { + if (!isSelf) return + scene.input.off(Phaser.Input.Events.POINTER_UP, onPointerClick) +}) </script> diff --git a/src/components/utilities/Controls.vue b/src/components/utilities/Controls.vue index fab14f7..b605c2e 100644 --- a/src/components/utilities/Controls.vue +++ b/src/components/utilities/Controls.vue @@ -11,9 +11,11 @@ import { getTile, tileToWorldXY } from '@/services/zone' import { useZoneEditorStore } from '@/stores/zoneEditor' import { useGameStore } from '@/stores/game' -const props = defineProps<{ +interface Props { layer: Phaser.Tilemaps.TilemapLayer -}>() +} + +const props = defineProps<Props>() const scene = useScene() const zoneEditorStore = useZoneEditorStore() @@ -27,10 +29,16 @@ const waypoint = ref({ }) const cam = ref(scene.cameras.main) +const isDragging = ref(false) +let pointerDownTimer: number | null = null +let pointerUpTimer: number | null = null + +const DRAG_DELAY = 150 +const MOVE_RESET_DELAY = 100 function updateWaypoint(pointer: Phaser.Input.Pointer) { const { x: px, y: py } = scene.cameras.main.getWorldPoint(pointer.x, pointer.y) - const pointerTile = getTile(px, py, props.layer) as Phaser.Tilemaps.Tile + const pointerTile = getTile(px, py, props.layer) if (!pointerTile) { waypoint.value.visible = false @@ -46,42 +54,68 @@ function updateWaypoint(pointer: Phaser.Input.Pointer) { } function dragZone(pointer: Phaser.Input.Pointer) { - if (!pointer.isDown) return + if (!isDragging.value) return const { x, y, prevPosition } = pointer cam.value.scrollX -= (x - prevPosition.x) / cam.value.zoom cam.value.scrollY -= (y - prevPosition.y) / cam.value.zoom } -function handleZoom(pointer: Phaser.Input.Pointer, _: any, __: any, deltaY: number) { - if (pointer.event.altKey) { +function handleZoom(pointer: Phaser.Input.Pointer, _: unknown, __: unknown, deltaY: number) { + if (pointer.event instanceof WheelEvent && pointer.event.altKey) { scene.scale.setZoom(scene.scale.zoom - deltaY * 0.01) cam.value = scene.cameras.main } } +function onPointerDown(pointer: Phaser.Input.Pointer) { + if (pointer.event instanceof MouseEvent && (pointer.event.altKey || tool.value === 'move')) { + pointerDownTimer = setTimeout(() => { + isDragging.value = true + gameStore.setMovingCamera(true) + scene.input.on(Phaser.Input.Events.POINTER_MOVE, dragZone) + }, DRAG_DELAY) + } +} + +function onPointerUp() { + if (pointerDownTimer) { + clearTimeout(pointerDownTimer) + pointerDownTimer = null + } + isDragging.value = false + scene.input.off(Phaser.Input.Events.POINTER_MOVE, dragZone) + + if (pointerUpTimer) { + clearTimeout(pointerUpTimer) + } + + pointerUpTimer = setTimeout(() => { + gameStore.setMovingCamera(false) + }, MOVE_RESET_DELAY) +} + function setupEventListeners() { scene.input.on(Phaser.Input.Events.POINTER_MOVE, updateWaypoint) scene.input.on(Phaser.Input.Events.POINTER_WHEEL, handleZoom) - - scene.input.on(Phaser.Input.Events.POINTER_DOWN, (pointer: Phaser.Input.Pointer) => { - if (pointer.event.altKey || tool.value === 'move') { - gameStore.setMovingCamera(true) - scene.input.on(Phaser.Input.Events.POINTER_MOVE, dragZone) - } - }) - - scene.input.on(Phaser.Input.Events.POINTER_UP, () => { - gameStore.setMovingCamera(false) - scene.input.off(Phaser.Input.Events.POINTER_MOVE, dragZone) - }) + scene.input.on(Phaser.Input.Events.POINTER_DOWN, onPointerDown) + scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerUp) } function cleanupEventListeners() { scene.input.off(Phaser.Input.Events.POINTER_MOVE, updateWaypoint) scene.input.off(Phaser.Input.Events.POINTER_MOVE, dragZone) - scene.input.off(Phaser.Input.Events.POINTER_DOWN) - scene.input.off(Phaser.Input.Events.POINTER_UP) + scene.input.off(Phaser.Input.Events.POINTER_DOWN, onPointerDown) + scene.input.off(Phaser.Input.Events.POINTER_UP, onPointerUp) scene.input.off(Phaser.Input.Events.POINTER_WHEEL, handleZoom) + + if (pointerDownTimer) { + clearTimeout(pointerDownTimer) + pointerDownTimer = null + } + if (pointerUpTimer) { + clearTimeout(pointerUpTimer) + pointerUpTimer = null + } } setupEventListeners() diff --git a/src/stores/zoneEditor.ts b/src/stores/zoneEditor.ts index 113c860..1b800a6 100644 --- a/src/stores/zoneEditor.ts +++ b/src/stores/zoneEditor.ts @@ -1,5 +1,5 @@ import { defineStore } from 'pinia' -import { useGameStore } from '@/stores/game'; +import { useGameStore } from '@/stores/game' import type { Zone, Object, Tile, ZoneObject } from '@/types' export const useZoneEditorStore = defineStore('zoneEditor', { @@ -63,9 +63,9 @@ export const useZoneEditorStore = defineStore('zoneEditor', { this.selectedObject = object }, setSelectedZoneObject(zoneObject: ZoneObject) { - const gameStore = useGameStore(); // Access the gameStore - if (gameStore.isMovingCamera) return; // Step 2: Check isMovingCamera before proceeding - + const gameStore = useGameStore() // Access the gameStore + if (gameStore.isMovingCamera) return // Step 2: Check isMovingCamera before proceeding + this.selectedZoneObject = zoneObject }, setObjectDepth(depth: number) {