From bdc2ba35c9aabbe140bc678e1247af966fef06ce Mon Sep 17 00:00:00 2001 From: Dennis Postma <dennis@directonline.io> Date: Sat, 24 Aug 2024 03:07:48 +0200 Subject: [PATCH] Major refractor, cleaning and improvements. --- .eslintrc.cjs | 10 +- package-lock.json | 12 +- src/components/Zone.vue | 233 ------------------ .../{utilities => gameMaster}/GmPanel.vue | 2 +- .../{utilities => gameMaster}/GmTools.vue | 0 .../assetManager/AssetManager.vue | 12 +- .../partials/object/ObjectDetails.vue | 0 .../partials/object/ObjectList.vue | 0 .../partials/sprite/SpriteDetails.vue | 2 +- .../partials/sprite/SpriteList.vue | 0 .../sprite/partials/SpriteImagesInput.vue | 0 .../partials/tile/TileDetails.vue | 0 .../assetManager/partials/tile/TileList.vue | 0 .../zoneEditor/ZoneEditor.vue | 14 +- .../zoneEditor/partials/CreateZone.vue | 0 .../zoneEditor/partials/ObjectList.vue | 0 .../partials/SelectedZoneObject.vue | 0 .../zoneEditor/partials/TeleportModal.vue | 0 .../zoneEditor/partials/TileList.vue | 0 .../zoneEditor/partials/Toolbar.vue | 0 .../zoneEditor/partials/ZoneList.vue | 2 +- .../zoneEditor/partials/ZoneSettings.vue | 2 +- .../inventory => gui}/Inventory.vue | 0 src/components/zone/Characters.vue | 14 ++ src/components/zone/Objects.vue | 7 + src/components/zone/Tiles.vue | 61 +++++ src/components/zone/Zone.vue | 41 +++ .../pointerHandlers/useGamePointerHandlers.ts | 11 +- src/composables/useCameraControls.ts | 2 +- src/composables/usePointerHandlers.ts | 30 +-- src/config.ts | 4 +- src/screens/Characters.vue | 1 + src/screens/Game.vue | 26 +- 33 files changed, 188 insertions(+), 298 deletions(-) delete mode 100644 src/components/Zone.vue rename src/components/{utilities => gameMaster}/GmPanel.vue (93%) rename src/components/{utilities => gameMaster}/GmTools.vue (100%) rename src/components/{utilities => gameMaster}/assetManager/AssetManager.vue (83%) rename src/components/{utilities => gameMaster}/assetManager/partials/object/ObjectDetails.vue (100%) rename src/components/{utilities => gameMaster}/assetManager/partials/object/ObjectList.vue (100%) rename src/components/{utilities => gameMaster}/assetManager/partials/sprite/SpriteDetails.vue (98%) rename src/components/{utilities => gameMaster}/assetManager/partials/sprite/SpriteList.vue (100%) rename src/components/{utilities => gameMaster}/assetManager/partials/sprite/partials/SpriteImagesInput.vue (100%) rename src/components/{utilities => gameMaster}/assetManager/partials/tile/TileDetails.vue (100%) rename src/components/{utilities => gameMaster}/assetManager/partials/tile/TileList.vue (100%) rename src/components/{utilities => gameMaster}/zoneEditor/ZoneEditor.vue (93%) rename src/components/{utilities => gameMaster}/zoneEditor/partials/CreateZone.vue (100%) rename src/components/{utilities => gameMaster}/zoneEditor/partials/ObjectList.vue (100%) rename src/components/{utilities => gameMaster}/zoneEditor/partials/SelectedZoneObject.vue (100%) rename src/components/{utilities => gameMaster}/zoneEditor/partials/TeleportModal.vue (100%) rename src/components/{utilities => gameMaster}/zoneEditor/partials/TileList.vue (100%) rename src/components/{utilities => gameMaster}/zoneEditor/partials/Toolbar.vue (100%) rename src/components/{utilities => gameMaster}/zoneEditor/partials/ZoneList.vue (96%) rename src/components/{utilities => gameMaster}/zoneEditor/partials/ZoneSettings.vue (97%) rename src/components/{utilities/inventory => gui}/Inventory.vue (100%) create mode 100644 src/components/zone/Characters.vue create mode 100644 src/components/zone/Objects.vue create mode 100644 src/components/zone/Tiles.vue create mode 100644 src/components/zone/Zone.vue diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 6f40582..5d7bb6d 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -3,13 +3,11 @@ require('@rushstack/eslint-patch/modern-module-resolution') module.exports = { root: true, - 'extends': [ - 'plugin:vue/vue3-essential', - 'eslint:recommended', - '@vue/eslint-config-typescript', - '@vue/eslint-config-prettier/skip-formatting' - ], + extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/eslint-config-typescript', '@vue/eslint-config-prettier/skip-formatting'], parserOptions: { ecmaVersion: 'latest' + }, + rules: { + 'vue/multi-word-component-names': 'off' } } diff --git a/package-lock.json b/package-lock.json index 8ac3727..6598a1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4915,9 +4915,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -6750,9 +6750,9 @@ "license": "Apache-2.0" }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true, "license": "0BSD" }, diff --git a/src/components/Zone.vue b/src/components/Zone.vue deleted file mode 100644 index cb0e589..0000000 --- a/src/components/Zone.vue +++ /dev/null @@ -1,233 +0,0 @@ -<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/utilities/GmPanel.vue b/src/components/gameMaster/GmPanel.vue similarity index 93% rename from src/components/utilities/GmPanel.vue rename to src/components/gameMaster/GmPanel.vue index 553e8cd..cf5c9db 100644 --- a/src/components/utilities/GmPanel.vue +++ b/src/components/gameMaster/GmPanel.vue @@ -20,7 +20,7 @@ <script setup lang="ts"> import { ref } from 'vue' import Modal from '@/components/utilities/Modal.vue' -import AssetManager from '@/components/utilities/assetManager/AssetManager.vue' +import AssetManager from '@/components/gameMaster/assetManager/AssetManager.vue' import { useGameStore } from '@/stores/game' const gameStore = useGameStore() diff --git a/src/components/utilities/GmTools.vue b/src/components/gameMaster/GmTools.vue similarity index 100% rename from src/components/utilities/GmTools.vue rename to src/components/gameMaster/GmTools.vue diff --git a/src/components/utilities/assetManager/AssetManager.vue b/src/components/gameMaster/assetManager/AssetManager.vue similarity index 83% rename from src/components/utilities/assetManager/AssetManager.vue rename to src/components/gameMaster/assetManager/AssetManager.vue index 2d185b9..9d2d083 100644 --- a/src/components/utilities/assetManager/AssetManager.vue +++ b/src/components/gameMaster/assetManager/AssetManager.vue @@ -58,12 +58,12 @@ <script setup lang="ts"> import { ref } from 'vue' import { useAssetManagerStore } from '@/stores/assetManager' -import TileList from '@/components/utilities/assetManager/partials/tile/TileList.vue' -import TileDetails from '@/components/utilities/assetManager/partials/tile/TileDetails.vue' -import ObjectList from '@/components/utilities/assetManager/partials/object/ObjectList.vue' -import ObjectDetails from '@/components/utilities/assetManager/partials/object/ObjectDetails.vue' -import SpriteList from '@/components/utilities/assetManager/partials/sprite/SpriteList.vue' -import SpriteDetails from '@/components/utilities/assetManager/partials/sprite/SpriteDetails.vue' +import TileList from '@/components/gameMaster/assetManager/partials/tile/TileList.vue' +import TileDetails from '@/components/gameMaster/assetManager/partials/tile/TileDetails.vue' +import ObjectList from '@/components/gameMaster/assetManager/partials/object/ObjectList.vue' +import ObjectDetails from '@/components/gameMaster/assetManager/partials/object/ObjectDetails.vue' +import SpriteList from '@/components/gameMaster/assetManager/partials/sprite/SpriteList.vue' +import SpriteDetails from '@/components/gameMaster/assetManager/partials/sprite/SpriteDetails.vue' const assetManagerStore = useAssetManagerStore() const selectedCategory = ref('tiles') diff --git a/src/components/utilities/assetManager/partials/object/ObjectDetails.vue b/src/components/gameMaster/assetManager/partials/object/ObjectDetails.vue similarity index 100% rename from src/components/utilities/assetManager/partials/object/ObjectDetails.vue rename to src/components/gameMaster/assetManager/partials/object/ObjectDetails.vue diff --git a/src/components/utilities/assetManager/partials/object/ObjectList.vue b/src/components/gameMaster/assetManager/partials/object/ObjectList.vue similarity index 100% rename from src/components/utilities/assetManager/partials/object/ObjectList.vue rename to src/components/gameMaster/assetManager/partials/object/ObjectList.vue diff --git a/src/components/utilities/assetManager/partials/sprite/SpriteDetails.vue b/src/components/gameMaster/assetManager/partials/sprite/SpriteDetails.vue similarity index 98% rename from src/components/utilities/assetManager/partials/sprite/SpriteDetails.vue rename to src/components/gameMaster/assetManager/partials/sprite/SpriteDetails.vue index bd1fb6e..a3c53eb 100644 --- a/src/components/utilities/assetManager/partials/sprite/SpriteDetails.vue +++ b/src/components/gameMaster/assetManager/partials/sprite/SpriteDetails.vue @@ -70,7 +70,7 @@ import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue' import { useAssetManagerStore } from '@/stores/assetManager' import { useGameStore } from '@/stores/game' import Accordion from '@/components/utilities/Accordion.vue' -import SpriteActionsInput from '@/components/utilities/assetManager/partials/sprite/partials/SpriteImagesInput.vue' +import SpriteActionsInput from '@/components/gameMaster/assetManager/partials/sprite/partials/SpriteImagesInput.vue' import { uuidv4 } from '@/utilities' const gameStore = useGameStore() diff --git a/src/components/utilities/assetManager/partials/sprite/SpriteList.vue b/src/components/gameMaster/assetManager/partials/sprite/SpriteList.vue similarity index 100% rename from src/components/utilities/assetManager/partials/sprite/SpriteList.vue rename to src/components/gameMaster/assetManager/partials/sprite/SpriteList.vue diff --git a/src/components/utilities/assetManager/partials/sprite/partials/SpriteImagesInput.vue b/src/components/gameMaster/assetManager/partials/sprite/partials/SpriteImagesInput.vue similarity index 100% rename from src/components/utilities/assetManager/partials/sprite/partials/SpriteImagesInput.vue rename to src/components/gameMaster/assetManager/partials/sprite/partials/SpriteImagesInput.vue diff --git a/src/components/utilities/assetManager/partials/tile/TileDetails.vue b/src/components/gameMaster/assetManager/partials/tile/TileDetails.vue similarity index 100% rename from src/components/utilities/assetManager/partials/tile/TileDetails.vue rename to src/components/gameMaster/assetManager/partials/tile/TileDetails.vue diff --git a/src/components/utilities/assetManager/partials/tile/TileList.vue b/src/components/gameMaster/assetManager/partials/tile/TileList.vue similarity index 100% rename from src/components/utilities/assetManager/partials/tile/TileList.vue rename to src/components/gameMaster/assetManager/partials/tile/TileList.vue diff --git a/src/components/utilities/zoneEditor/ZoneEditor.vue b/src/components/gameMaster/zoneEditor/ZoneEditor.vue similarity index 93% rename from src/components/utilities/zoneEditor/ZoneEditor.vue rename to src/components/gameMaster/zoneEditor/ZoneEditor.vue index 79ff00d..428b16f 100644 --- a/src/components/utilities/zoneEditor/ZoneEditor.vue +++ b/src/components/gameMaster/zoneEditor/ZoneEditor.vue @@ -33,13 +33,13 @@ import config from '@/config' // Components import Controls from '@/components/utilities/Controls.vue' -import Toolbar from '@/components/utilities/zoneEditor/partials/Toolbar.vue' -import Tiles from '@/components/utilities/zoneEditor/partials/TileList.vue' -import SelectedZoneObject from '@/components/utilities/zoneEditor/partials/SelectedZoneObject.vue' -import ZoneSettings from '@/components/utilities/zoneEditor/partials/ZoneSettings.vue' -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 Toolbar from '@/components/gameMaster/zoneEditor/partials/Toolbar.vue' +import Tiles from '@/components/gameMaster/zoneEditor/partials/TileList.vue' +import SelectedZoneObject from '@/components/gameMaster/zoneEditor/partials/SelectedZoneObject.vue' +import ZoneSettings from '@/components/gameMaster/zoneEditor/partials/ZoneSettings.vue' +import Objects from '@/components/gameMaster/zoneEditor/partials/ObjectList.vue' +import ZoneList from '@/components/gameMaster/zoneEditor/partials/ZoneList.vue' +import TeleportModal from '@/components/gameMaster/zoneEditor/partials/TeleportModal.vue' import Tilemap = Phaser.Tilemaps.Tilemap import TilemapLayer = Phaser.Tilemaps.TilemapLayer diff --git a/src/components/utilities/zoneEditor/partials/CreateZone.vue b/src/components/gameMaster/zoneEditor/partials/CreateZone.vue similarity index 100% rename from src/components/utilities/zoneEditor/partials/CreateZone.vue rename to src/components/gameMaster/zoneEditor/partials/CreateZone.vue diff --git a/src/components/utilities/zoneEditor/partials/ObjectList.vue b/src/components/gameMaster/zoneEditor/partials/ObjectList.vue similarity index 100% rename from src/components/utilities/zoneEditor/partials/ObjectList.vue rename to src/components/gameMaster/zoneEditor/partials/ObjectList.vue diff --git a/src/components/utilities/zoneEditor/partials/SelectedZoneObject.vue b/src/components/gameMaster/zoneEditor/partials/SelectedZoneObject.vue similarity index 100% rename from src/components/utilities/zoneEditor/partials/SelectedZoneObject.vue rename to src/components/gameMaster/zoneEditor/partials/SelectedZoneObject.vue diff --git a/src/components/utilities/zoneEditor/partials/TeleportModal.vue b/src/components/gameMaster/zoneEditor/partials/TeleportModal.vue similarity index 100% rename from src/components/utilities/zoneEditor/partials/TeleportModal.vue rename to src/components/gameMaster/zoneEditor/partials/TeleportModal.vue diff --git a/src/components/utilities/zoneEditor/partials/TileList.vue b/src/components/gameMaster/zoneEditor/partials/TileList.vue similarity index 100% rename from src/components/utilities/zoneEditor/partials/TileList.vue rename to src/components/gameMaster/zoneEditor/partials/TileList.vue diff --git a/src/components/utilities/zoneEditor/partials/Toolbar.vue b/src/components/gameMaster/zoneEditor/partials/Toolbar.vue similarity index 100% rename from src/components/utilities/zoneEditor/partials/Toolbar.vue rename to src/components/gameMaster/zoneEditor/partials/Toolbar.vue diff --git a/src/components/utilities/zoneEditor/partials/ZoneList.vue b/src/components/gameMaster/zoneEditor/partials/ZoneList.vue similarity index 96% rename from src/components/utilities/zoneEditor/partials/ZoneList.vue rename to src/components/gameMaster/zoneEditor/partials/ZoneList.vue index 2182b84..0e17e90 100644 --- a/src/components/utilities/zoneEditor/partials/ZoneList.vue +++ b/src/components/gameMaster/zoneEditor/partials/ZoneList.vue @@ -34,7 +34,7 @@ import { useGameStore } from '@/stores/game' import Modal from '@/components/utilities/Modal.vue' import type { Zone } from '@/types' import { useZoneEditorStore } from '@/stores/zoneEditor' -import CreateZone from '@/components/utilities/zoneEditor/partials/CreateZone.vue' +import CreateZone from '@/components/gameMaster/zoneEditor/partials/CreateZone.vue' const gameStore = useGameStore() const zoneEditorStore = useZoneEditorStore() diff --git a/src/components/utilities/zoneEditor/partials/ZoneSettings.vue b/src/components/gameMaster/zoneEditor/partials/ZoneSettings.vue similarity index 97% rename from src/components/utilities/zoneEditor/partials/ZoneSettings.vue rename to src/components/gameMaster/zoneEditor/partials/ZoneSettings.vue index 2a00ea2..7743a1f 100644 --- a/src/components/utilities/zoneEditor/partials/ZoneSettings.vue +++ b/src/components/gameMaster/zoneEditor/partials/ZoneSettings.vue @@ -37,7 +37,7 @@ <script setup> import { ref, watch } from 'vue' import Modal from '@/components/utilities/Modal.vue' -import { useZoneEditorStore } from '@/stores/zoneEditor' +import { useZoneEditorStore } from '@/stores/zoneEditor.ts' const zoneEditorStore = useZoneEditorStore() diff --git a/src/components/utilities/inventory/Inventory.vue b/src/components/gui/Inventory.vue similarity index 100% rename from src/components/utilities/inventory/Inventory.vue rename to src/components/gui/Inventory.vue diff --git a/src/components/zone/Characters.vue b/src/components/zone/Characters.vue new file mode 100644 index 0000000..fce2790 --- /dev/null +++ b/src/components/zone/Characters.vue @@ -0,0 +1,14 @@ +<template> + <Character v-for="item in zoneStore.characters" :key="item.id" :layer="zoneTilemap as any" :character="item" :depth="item.depth" /> +</template> + +<script setup lang="ts"> +import Character from '@/components/sprites/Character.vue' +import { useZoneStore } from '@/stores/zone' +import { useGameStore } from '@/stores/game' +import { useAssetStore } from '@/stores/assets' +import { useZoneEditorStore } from '@/stores/zoneEditor' + +const gameStore = useGameStore() +const zoneStore = useZoneStore() +</script> diff --git a/src/components/zone/Objects.vue b/src/components/zone/Objects.vue new file mode 100644 index 0000000..d0e7cdb --- /dev/null +++ b/src/components/zone/Objects.vue @@ -0,0 +1,7 @@ +<template> + +</template> + +<script setup lang="ts"> + +</script> \ No newline at end of file diff --git a/src/components/zone/Tiles.vue b/src/components/zone/Tiles.vue new file mode 100644 index 0000000..a3aff15 --- /dev/null +++ b/src/components/zone/Tiles.vue @@ -0,0 +1,61 @@ +<template> + <TilemapLayer :tilemap="zoneTilemap" :tileset="tileArray" :layerIndex="0" :cull-padding="10" /> + <Controls :layer="tiles" /> +</template> + +<script setup lang="ts"> +import config from '@/config' +import { TilemapLayer, useScene } from 'phavuer' +import { useAssetStore } from '@/stores/assets' +import { useZoneStore } from '@/stores/zone' +import { onBeforeMount, onBeforeUnmount, ref } from 'vue' +import { storeToRefs } from 'pinia' +import { placeTile, setAllTiles } from '@/services/zone' +import Controls from '@/components/utilities/Controls.vue' + +const assetStore = useAssetStore() +const zoneStore = useZoneStore() +const scene = useScene() + +const { zone } = storeToRefs(zoneStore) +const zoneTilemap = ref(createTilemap()) +const tiles = ref(createTileLayer()) +const tileArray = ref(createTileArray()) + +function createTilemap() { + const zoneData = new Phaser.Tilemaps.MapData({ + width: zone.value?.width, + height: zone.value?.height, + 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')) +} + +onBeforeMount(() => { + tileArray.value.forEach((row, y) => row.forEach((_, x) => placeTile(zoneTilemap.value, tiles.value, x, y, 'blank_tile'))) + + 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')) + } +}) + +onBeforeUnmount(() => { + tiles.value?.destroy() + zoneTilemap.value.removeAllLayers() + zoneTilemap.value.destroy() +}) +</script> \ No newline at end of file diff --git a/src/components/zone/Zone.vue b/src/components/zone/Zone.vue new file mode 100644 index 0000000..749a979 --- /dev/null +++ b/src/components/zone/Zone.vue @@ -0,0 +1,41 @@ +<template> + <Tiles :key="zoneStore.zone?.id ?? 0" /> + <Objects /> + <Characters /> +</template> + +<script setup lang="ts"> +import { useGameStore } from '@/stores/game' +import { useZoneStore } from '@/stores/zone' +import { onBeforeMount, onBeforeUnmount, watch } from 'vue' +import type { Character as CharacterT, Zone as ZoneT } from '@/types' +import Tiles from '@/components/zone/Tiles.vue' +import Objects from '@/components/zone/Objects.vue' +import Characters from '@/components/zone/Characters.vue' + +const gameStore = useGameStore() +const zoneStore = useZoneStore() + +type zoneLoadData = { + zone: ZoneT + characters: CharacterT[] +} + +gameStore.connection?.emit('zone:characterJoin', { zoneId: gameStore.character?.zoneId }, (response: zoneLoadData) => { + zoneStore.setZone(response.zone) + zoneStore.setCharacters(response.characters) +}) + +watch(() => zoneStore.zone, (newZone) => { + console.log('Zone changed:', newZone) +}, { deep: true }) + + +onBeforeMount(() => { + +}); + +onBeforeUnmount(() => { + +}); +</script> diff --git a/src/composables/pointerHandlers/useGamePointerHandlers.ts b/src/composables/pointerHandlers/useGamePointerHandlers.ts index db323ba..0328799 100644 --- a/src/composables/pointerHandlers/useGamePointerHandlers.ts +++ b/src/composables/pointerHandlers/useGamePointerHandlers.ts @@ -3,7 +3,7 @@ import { getTile, tileToWorldXY } from '@/services/zone' import { useGameStore } from '@/stores/game' import config from '@/config' -export function useGamePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilemaps.TilemapLayer, waypoint: Ref<{ visible: boolean; x: number; y: number }>, camera: Ref<Phaser.Cameras.Scene2D.Camera>) { +export function useGamePointerHandlers(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 gameStore = useGameStore() function updateWaypoint(pointer: Phaser.Input.Pointer) { @@ -18,7 +18,16 @@ export function useGamePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilema } } + function dragZone(pointer: Phaser.Input.Pointer) { + if (isDragging.value) { + const { x, y, prevPosition } = pointer + const { scrollX, scrollY, zoom } = camera.value + camera.value.setScroll(scrollX - (x - prevPosition.x) / zoom, scrollY - (y - prevPosition.y) / zoom) + } + } + function handlePointerMove(pointer: Phaser.Input.Pointer) { + dragZone(pointer) updateWaypoint(pointer) } diff --git a/src/composables/useCameraControls.ts b/src/composables/useCameraControls.ts index d4c81ff..ae4d7fd 100644 --- a/src/composables/useCameraControls.ts +++ b/src/composables/useCameraControls.ts @@ -12,7 +12,7 @@ export function useCameraControls(scene: Phaser.Scene): any { const MOVE_RESET_DELAY = 100 function onPointerDown(pointer: Phaser.Input.Pointer) { - if (pointer.event instanceof MouseEvent || pointer.event.altKey) { + if (pointer.event instanceof MouseEvent || pointer.event.shiftKey) { pointerDownTimer = setTimeout(() => { isDragging.value = true gameStore.setMovingCamera(true) diff --git a/src/composables/usePointerHandlers.ts b/src/composables/usePointerHandlers.ts index adcfba4..1efeb52 100644 --- a/src/composables/usePointerHandlers.ts +++ b/src/composables/usePointerHandlers.ts @@ -1,30 +1,32 @@ -import { computed, type Ref } from 'vue' +import { computed, type Ref, watch } from 'vue' import { useZoneEditorStore } from '@/stores/zoneEditor' import { useGamePointerHandlers } from '@/composables/pointerHandlers/useGamePointerHandlers' import { useZoneEditorPointerHandlers } from '@/composables/pointerHandlers/useZoneEditorPointerHandlers' +import { useGameStore } from '@/stores/game' 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 gameStore = useGameStore() const zoneEditorStore = useZoneEditorStore() - const isZoneEditorActive = computed(() => zoneEditorStore.active) - const gameHandlers = useGamePointerHandlers(scene, layer, waypoint, camera) + const gameHandlers = useGamePointerHandlers(scene, layer, waypoint, camera, isDragging) const zoneEditorHandlers = useZoneEditorPointerHandlers(scene, layer, waypoint, camera, isDragging) + let currentHandlers = computed(() => zoneEditorStore.active ? zoneEditorHandlers : gameHandlers) + const setupPointerHandlers = () => { - if (isZoneEditorActive.value) { - zoneEditorHandlers.setupPointerHandlers() - } else { - gameHandlers.setupPointerHandlers() - } + currentHandlers.value.setupPointerHandlers() } const cleanupPointerHandlers = () => { - if (isZoneEditorActive.value) { - zoneEditorHandlers.cleanupPointerHandlers() - } else { - gameHandlers.cleanupPointerHandlers() - } + currentHandlers.value.cleanupPointerHandlers() } + watch(() => zoneEditorStore.active, (newValue, oldValue) => { + if (newValue !== oldValue) { + cleanupPointerHandlers() + setupPointerHandlers() + } + }) + return { setupPointerHandlers, cleanupPointerHandlers } -} +} \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index 7793640..a663e30 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,8 +1,8 @@ -const dev: boolean = false +const dev: boolean = true export default { name: 'New Quest', development: dev, server_endpoint: dev ? 'http://localhost:4000' : 'https://nq-server.cr-a.directonline.io', - tile_size: { x: 64, y: 32, z: 1 }, + tile_size: { x: 64, y: 32, z: 1 } } diff --git a/src/screens/Characters.vue b/src/screens/Characters.vue index 228eb19..0ebe8c3 100644 --- a/src/screens/Characters.vue +++ b/src/screens/Characters.vue @@ -74,6 +74,7 @@ import { useGameStore } from '@/stores/game' import { onBeforeMount, onBeforeUnmount, onMounted, ref } from 'vue' import Modal from '@/components/utilities/Modal.vue' import { type Character as CharacterT } from '@/types' +import { useZoneStore } from '@/stores/zone' const isLoading = ref(true) const characters = ref([]) diff --git a/src/screens/Game.vue b/src/screens/Game.vue index a0e72af..6c4fac2 100644 --- a/src/screens/Game.vue +++ b/src/screens/Game.vue @@ -5,14 +5,14 @@ <Inventory /> <div v-if="!zoneEditorStore.active"> - <Game :config="gameConfig" @create="createGame"> + <Game :config="gameConfig" @create="createGame" class="111mt-[-60px]"> <Scene name="main" @preload="preloadScene" @create="createScene"> <div class="fixed inset-x-0 top-0 flex justify-start items-end p-10 pointer-events-none"> <div class="pointer-events-auto"> <Hud /> </div> </div> - <Zone v-if="isLoaded" :key="zoneStore.zone?.id ?? 0" /> + <Zone v-if="isLoaded" /> <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,24 +37,22 @@ <script setup lang="ts"> import config from '@/config' import 'phaser' -import { watch, ref, onBeforeUnmount, onBeforeMount } from 'vue' +import { watch, ref, onBeforeUnmount } 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 { useZoneStore } from '@/stores/zone' import Hud from '@/components/gui/Hud.vue' -import Zone from '@/components/Zone.vue' +import Zone from '@/components/zone/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 GmTools from '@/components/gameMaster/GmTools.vue' +import ZoneEditor from '@/components/gameMaster/zoneEditor/ZoneEditor.vue' +import GmPanel from '@/components/gameMaster/GmPanel.vue' +import Inventory from '@/components/gui/Inventory.vue' const gameStore = useGameStore() -const zoneStore = useZoneStore() const zoneEditorStore = useZoneEditorStore() const assetStore = useAssetStore() const isLoaded = ref(false) @@ -163,14 +161,6 @@ const createScene = (scene: Phaser.Scene) => { }) } -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() })