forked from noxious/client
Map object position as tile coordinates, map objects correctly snap to each tile now when moving, and fixed bug of placing objects over eachother on the same tile
This commit is contained in:
parent
90d7252784
commit
841ec0f3df
@ -5,15 +5,19 @@
|
||||
<script setup lang="ts">
|
||||
import type { PlacedMapObject, TextureData } from '@/application/types'
|
||||
import { loadTexture } from '@/composables/gameComposable'
|
||||
import { calculateIsometricDepth } from '@/composables/mapComposable'
|
||||
import { calculateIsometricDepth, tileToWorldXY } from '@/composables/mapComposable'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { Image, useScene } from 'phavuer'
|
||||
import { computed, onMounted } from 'vue'
|
||||
import config from '@/application/config'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import Tilemap = Phaser.Tilemaps.Tilemap
|
||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer
|
||||
|
||||
const props = defineProps<{
|
||||
placedMapObject: PlacedMapObject
|
||||
placedMapObject: PlacedMapObject,
|
||||
tileMap: Tilemap
|
||||
tileMapLayer: TilemapLayer
|
||||
}>()
|
||||
|
||||
const gameStore = useGameStore()
|
||||
@ -32,12 +36,11 @@ const imageProps = computed(() => ({
|
||||
}))
|
||||
|
||||
function calculateObjectPlacement(mapObj: PlacedMapObject) : {x: number; y: number} {
|
||||
let position = { x: mapObj.positionX, y: mapObj.positionY }
|
||||
let halfTileWidth = config.tile_size.width/2
|
||||
let halfTileHeight = config.tile_size.height/2
|
||||
let position = tileToWorldXY(props.tileMapLayer, mapObj.positionX, mapObj.positionY)
|
||||
|
||||
return {
|
||||
x: position.x-mapObj.mapObject.frameWidth/2,
|
||||
y: position.y-mapObj.mapObject.frameHeight/2-halfTileHeight
|
||||
x: position.worldPositionX-mapObj.mapObject.frameWidth/2,
|
||||
y: position.worldPositionY-mapObj.mapObject.frameHeight/2+config.tile_size.height
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<MapTiles ref="mapTiles" @tileMap:create="tileMap = $event" />
|
||||
<PlacedMapObjects ref="mapObjects" v-if="tileMap" :tileMap />
|
||||
<MapEventTiles ref="eventTiles" v-if="tileMap" :tileMap />
|
||||
<MapTiles ref="mapTiles" v-if="tileMap && tileMapLayer" :tileMapLayer :tileMap @tileMap:create="tileMap = $event" />
|
||||
<PlacedMapObjects ref="mapObjects" v-if="tileMap && tileMapLayer" :tileMapLayer :tileMap />
|
||||
<MapEventTiles ref="eventTiles" v-if="tileMap && tileMapLayer" :tileMapLayer :tileMap />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -11,8 +11,11 @@ import PlacedMapObjects from '@/components/gameMaster/mapEditor/mapPartials/Plac
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { useScene } from 'phavuer'
|
||||
import { onBeforeUnmount, onMounted, onUnmounted, shallowRef, useTemplateRef } from 'vue'
|
||||
import { createTileLayer, createTileMap } from '@/composables/mapComposable'
|
||||
|
||||
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
||||
const tileMapLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
||||
|
||||
const mapEditor = useMapEditorComposable()
|
||||
|
||||
const scene = useScene()
|
||||
@ -72,6 +75,10 @@ function handlePointerUp(pointer: Phaser.Input.Pointer) {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
tileMap.value = createTileMap(scene, mapEditor.currentMap.value!)
|
||||
mapTiles.value?.$emit('tileMap:create', tileMap.value)
|
||||
tileMapLayer.value = createTileLayer(tileMap.value, mapEditor.currentMap.value)
|
||||
|
||||
addEventListener('keydown', handleKeyDown)
|
||||
scene.input.on(Phaser.Input.Events.POINTER_DOWN, handlePointerDown)
|
||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
|
||||
@ -79,6 +86,12 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (tileMap.value) {
|
||||
tileMap.value.destroyLayer('tiles')
|
||||
tileMap.value.removeAllLayers()
|
||||
tileMap.value.destroy()
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { MapEventTileType, type MapEventTile, type Map as MapT } from '@/application/types'
|
||||
import { MapEventTileType, type MapEventTile, type Map as MapT, type UUID } from '@/application/types'
|
||||
import { uuidv4 } from '@/application/utilities'
|
||||
import { getTile, tileToWorldX, tileToWorldY } from '@/composables/mapComposable'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
@ -42,7 +42,7 @@ function pencil(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||
if (mapEditor.drawMode.value === 'teleport' && !mapEditor.teleportSettings.value.toMapId) return
|
||||
|
||||
const newEventTile = {
|
||||
id: uuidv4(),
|
||||
id: uuidv4() as UUID,
|
||||
mapId: map.id,
|
||||
map: map.id,
|
||||
type: mapEditor.drawMode.value === 'blocking tile' ? MapEventTileType.BLOCK : MapEventTileType.TELEPORT,
|
||||
@ -56,7 +56,7 @@ function pencil(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||
toPositionY: mapEditor.teleportSettings.value.toPositionY,
|
||||
toRotation: mapEditor.teleportSettings.value.toRotation
|
||||
}
|
||||
: undefined
|
||||
: {}
|
||||
}
|
||||
|
||||
map.mapEventTiles.push(newEventTile)
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Controls v-if="tileLayer" :layer="tileLayer" :depth="0" />
|
||||
<Controls v-if="props.tileMapLayer" :layer="props.tileMapLayer" :depth="0" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -16,11 +16,13 @@ const scene = useScene()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const tileStorage = new TileStorage()
|
||||
|
||||
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
||||
const tileLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
||||
|
||||
defineExpose({ handlePointer, finalizeCommand, undo, redo })
|
||||
|
||||
const props = defineProps<{
|
||||
tileMap: Phaser.Tilemaps.Tilemap
|
||||
tileMapLayer: Phaser.Tilemaps.TilemapLayer
|
||||
}>()
|
||||
|
||||
class EditorCommand {
|
||||
public operation: 'draw' | 'erase' = 'draw'
|
||||
public tileName: string = "blank_tile"
|
||||
@ -46,14 +48,12 @@ function pencil(pointer: Phaser.Input.Pointer) {
|
||||
// Check if there is a selected tile
|
||||
if (!mapEditor.selectedTile.value) return
|
||||
|
||||
if (!tileMap.value || !tileLayer.value) return
|
||||
|
||||
// Check if there is a tile
|
||||
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
||||
const tile = getTile(props.tileMapLayer, pointer.worldX, pointer.worldY)
|
||||
if (!tile) return
|
||||
|
||||
// Place tile
|
||||
placeTile(tileMap.value, tileLayer.value, tile.x, tile.y, mapEditor.selectedTile.value)
|
||||
placeTile(props.tileMap, props.tileMapLayer, tile.x, tile.y, mapEditor.selectedTile.value)
|
||||
|
||||
createCommandUpdate(tile.x, tile.y, mapEditor.selectedTile.value, 'draw')
|
||||
|
||||
@ -65,14 +65,12 @@ function eraser(pointer: Phaser.Input.Pointer) {
|
||||
let map = mapEditor.currentMap.value
|
||||
if (!map) return
|
||||
|
||||
if (!tileMap.value || !tileLayer.value) return
|
||||
|
||||
// Check if there is a tile
|
||||
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
||||
const tile = getTile(props.tileMapLayer, pointer.worldX, pointer.worldY)
|
||||
if (!tile) return
|
||||
|
||||
// Place tile
|
||||
placeTile(tileMap.value, tileLayer.value, tile.x, tile.y, 'blank_tile')
|
||||
placeTile(props.tileMap, props.tileMapLayer, tile.x, tile.y, 'blank_tile')
|
||||
|
||||
createCommandUpdate(tile.x, tile.y, 'blank_tile', 'erase')
|
||||
|
||||
@ -81,10 +79,9 @@ function eraser(pointer: Phaser.Input.Pointer) {
|
||||
}
|
||||
|
||||
function paint(pointer: Phaser.Input.Pointer) {
|
||||
if (!tileMap.value || !tileLayer.value) return
|
||||
// Set new tileArray with selected tile
|
||||
const tileArray = createTileArray(tileMap.value.width, tileMap.value.height, mapEditor.selectedTile.value)
|
||||
setLayerTiles(tileMap.value, tileLayer.value, tileArray)
|
||||
const tileArray = createTileArray(props.tileMap.width, props.tileMap.height, mapEditor.selectedTile.value)
|
||||
setLayerTiles(props.tileMap, props.tileMapLayer, tileArray)
|
||||
|
||||
// Adjust mapEditorStore.map.tiles
|
||||
if (mapEditor.currentMap.value) {
|
||||
@ -97,10 +94,8 @@ function tilePicker(pointer: Phaser.Input.Pointer) {
|
||||
let map = mapEditor.currentMap.value
|
||||
if (!map) return
|
||||
|
||||
if (!tileMap.value || !tileLayer.value) return
|
||||
|
||||
// Check if there is a tile
|
||||
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
||||
const tile = getTile(props.tileMapLayer, pointer.worldX, pointer.worldY)
|
||||
if (!tile) return
|
||||
|
||||
// Select the tile
|
||||
@ -108,8 +103,6 @@ function tilePicker(pointer: Phaser.Input.Pointer) {
|
||||
}
|
||||
|
||||
function handlePointer(pointer: Phaser.Input.Pointer) {
|
||||
if (!tileMap.value || !tileLayer.value) return
|
||||
|
||||
// Check if left mouse button is pressed
|
||||
if (!pointer.isDown && pointer.button === 0) return
|
||||
|
||||
@ -187,13 +180,13 @@ function applyCommands(tiles: string[][], ...commands: EditorCommand[]): string[
|
||||
}
|
||||
|
||||
function updateMapTiles() {
|
||||
if (!tileMap.value || !tileLayer.value || !mapEditor.currentMap.value) return
|
||||
if (!mapEditor.currentMap.value) return
|
||||
|
||||
let indexedCommands = commandStack.slice(0, commandIndex.value)
|
||||
let modifiedTiles = applyCommands(originTiles, ...indexedCommands)
|
||||
|
||||
//replaceTiles(mapEditor.currentMap.value.tiles, layer, tileMap.value.width, tileMap.value.height)
|
||||
setLayerTiles(tileMap.value, tileLayer.value, modifiedTiles)
|
||||
setLayerTiles(props.tileMap, props.tileMapLayer, modifiedTiles)
|
||||
mapEditor.currentMap.value.tiles = modifiedTiles
|
||||
}
|
||||
|
||||
@ -205,10 +198,10 @@ function cloneArray(arr: any[]) : any[] {
|
||||
watch(
|
||||
() => mapEditor.shouldClearTiles,
|
||||
(shouldClear) => {
|
||||
if (shouldClear && mapEditor.currentMap.value && tileMap.value && tileLayer.value) {
|
||||
const blankTiles = createTileArray(tileLayer.value.width, tileLayer.value.height, 'blank_tile')
|
||||
setLayerTiles(tileMap.value, tileLayer.value, blankTiles)
|
||||
replaceTiles(mapEditor.currentMap.value.tiles, blankTiles, tileLayer.value.width, tileLayer.value.height)
|
||||
if (shouldClear && mapEditor.currentMap.value) {
|
||||
const blankTiles = createTileArray(props.tileMapLayer.width, props.tileMapLayer.height, 'blank_tile')
|
||||
setLayerTiles(props.tileMap, props.tileMapLayer, blankTiles)
|
||||
replaceTiles(mapEditor.currentMap.value.tiles, blankTiles, props.tileMapLayer.width, props.tileMapLayer.height)
|
||||
mapEditor.resetClearTilesFlag()
|
||||
}
|
||||
}
|
||||
@ -230,20 +223,9 @@ onMounted(async () => {
|
||||
const mapState = mapEditor.currentMap.value
|
||||
|
||||
//Clone
|
||||
originTiles = cloneArray(mapEditor.currentMap.value.tiles)
|
||||
originTiles = cloneArray(mapState.tiles)
|
||||
|
||||
tileMap.value = createTileMap(scene, mapEditor.currentMap.value)
|
||||
emit('tileMap:create', tileMap.value)
|
||||
tileLayer.value = createTileLayer(tileMap.value, mapEditor.currentMap.value)
|
||||
|
||||
setLayerTiles(tileMap.value, tileLayer.value, mapState.tiles)
|
||||
setLayerTiles(props.tileMap, props.tileMapLayer, mapState.tiles)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (tileMap.value) {
|
||||
tileMap.value.destroyLayer('tiles')
|
||||
tileMap.value.removeAllLayers()
|
||||
tileMap.value.destroy()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<SelectedPlacedMapObjectComponent v-if="mapEditor.selectedPlacedObject.value" :placedMapObject="mapEditor.selectedPlacedObject.value" @move="moveMapObject" @rotate="rotatePlacedMapObject" @delete="deletePlacedMapObject" />
|
||||
<PlacedMapObject v-for="placedMapObject in mapEditor.currentMap.value?.placedMapObjects" :placedMapObject @pointerdown="clickPlacedMapObject(placedMapObject)" />
|
||||
<PlacedMapObject :tileMapLayer :tileMap v-for="placedMapObject in mapEditor.currentMap.value?.placedMapObjects" :placedMapObject @pointerdown="clickPlacedMapObject(placedMapObject)" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Map as MapT, PlacedMapObject as PlacedMapObjectT } from '@/application/types'
|
||||
import type { Map as MapT, PlacedMapObject as PlacedMapObjectT, UUID } from '@/application/types'
|
||||
import { uuidv4 } from '@/application/utilities'
|
||||
import PlacedMapObject from '@/components/game/map/partials/PlacedMapObject.vue'
|
||||
import SelectedPlacedMapObjectComponent from '@/components/gameMaster/mapEditor/partials/SelectedPlacedMapObject.vue'
|
||||
@ -13,6 +13,7 @@ import { useScene } from 'phavuer'
|
||||
import { ref, watch } from 'vue'
|
||||
import { getTile, tileToWorldX, tileToWorldY } from '@/composables/mapComposable'
|
||||
import Tilemap = Phaser.Tilemaps.Tilemap
|
||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer
|
||||
|
||||
const scene = useScene()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
@ -20,7 +21,8 @@ const mapEditor = useMapEditorComposable()
|
||||
defineExpose({ handlePointer })
|
||||
|
||||
const props = defineProps<{
|
||||
tileMap: Tilemap
|
||||
tileMap: Tilemap,
|
||||
tileMapLayer: TilemapLayer
|
||||
}>()
|
||||
|
||||
function pencil(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||
@ -33,13 +35,13 @@ function pencil(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||
if (!mapEditor.selectedMapObject.value) return
|
||||
|
||||
const newPlacedMapObject: PlacedMapObjectT = {
|
||||
id: uuidv4(),
|
||||
id: uuidv4() as UUID,
|
||||
depth: 0,
|
||||
map: map,
|
||||
mapObject: mapEditor.selectedMapObject.value,
|
||||
isRotated: false,
|
||||
positionX: tileToWorldX(props.tileMap, tile.x, tile.y),
|
||||
positionY: tileToWorldY(props.tileMap, tile.x, tile.y)
|
||||
positionX: tile.x,
|
||||
positionY: tile.y
|
||||
}
|
||||
|
||||
// Add new object to mapObjects
|
||||
@ -75,9 +77,11 @@ function moveMapObject(id: string, map: MapT) {
|
||||
|
||||
function handlePointerMove(pointer: Phaser.Input.Pointer) {
|
||||
if (!mapEditor.movingPlacedObject.value) return
|
||||
const tile = getTile(props.tileMap, pointer.worldX, pointer.worldY)
|
||||
if (!tile) return
|
||||
|
||||
mapEditor.movingPlacedObject.value.positionX = pointer.worldX
|
||||
mapEditor.movingPlacedObject.value.positionY = pointer.worldY
|
||||
mapEditor.movingPlacedObject.value.positionX = tile.x
|
||||
mapEditor.movingPlacedObject.value.positionY = tile.y
|
||||
}
|
||||
|
||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
|
||||
@ -103,7 +107,7 @@ function rotatePlacedMapObject(id: string, map: MapT) {
|
||||
}
|
||||
|
||||
function deletePlacedMapObject(id: string, map: MapT) {
|
||||
let mapE = mapEditor.currentMap.value
|
||||
let mapE = mapEditor.currentMap.value!
|
||||
mapE.placedMapObjects = map.placedMapObjects.filter((object) => object.id !== id)
|
||||
mapEditor.selectedPlacedObject.value = null
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ let selectEraserOpen = ref(false)
|
||||
let tileListShown = ref(false)
|
||||
let mapObjectListShown = ref(false)
|
||||
|
||||
let checkboxValue = ref(false)
|
||||
let checkboxValue = ref<Boolean>(false)
|
||||
|
||||
defineExpose({ tileListShown, mapObjectListShown })
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
<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="mapEditor.currentMap.value?.id" />
|
||||
<Map v-if="mapEditor.currentMap.value" :key="mapEditor.currentMap.value?.id" />
|
||||
<Toolbar
|
||||
ref="toolbar"
|
||||
@save="save"
|
||||
|
Loading…
x
Reference in New Issue
Block a user