Started streamlining map editor with regular map logic

This commit is contained in:
Dennis Postma 2025-01-22 20:34:56 +01:00
parent 41005735f9
commit ebd6d96e54
4 changed files with 83 additions and 99 deletions

View File

@ -0,0 +1,20 @@
<template>
<MapTiles @tileMap:create="tileMap = $event" />
<PlacedMapObjects v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
<MapEventTiles v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
</template>
<script setup lang="ts">
import MapEventTiles from '@/components/gameMaster/mapEditor/mapPartials/MapEventTiles.vue'
import MapTiles from '@/components/gameMaster/mapEditor/mapPartials/MapTiles.vue'
import PlacedMapObjects from '@/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue'
import { useMapEditorStore } from '@/stores/mapEditorStore'
import { onUnmounted, shallowRef } from 'vue'
const mapEditorStore = useMapEditorStore()
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
onUnmounted(() => {
mapEditorStore.reset()
})
</script>

View File

@ -1,72 +0,0 @@
<template>
<MapTiles @tileMap:create="tileMap = $event" />
<PlacedMapObjects v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
<MapEventTiles v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
<Toolbar @save="save" @clear="clear" />
<MapList />
<TileList />
<ObjectList />
<MapSettings />
<TeleportModal />
</template>
<script setup lang="ts">
import { type Map } from '@/application/types'
import MapEventTiles from '@/components/gameMaster/mapEditor/mapPartials/MapEventTiles.vue'
import MapTiles from '@/components/gameMaster/mapEditor/mapPartials/MapTiles.vue'
import PlacedMapObjects from '@/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue'
import MapList from '@/components/gameMaster/mapEditor/partials/MapList.vue'
import ObjectList from '@/components/gameMaster/mapEditor/partials/MapObjectList.vue'
import MapSettings from '@/components/gameMaster/mapEditor/partials/MapSettings.vue'
import TeleportModal from '@/components/gameMaster/mapEditor/partials/TeleportModal.vue'
import TileList from '@/components/gameMaster/mapEditor/partials/TileList.vue'
import Toolbar from '@/components/gameMaster/mapEditor/partials/Toolbar.vue'
import { useGameStore } from '@/stores/gameStore'
import { useMapEditorStore } from '@/stores/mapEditorStore'
import { onUnmounted, shallowRef } from 'vue'
const gameStore = useGameStore()
const mapEditorStore = useMapEditorStore()
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
function clear() {
if (!mapEditorStore.map) return
// Clear objects, event tiles and tiles
mapEditorStore.map.placedMapObjects = []
mapEditorStore.map.mapEventTiles = []
mapEditorStore.triggerClearTiles()
}
function save() {
if (!mapEditorStore.map) return
const data = {
mapId: mapEditorStore.map.id,
name: mapEditorStore.mapSettings.name,
width: mapEditorStore.mapSettings.width,
height: mapEditorStore.mapSettings.height,
tiles: mapEditorStore.map.tiles,
pvp: mapEditorStore.map.pvp,
mapEffects: mapEditorStore.map.mapEffects?.map(({ id, effect, strength }) => ({ id, effect, strength })) ?? [],
mapEventTiles: mapEditorStore.map.mapEventTiles?.map(({ id, type, positionX, positionY, teleport }) => ({ id, type, positionX, positionY, teleport })) ?? [],
placedMapObjects: mapEditorStore.map.placedMapObjects?.map(({ id, mapObject, depth, isRotated, positionX, positionY }) => ({ id, mapObject, depth, isRotated, positionX, positionY })) ?? []
}
if (mapEditorStore.isSettingsModalShown) {
mapEditorStore.toggleSettingsModal()
}
gameStore.connection?.emit('gm:map:update', data, (response: Map) => {
mapEditorStore.setMap(response)
})
}
onUnmounted(() => {
mapEditorStore.reset()
})
</script>

View File

