diff --git a/package-lock.json b/package-lock.json index 8071350..8ac3727 100644 --- a/package-lock.json +++ b/package-lock.json @@ -150,9 +150,9 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.4.tgz", - "integrity": "sha512-NFtZmZsyzDPJnk9Zg3BbTfKKc9UlHYzD0E//p2Z3B9nCwwtJW9T0gVbCz8+fBngnn4zf1Dr3IK8PHQQHq0lDQw==", + "version": "7.25.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.5.tgz", + "integrity": "sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==", "dev": true, "license": "MIT", "dependencies": { @@ -2750,9 +2750,9 @@ } }, "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz", + "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", diff --git a/src/components/World.vue b/src/components/World.vue deleted file mode 100644 index f1a7d43..0000000 --- a/src/components/World.vue +++ /dev/null @@ -1,118 +0,0 @@ -<template> - <TilemapLayerC :tilemap="zoneTilemap" :tileset="exampleTilesArray as any" :layerIndex="0" :cull-padding-x="10" :cull-padding-y="10" /> - <Controls :layer="tiles" /> - - <Container :depth="2"> - <template v-for="item in sortedItems" :key="item.id"> - <Image - v-if="item.type === 'object'" - :x="tileToWorldX(zoneTilemap as any, item.positionX, item.positionY)" - :y="tileToWorldY(zoneTilemap as any, item.positionX, item.positionY)" - :texture="item.object.id" - :originY="Number(item.object.originX)" - :originX="Number(item.object.originY)" - :depth="item.depth > 0 ? item.depth : undefined" - /> - <Character v-else :layer="zoneTilemap as any" :character="item" :depth="item.depth" /> - </template> - </Container> -</template> - -<script setup lang="ts"> -import config from '@/config' -import { Container, Image, TilemapLayer as TilemapLayerC, useScene } from 'phavuer' -import { onBeforeMount, onBeforeUnmount, ref, toRaw, computed } from 'vue' -import Controls from '@/components/utilities/Controls.vue' -import { useGameStore } from '@/stores/game' -import { useAssetStore } from '@/stores/assets' -import type { Zone, ZoneObject, ExtendedCharacter } from '@/types' -import TilemapLayer = Phaser.Tilemaps.TilemapLayer -import { useZoneStore } from '@/stores/zone' -import Character from '@/components/sprites/Character.vue' -import { createZoneData, createTilesetImages, initializeZoneTiles, updateZoneTiles, calculateDepth, sortByDepth, tileToWorldX, tileToWorldY } from '@/services/zone' - -const scene = useScene() -const gameStore = useGameStore() -const assetStore = useAssetStore() -const zoneStore = useZoneStore() - -const zoneData = createZoneData(gameStore.character?.zone?.width ?? 10, gameStore.character?.zone?.height ?? 10, config.tile_size.x, config.tile_size.y) - -const zoneTilemap = new Phaser.Tilemaps.Tilemap(scene, zoneData) -const tilesetImages = createTilesetImages(zoneTilemap, toRaw(assetStore.assets), config.tile_size) - -const tiles = zoneTilemap.createBlankLayer('tiles', tilesetImages, 0, config.tile_size.y) as TilemapLayer -const exampleTilesArray = initializeZoneTiles(zoneTilemap, tiles, gameStore.character?.zone?.width ?? 10, gameStore.character?.zone?.height ?? 10) - -const zoneObjects = ref<ZoneObject[]>([]) - -// Computed property that combines and sorts both objects and characters -const sortedItems = computed(() => { - const objects = zoneObjects.value.map((obj) => ({ - ...obj, - type: 'object' as const, - depth: calculateDepth(obj.positionX, obj.positionY, zoneTilemap.width) - })) - - const characters = zoneStore.characters.map((char) => ({ - ...char, - type: 'character' as const, - depth: calculateDepth(char.positionX, char.positionY, zoneTilemap.width) - })) - - return sortByDepth([...objects, ...characters], zoneTilemap.width) -}) - -// Event listeners -gameStore.connection?.on('zone:character:join', (data: ExtendedCharacter) => { - zoneStore.addCharacter(data) -}) - -gameStore.connection?.on('zone:character:leave', (character_id: number) => { - zoneStore.removeCharacter(character_id) -}) - -gameStore.connection?.on('character:moved', (data: ExtendedCharacter) => { - zoneStore.updateCharacter(data) -}) - -onBeforeMount(() => { - if (gameStore.character?.zone) { - updateZoneTiles(zoneTilemap, tiles, gameStore.character.zone) - } - - zoneObjects.value = gameStore.character?.zone?.zoneObjects ?? [] - - type TResponse = { - zone: Zone - characters: ExtendedCharacter[] - } - - gameStore.connection?.emit('character:zone:request', { zoneId: gameStore.character?.zoneId }, (response: TResponse) => { - zoneStore.setZone(response.zone) - const uniqueCharacters = [...new Set(response.characters)] - zoneStore.setCharacters(uniqueCharacters) - updateZoneTiles(zoneTilemap, tiles, response.zone) - zoneObjects.value = response.zone.zoneObjects - }) -}) - -onBeforeUnmount(() => { - zoneObjects.value = [] - tiles.destroy() - zoneTilemap.removeAllLayers() - zoneTilemap.destroy() - zoneStore.reset() - - gameStore.connection?.emit('character:zone:leave') - gameStore.connection?.off('character:zone:load') - gameStore.connection?.off('zone:character:join') - gameStore.connection?.off('user:disconnect') - gameStore.connection?.off('character:moved') -}) - -// center camera -const centerY = (zoneTilemap.height * zoneTilemap.tileHeight) / 2 -const centerX = (zoneTilemap.width * zoneTilemap.tileWidth) / 2 -scene.cameras.main.centerOn(centerX, centerY) -</script> diff --git a/src/components/Zone.vue b/src/components/Zone.vue new file mode 100644 index 0000000..cb0e589 --- /dev/null +++ b/src/components/Zone.vue @@ -0,0 +1,233 @@ +<template> + <TilemapLayerC :tilemap="zoneTilemap" :tileset="tileArray" :layerIndex="0" :cull-padding="10" /> + <Controls :layer="tiles" /> + + <Container :depth="2"> + <template v-for="item in sortedItems" :key="item.id"> + <Image + v-if="item.type === 'object'" + :x="tileToWorldX(zoneTilemap as any, item.positionX, item.positionY)" + :y="tileToWorldY(zoneTilemap as any, item.positionX, item.positionY)" + :texture="item.object.id" + :originY="Number(item.object.originX)" + :originX="Number(item.object.originY)" + :depth="item.depth > 0 ? item.depth : undefined" + /> + <Character v-else :layer="zoneTilemap as any" :character="item" :depth="item.depth" /> + </template> + </Container> +</template> + +<script setup lang="ts"> +import config from '@/config' +import { Container, Image, TilemapLayer as TilemapLayerC, useScene } from 'phavuer' +import { onBeforeMount, onBeforeUnmount, ref, toRaw, computed, onUnmounted } from 'vue' +import Controls from '@/components/utilities/Controls.vue' +import { useGameStore } from '@/stores/game' +import { useAssetStore } from '@/stores/assets' +import type { Zone, ZoneObject, ExtendedCharacter, CharacterType } from '@/types' +import TilemapLayer = Phaser.Tilemaps.TilemapLayer +import { useZoneStore } from '@/stores/zone' +import Character from '@/components/sprites/Character.vue' +import { + createZoneData, + createTilesetImages, + initializeZoneTiles, + updateZoneTiles, + calculateDepth, + sortByDepth, + tileToWorldX, + tileToWorldY, + placeTile, setAllTiles +} from '@/services/zone' +import { storeToRefs } from 'pinia' +import Tilemap = Phaser.Tilemaps.Tilemap + +const scene = useScene() +const gameStore = useGameStore() +const assetStore = useAssetStore() +const zoneStore = useZoneStore() + +const { zone } = storeToRefs(zoneStore) +type zoneLoadData = { + zone: Zone + characters: ExtendedCharacter[] +} +if (!zone) { + gameStore.connection?.emit('character:zone:request', { zoneId: gameStore.character?.zoneId }, (response: zoneLoadData) => { + zoneStore.setCharacters(response.characters) + zoneStore.setZone(response.zone) + }) +} + +const zoneTilemap = ref(createTilemap()) +const tiles = ref(createTileLayer()) +const zoneObjects = ref<ZoneObject[]>([]) +const tileArray = ref(createTileArray()) + +// Computed property that combines and sorts both objects and characters +const sortedItems = computed(() => { + const objects = zoneObjects.value.map((obj) => ({ + ...obj, + type: 'object' as const, + depth: calculateDepth(obj.positionX, obj.positionY, zoneTilemap.value.width) + })) + + const characters = zoneStore.characters.map((char) => ({ + ...char, + type: 'character' as const, + depth: calculateDepth(char.positionX, char.positionY, zoneTilemap.value.width) + })) + + return sortByDepth([...objects, ...characters], zoneTilemap.value.width) +}) + +function createTilemap() { + const zoneData = new Phaser.Tilemaps.MapData({ + width: zone.value?.width ?? 10, + height: zone.value?.height ?? 10, + tileWidth: config.tile_size.x, + tileHeight: config.tile_size.y, + orientation: Phaser.Tilemaps.Orientation.ISOMETRIC, + format: Phaser.Tilemaps.Formats.ARRAY_2D + }) + return new Phaser.Tilemaps.Tilemap(scene, zoneData) +} + +function createTileLayer() { + const tilesetImages = assetStore.assets.filter((asset) => asset.group === 'tiles').map((asset, index) => zoneTilemap.value.addTilesetImage(asset.key, asset.key, config.tile_size.x, config.tile_size.y, 0, 0, index + 1)) + tilesetImages.push(zoneTilemap.value.addTilesetImage('blank_tile', 'blank_tile', config.tile_size.x, config.tile_size.y, 0, 0, 0)) + return zoneTilemap.value.createBlankLayer('tiles', tilesetImages, 0, config.tile_size.y) +} + +function createTileArray() { + return Array.from({ length: zone.value?.width ?? 0 }, () => Array.from({ length: zone.value?.height ?? 0 }, () => 'blank_tile')) +} + +function getObjectImageProps(object: ZoneObject) { + return { + x: tileToWorldX(zoneTilemap.value as any, object.positionX, object.positionY), + y: tileToWorldY(zoneTilemap.value as any, object.positionX, object.positionY), + texture: object.object.id, + originY: Number(object.object.originX), + originX: Number(object.object.originY) + } +} + +onBeforeMount(() => { + console.log('before mount') + if (!zone.value) { + gameStore.connection?.emit('character:zone:request', { zoneId: gameStore.character?.zoneId }) + } + tileArray.value.forEach((row, y) => row.forEach((_, x) => placeTile(zoneTilemap.value, tiles.value, x, y, 'blank_tile'))) + + + console.log('zone', zone.value) + + if (zone.value?.tiles) { + setAllTiles(zoneTilemap.value, tiles.value, zone.value.tiles) + tileArray.value = zone.value.tiles.map((row) => row.map((tileId) => tileId || 'blank_tile')) + } + + zoneObjects.value = zone.value?.zoneObjects ?? [] + + // Center camera + const centerY = (zoneTilemap.value.height * zoneTilemap.value.tileHeight) / 2 + const centerX = (zoneTilemap.value.width * zoneTilemap.value.tileWidth) / 2 + scene.cameras.main.centerOn(centerX, centerY) +}) + +onBeforeUnmount(() => { + zoneObjects.value = [] + tiles.value.destroy() + zoneTilemap.value.removeAllLayers() + zoneTilemap.value.destroy() + zoneStore.reset() +}) + +gameStore.connection?.on('character:dataUpdated', (data: CharacterType) => { + gameStore.setCharacter(data) +}) + +onUnmounted(() => { + gameStore.connection?.off('character:dataUpdated') +}) + +// const zoneData = createZoneData(gameStore.character?.zone?.width ?? 10, gameStore.character?.zone?.height ?? 10, config.tile_size.x, config.tile_size.y) +// +// const zoneTilemap = new Phaser.Tilemaps.Tilemap(scene, zoneData) +// const tilesetImages = createTilesetImages(zoneTilemap, toRaw(assetStore.assets), config.tile_size) +// +// const tiles = zoneTilemap.createBlankLayer('tiles', tilesetImages, 0, config.tile_size.y) as TilemapLayer +// const exampleTilesArray = initializeZoneTiles(zoneTilemap, tiles, gameStore.character?.zone?.width ?? 10, gameStore.character?.zone?.height ?? 10) +// +// const zoneObjects = ref<ZoneObject[]>([]) +// +// // Computed property that combines and sorts both objects and characters +// const sortedItems = computed(() => { +// const objects = zoneObjects.value.map((obj) => ({ +// ...obj, +// type: 'object' as const, +// depth: calculateDepth(obj.positionX, obj.positionY, zoneTilemap.width) +// })) +// +// const characters = zoneStore.characters.map((char) => ({ +// ...char, +// type: 'character' as const, +// depth: calculateDepth(char.positionX, char.positionY, zoneTilemap.width) +// })) +// +// return sortByDepth([...objects, ...characters], zoneTilemap.width) +// }) +// +// // Event listeners +// gameStore.connection?.on('zone:character:join', (data: ExtendedCharacter) => { +// zoneStore.addCharacter(data) +// }) +// +// gameStore.connection?.on('zone:character:leave', (character_id: number) => { +// zoneStore.removeCharacter(character_id) +// }) +// +// gameStore.connection?.on('character:move', (data: ExtendedCharacter) => { +// zoneStore.updateCharacter(data) +// }) +// +// type zoneLoadData = { +// zone: Zone +// characters: ExtendedCharacter[] +// } +// // +// gameStore.connection?.on('character:zone:load', (data: zoneLoadData) => { +// zoneStore.setZone(data.zone) +// zoneStore.setCharacters(data.characters) +// }) +// +// onBeforeMount(() => { +// if (gameStore.character?.zone) { +// updateZoneTiles(zoneTilemap, tiles, gameStore.character.zone) +// } +// +// zoneObjects.value = gameStore.character?.zone?.zoneObjects ?? [] +// gameStore.connection?.emit('character:zone:request', { zoneId: gameStore.character?.zoneId }) +// }) +// +// onBeforeUnmount(() => { +// zoneObjects.value = [] +// tiles.destroy() +// zoneTilemap.removeAllLayers() +// zoneTilemap.destroy() +// zoneStore.reset() +// +// gameStore.connection?.emit('character:zone:leave') +// gameStore.connection?.off('character:zone:load') +// gameStore.connection?.off('zone:character:join') +// gameStore.connection?.off('user:disconnect') +// gameStore.connection?.off('character:move') +// }) +// +// // center camera +// const centerY = (zoneTilemap.height * zoneTilemap.tileHeight) / 2 +// const centerX = (zoneTilemap.width * zoneTilemap.tileWidth) / 2 +// scene.cameras.main.centerOn(centerX, centerY) +</script> diff --git a/src/components/sprites/Character.vue b/src/components/sprites/Character.vue index 9fa5550..2ff0524 100644 --- a/src/components/sprites/Character.vue +++ b/src/components/sprites/Character.vue @@ -17,6 +17,7 @@ import { Container, Image, RoundRectangle, Sprite, Text } from 'phavuer' import { type ExtendedCharacter as CharacterT } from '@/types' import { tileToWorldX, tileToWorldY } from '@/services/zone' import { watch, computed, ref, onMounted, onUnmounted } from 'vue' +import config from '@/config' interface Props { layer: Phaser.Tilemaps.TilemapLayer @@ -48,19 +49,27 @@ const updatePosition = (x: number, y: number) => { } const distance = Math.sqrt(Math.pow(targetX - currentX.value, 2) + Math.pow(targetY - currentY.value, 2)) - const duration = distance * 5 // Adjust this multiplier to control overall speed - tween.value = props.layer.scene.tweens.add({ - targets: { x: currentX.value, y: currentY.value }, - x: targetX, - y: targetY, - duration: duration, - ease: 'Linear', - onUpdate: (tween) => { - currentX.value = tween.targets[0].x ?? 0 - currentY.value = tween.targets[0].y ?? 0 - } - }) + if (distance > config.tile_size.x) { + // Teleport: No animation + currentX.value = targetX + currentY.value = targetY + } else { + // Normal movement: Animate + const duration = distance * 5 // Adjust this multiplier to control overall speed + + tween.value = props.layer.scene.tweens.add({ + targets: { x: currentX.value, y: currentY.value }, + x: targetX, + y: targetY, + duration: duration, + ease: 'Linear', + onUpdate: (tween) => { + currentX.value = tween.targets[0].x ?? 0 + currentY.value = tween.targets[0].y ?? 0 + } + }) + } } watch( diff --git a/src/components/utilities/zoneEditor/ZoneEditor.vue b/src/components/utilities/zoneEditor/ZoneEditor.vue index 9bb296f..79ff00d 100644 --- a/src/components/utilities/zoneEditor/ZoneEditor.vue +++ b/src/components/utilities/zoneEditor/ZoneEditor.vue @@ -1,6 +1,6 @@ <template> - <TilemapLayerC :tilemap="zoneTilemap" :tileset="tileArray" :layerIndex="0" :cull-padding="10" /> - <Controls :layer="tiles" /> + <TilemapLayerC :tilemap="zoneTilemap as Tilemap" :tileset="tileArray as any" :layerIndex="0" :cull-padding="10" /> + <Controls :layer="tiles as TilemapLayer" /> <Container :depth="2"> <Image v-for="object in sortedZoneObjects" :key="object.id" v-bind="getObjectImageProps(object)" @pointerup="() => zoneEditorStore.setSelectedZoneObject(object)" /> @@ -40,6 +40,8 @@ import ZoneSettings from '@/components/utilities/zoneEditor/partials/ZoneSetting import Objects from '@/components/utilities/zoneEditor/partials/ObjectList.vue' import ZoneList from '@/components/utilities/zoneEditor/partials/ZoneList.vue' import TeleportModal from '@/components/utilities/zoneEditor/partials/TeleportModal.vue' +import Tilemap = Phaser.Tilemaps.Tilemap +import TilemapLayer = Phaser.Tilemaps.TilemapLayer const scene = useScene() const gameStore = useGameStore() @@ -72,7 +74,7 @@ function createTilemap() { function createTileLayer() { const tilesetImages = assetStore.assets.filter((asset) => asset.group === 'tiles').map((asset, index) => zoneTilemap.value.addTilesetImage(asset.key, asset.key, config.tile_size.x, config.tile_size.y, 0, 0, index + 1)) tilesetImages.push(zoneTilemap.value.addTilesetImage('blank_tile', 'blank_tile', config.tile_size.x, config.tile_size.y, 0, 0, 0)) - return zoneTilemap.value.createBlankLayer('tiles', tilesetImages, 0, config.tile_size.y) + return zoneTilemap.value.createBlankLayer('tiles', tilesetImages as any, 0, config.tile_size.y) } function createTileArray() { @@ -82,8 +84,8 @@ function createTileArray() { function getObjectImageProps(object: ZoneObject) { return { tint: selectedZoneObject.value?.id === object.id ? 0x00ff00 : 0xffffff, - x: tileToWorldX(zoneTilemap.value, object.positionX, object.positionY), - y: tileToWorldY(zoneTilemap.value, object.positionX, object.positionY), + x: tileToWorldX(zoneTilemap.value as Tilemap, object.positionX, object.positionY), + y: tileToWorldY(zoneTilemap.value as Tilemap, object.positionX, object.positionY), texture: object.object.id, originY: Number(object.object.originX), originX: Number(object.object.originY) @@ -100,7 +102,7 @@ function getEventTileImageProps(tile: ZoneEventTile) { function eraser(tile: Phaser.Tilemaps.Tile) { if (eraserMode.value === 'tile') { - placeTile(zoneTilemap.value, tiles.value, tile.x, tile.y, 'blank_tile') + placeTile(zoneTilemap.value as Tilemap, tiles.value as TilemapLayer, tile.x, tile.y, 'blank_tile') tileArray.value[tile.y][tile.x] = 'blank_tile' } else if (eraserMode.value === 'object') { zoneObjects.value = zoneObjects.value.filter((object) => object.positionX !== tile.x || object.positionY !== tile.y) @@ -111,7 +113,7 @@ function eraser(tile: Phaser.Tilemaps.Tile) { function pencil(tile: Phaser.Tilemaps.Tile) { if (drawMode.value === 'tile' && selectedTile.value) { - placeTile(zoneTilemap.value, tiles.value, tile.x, tile.y, selectedTile.value.id) + placeTile(zoneTilemap.value as Tilemap, tiles.value as TilemapLayer, tile.x, tile.y, selectedTile.value.id) tileArray.value[tile.y][tile.x] = selectedTile.value.id } else if (drawMode.value === 'object' && selectedObject.value) { addZoneObject(tile) @@ -151,14 +153,14 @@ function addZoneEventTile(tile: Phaser.Tilemaps.Tile) { } : undefined } - zoneEventTiles.value = [...new Set([...zoneEventTiles.value, newEventTile])] + zoneEventTiles.value = [...new Set([...zoneEventTiles.value, newEventTile])] as any } function paint() { if (!selectedTile.value) return tileArray.value.forEach((row, y) => row.forEach((_, x) => { - placeTile(zoneTilemap.value, tiles.value, x, y, selectedTile.value!.id) + placeTile(zoneTilemap.value as Tilemap, tiles.value as TilemapLayer, x, y, selectedTile.value!.id) tileArray.value[y][x] = selectedTile.value!.id }) ) @@ -184,7 +186,7 @@ function save() { } function clear() { - tileArray.value.forEach((row, y) => row.forEach((_, x) => placeTile(zoneTilemap.value, tiles.value, x, y, 'blank_tile'))) + tileArray.value.forEach((row, y) => row.forEach((_, x) => placeTile(zoneTilemap.value as Tilemap, tiles.value as TilemapLayer, x, y, 'blank_tile'))) tileArray.value = createTileArray() zoneEventTiles.value = [] zoneObjects.value = [] diff --git a/src/components/utilities/zoneEditor/partials/ZoneList.vue b/src/components/utilities/zoneEditor/partials/ZoneList.vue index b64e4d8..2182b84 100644 --- a/src/components/utilities/zoneEditor/partials/ZoneList.vue +++ b/src/components/utilities/zoneEditor/partials/ZoneList.vue @@ -29,7 +29,7 @@ </template> <script setup lang="ts"> -import { ref, onMounted } from 'vue' +import { onMounted } from 'vue' import { useGameStore } from '@/stores/game' import Modal from '@/components/utilities/Modal.vue' import type { Zone } from '@/types' @@ -50,7 +50,6 @@ function fetchZones() { } function loadZone(id: number) { - console.log('loadZone', id) gameStore.connection?.emit('gm:zone_editor:zone:request', { zoneId: id }, (response: Zone) => { zoneEditorStore.setZone(response) }) diff --git a/src/composables/useGamePointerHandlers.ts b/src/composables/pointerHandlers/useGamePointerHandlers.ts similarity index 97% rename from src/composables/useGamePointerHandlers.ts rename to src/composables/pointerHandlers/useGamePointerHandlers.ts index 38f8ee2..db323ba 100644 --- a/src/composables/useGamePointerHandlers.ts +++ b/src/composables/pointerHandlers/useGamePointerHandlers.ts @@ -27,7 +27,7 @@ export function useGamePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilema const pointerTile = getTile(px, py, layer) if (pointerTile) { - gameStore.connection?.emit('character:move', { + gameStore.connection?.emit('character:initMove', { positionX: pointerTile.x, positionY: pointerTile.y }) diff --git a/src/composables/useZoneEditorPointerHandlers.ts b/src/composables/pointerHandlers/useZoneEditorPointerHandlers.ts similarity index 100% rename from src/composables/useZoneEditorPointerHandlers.ts rename to src/composables/pointerHandlers/useZoneEditorPointerHandlers.ts diff --git a/src/composables/useCameraControls.ts b/src/composables/useCameraControls.ts index 1c04ec5..d4c81ff 100644 --- a/src/composables/useCameraControls.ts +++ b/src/composables/useCameraControls.ts @@ -5,8 +5,8 @@ export function useCameraControls(scene: Phaser.Scene): any { const gameStore = useGameStore() const camera = ref(scene.cameras.main) const isDragging = ref(false) - let pointerDownTimer: number | null = null - let pointerUpTimer: number | null = null + let pointerDownTimer: number | null | NodeJS.Timeout = null + let pointerUpTimer: number | null | NodeJS.Timeout = null const DRAG_DELAY = 150 const MOVE_RESET_DELAY = 100 diff --git a/src/composables/usePointerHandlers.ts b/src/composables/usePointerHandlers.ts index ce128b6..adcfba4 100644 --- a/src/composables/usePointerHandlers.ts +++ b/src/composables/usePointerHandlers.ts @@ -1,7 +1,7 @@ import { computed, type Ref } from 'vue' import { useZoneEditorStore } from '@/stores/zoneEditor' -import { useGamePointerHandlers } from '@/composables/useGamePointerHandlers' -import { useZoneEditorPointerHandlers } from '@/composables/useZoneEditorPointerHandlers' +import { useGamePointerHandlers } from '@/composables/pointerHandlers/useGamePointerHandlers' +import { useZoneEditorPointerHandlers } from '@/composables/pointerHandlers/useZoneEditorPointerHandlers' export function usePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilemaps.TilemapLayer, waypoint: Ref<{ visible: boolean; x: number; y: number }>, camera: Ref<Phaser.Cameras.Scene2D.Camera>, isDragging: Ref<boolean>) { const zoneEditorStore = useZoneEditorStore() diff --git a/src/screens/Game.vue b/src/screens/Game.vue index cfe7bb7..bd8dbdd 100644 --- a/src/screens/Game.vue +++ b/src/screens/Game.vue @@ -12,7 +12,7 @@ <Hud /> </div> </div> - <World v-if="isLoaded" :key="gameStore.character?.zoneId" /> + <Zone v-if="isLoaded" :key="zoneStore.zone?.id ?? 0" /> <div class="fixed inset-x-0 bottom-0 flex justify-between gap-5 items-end py-10 px-5 xxs:p-10 pointer-events-none max-md:flex-wrap max-md:flex-col-reverse"> <div class="pointer-events-auto w-full"> <Chat /> @@ -37,31 +37,29 @@ <script setup lang="ts"> import config from '@/config' import 'phaser' -import { watch, ref, onBeforeUnmount } from 'vue' +import { watch, ref, onBeforeUnmount, onBeforeMount } from 'vue' import { storeToRefs } from 'pinia' import { Game, Scene } from 'phavuer' import { useGameStore } from '@/stores/game' import { useZoneEditorStore } from '@/stores/zoneEditor' import { useAssetStore } from '@/stores/assets' -import World from '@/components/World.vue' +import { useZoneStore } from '@/stores/zone' import Hud from '@/components/gui/Hud.vue' +import Zone from '@/components/Zone.vue' import Chat from '@/components/gui/Chat.vue' import Menubar from '@/components/gui/Menu.vue' import GmTools from '@/components/utilities/GmTools.vue' import ZoneEditor from '@/components/utilities/zoneEditor/ZoneEditor.vue' import GmPanel from '@/components/utilities/GmPanel.vue' -import Inventory from '@/components/utilities/inventory/Inventory.vue' +// import Inventory from '@/components/utilities/inventory/Inventory.vue' const gameStore = useGameStore() +const zoneStore = useZoneStore() const zoneEditorStore = useZoneEditorStore() const assetStore = useAssetStore() const isLoaded = ref(false) const { assets } = storeToRefs(assetStore) -onBeforeUnmount(() => { - gameStore.disconnectSocket() -}) - const gameConfig = { name: 'New Quest', width: window.innerWidth, @@ -161,10 +159,19 @@ const createScene = (scene: Phaser.Scene) => { }) scene.load.start() - - scene.load.once('complete', () => { - console.log('assets re-loaded') - }) + // scene.load.once('complete', () => {}) }) } + +gameStore.connection?.on('disconnect', () => { + game.scale.resize(window.innerWidth, window.innerHeight) +}) + +onBeforeMount(() => { + gameStore.connection?.emit('character:zone:request', { zoneId: gameStore.character?.zoneId }) +}) + +onBeforeUnmount(() => { + gameStore.disconnectSocket() +}) </script> diff --git a/src/services/zone.ts b/src/services/zone.ts index 5352f68..6b3df35 100644 --- a/src/services/zone.ts +++ b/src/services/zone.ts @@ -23,7 +23,7 @@ export function tileToWorldX(layer: Phaser.Tilemaps.TilemapLayer, pos_x: number, return worldPoint.x + config.tile_size.x / 2 } -export function tileToWorldY(layer: Phaser.Tilemaps.TilemapLayer, pos_x: number, pos_y: number): number { +export function tileToWorldY(layer: TilemapLayer, pos_x: number, pos_y: number): number { const worldPoint = layer.tileToWorldXY(pos_x, pos_y) return worldPoint.y + config.tile_size.y * 1.5 } @@ -86,8 +86,8 @@ export const updateZoneTiles = (zoneTilemap: Tilemap, tiles: Phaser.Tilemaps.Til } // Update the tilemap with any new 'blank_tile' entries - zoneTiles.forEach((row: any, y: number) => { - row.forEach((tileId, x) => { + zoneTiles.forEach((row: any, y: any) => { + row.forEach((tileId: any, x: any) => { placeTile(zoneTilemap, tiles, x, y, tileId) }) }) diff --git a/src/stores/game.ts b/src/stores/game.ts index 0b96d95..5145440 100644 --- a/src/stores/game.ts +++ b/src/stores/game.ts @@ -70,6 +70,9 @@ export const useGameStore = defineStore('game', { this.token = null this.user = null this.character = null + this.isGmPanelOpen = false + this.isMovingCamera = false + this.isChatOpen = false useCookies().remove('token') }