@ -1,9 +1,20 @@
<template>
<div class="flex justify-center items-center h-dvh relative">
<Game :config="gameConfig" @create="createGame">
<Scene name="main" @preload="preloadScene" @create="createScene">
<MapEditor :key="JSON.stringify(`${mapEditorStore.map?.id}_${mapEditorStore.map?.createdAt}_${mapEditorStore.map?.updatedAt}`)" v-if="isLoaded" />
<div v-else class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-white text-3xl font-ui">Loading...</div>
<Scene name="main" @preload="preloadScene">
<div v-if="!isLoaded" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-white text-3xl font-ui">Loading...</div>
<div v-else>
<Map :key="mapEditorStore.mapId" />
<Toolbar @save="save" @clear="clear" />
<MapList />
<TileList />
<ObjectList />
<MapSettings />
<TeleportModal />
</div>
</Scene>
</Game>
</div>
@ -12,17 +23,25 @@
<script setup lang="ts">
import config from '@/application/config'
import 'phaser'
import MapEditor from '@/components/gameMaster/mapEditor/MapEditor.vue'
import Map from '@/components/gameMaster/mapEditor/Map.vue'
import MapList from '@/components/gameMaster/mapEditor/partials/MapList.vue'
import ObjectList from '@/components/gameMaster/mapEditor/partials/MapObjectList.vue'
import MapSettings from '@/components/gameMaster/mapEditor/partials/MapSettings.vue'
import TeleportModal from '@/components/gameMaster/mapEditor/partials/TeleportModal.vue'
import TileList from '@/components/gameMaster/mapEditor/partials/TileList.vue'
import Toolbar from '@/components/gameMaster/mapEditor/partials/Toolbar.vue'
import { loadAllTilesIntoScene } from '@/composables/mapComposable'
import { useGameStore } from '@/stores/gameStore'
import { useMapEditorStore } from '@/stores/mapEditorStore'
import { Game, Scene } from 'phavuer'
import { ref } from 'vue'
import type { Map as MapT } from '@/application/types'
const gameStore = useGameStore()
const mapEditorStore = useMapEditorStore()
const isLoaded = ref(false)
const currentMap = ref<MapT | null>(null)
const gameConfig = {
name: config.name,
@ -37,15 +56,6 @@ const createGame = (game: Phaser.Game) => {
addEventListener('resize', () => {
game.scale.resize(window.innerWidth, window.innerHeight)
})
// We don't support canvas mode, only WebGL
if (game.renderer.type === Phaser.CANVAS) {
gameStore.addNotification({
title: 'Warning',
message: 'Your browser does not support WebGL. Please use a modern browser like Chrome, Firefox, or Edge.'
})
gameStore.disconnectSocket()
}
}
const preloadScene = async (scene: Phaser.Scene) => {
@ -65,5 +75,36 @@ const preloadScene = async (scene: Phaser.Scene) => {
})
}
const createScene = async (scene: Phaser.Scene) => {}
function save() {
if (!mapEditorStore.map) return
const data = {
mapId: mapEditorStore.map.id,
name: mapEditorStore.mapSettings.name,
width: mapEditorStore.mapSettings.width,
height: mapEditorStore.mapSettings.height,
tiles: mapEditorStore.map.tiles,
pvp: mapEditorStore.map.pvp,
mapEffects: mapEditorStore.map.mapEffects?.map(({ id, effect, strength }) => ({ id, effect, strength })) ?? [],
mapEventTiles: mapEditorStore.map.mapEventTiles?.map(({ id, type, positionX, positionY, teleport }) => ({ id, type, positionX, positionY, teleport })) ?? [],
placedMapObjects: mapEditorStore.map.placedMapObjects?.map(({ id, mapObject, depth, isRotated, positionX, positionY }) => ({ id, mapObject, depth, isRotated, positionX, positionY })) ?? []
}
if (mapEditorStore.isSettingsModalShown) {
mapEditorStore.toggleSettingsModal()
}
gameStore.connection?.emit('gm:map:update', data, (response: MapT) => {
mapEditorStore.setMap(response)
})
}
function clear() {
if (!mapEditorStore.map) return
// Clear objects, event tiles and tiles
mapEditorStore.map.placedMapObjects = []
mapEditorStore.map.mapEventTiles = []
mapEditorStore.triggerClearTiles()
}
</script>

View File

@ -1,5 +1,4 @@
import type { Map, MapEffect, MapObject, PlacedMapObject, Tile } from '@/application/types'
import { useGameStore } from '@/stores/gameStore'
import type { Map, MapEffect, MapObject, Tile, UUID } from '@/application/types'
import { defineStore } from 'pinia'
export type TeleportSettings = {
@ -12,8 +11,8 @@ export type TeleportSettings = {
export const useMapEditorStore = defineStore('mapEditor', {
state: () => {
return {
active: false,
map: null as Map | null,
active: true,
mapId: '',
tool: 'move',
drawMode: 'tile',
eraserMode: 'tile',
@ -45,13 +44,11 @@ export const useMapEditorStore = defineStore('mapEditor', {
},
actions: {
toggleActive() {
const gameStore = useGameStore()
if (!this.active) gameStore.connection?.emit('map:character:leave')
if (this.active) this.reset()
this.active = !this.active
},
setMap(map: Map | null) {
this.map = map
setMapId(mapId: UUID) {
this.mapId = mapId
},
setMapName(name: string) {
this.mapSettings.name = name
@ -63,11 +60,9 @@ export const useMapEditorStore = defineStore('mapEditor', {
this.mapSettings.height = height
},
setMapPvp(pvp: boolean) {
if (!this.map) return
this.map.pvp = pvp
this.mapSettings.pvp = pvp
},
setMapEffects(mapEffects: MapEffect[]) {
if (!this.map) return
this.mapSettings.mapEffects = mapEffects
},
setTool(tool: string) {
@ -113,8 +108,8 @@ export const useMapEditorStore = defineStore('mapEditor', {
resetClearTilesFlag() {
this.shouldClearTiles = false
},
reset(resetMap = false) {
if (resetMap) this.map = null
reset() {
this.mapId = ''
this.mapList = []
this.tileList = []
this.mapObjectList = []