Best undo/redo function across all map editor elements
This commit is contained in:
parent
ca307d4de3
commit
9459639497
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<MapTiles ref="mapTiles" @createCommand="addCommand" v-if="tileMap && tileMapLayer" :tileMap :tileMapLayer />
|
||||
<PlacedMapObjects ref="mapObjects" @createCommand="addCommand" v-if="tileMap && tileMapLayer" :tileMap :tileMapLayer />
|
||||
<PlacedMapObjects ref="mapObjects" @update="updateMapObjects" @updateAndCommit="updateAndCommit" v-if="tileMap && tileMapLayer" :tileMap :tileMapLayer />
|
||||
<MapEventTiles ref="eventTiles" @createCommand="addCommand" v-if="tileMap" :tileMap />
|
||||
</template>
|
||||
|
||||
@ -10,12 +10,13 @@ import MapEventTiles from '@/components/gameMaster/mapEditor/mapPartials/MapEven
|
||||
import MapTiles from '@/components/gameMaster/mapEditor/mapPartials/MapTiles.vue'
|
||||
import PlacedMapObjects from '@/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { cloneArray, createTileLayer, createTileMap, placeTiles } from '@/services/mapService'
|
||||
import { cloneArray, createTileArray, createTileLayer, createTileMap, placeTiles } from '@/services/mapService'
|
||||
import { TileStorage } from '@/storage/storages'
|
||||
import { useScene } from 'phavuer'
|
||||
|
||||
import { onBeforeUnmount, onMounted, onUnmounted, ref, shallowRef, useTemplateRef, watch } from 'vue'
|
||||
import type { MapEventTile, PlacedMapObject as PlacedMapObjectT } from '@/application/types'
|
||||
import type { PlacedMapObject as PlacedMapObjectT, Map as MapT, MapEventTile } from '@/application/types'
|
||||
import { useManualRefHistory, useRefHistory } from '@vueuse/core'
|
||||
|
||||
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
||||
const tileMapLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
||||
@ -28,18 +29,20 @@ const mapObjects = useTemplateRef('mapObjects')
|
||||
const eventTiles = useTemplateRef('eventTiles')
|
||||
|
||||
//Record of commands
|
||||
let commandStack: EditorCommand[] = []
|
||||
let commandStack: (EditorCommand | number) [] = []
|
||||
let commandIndex = ref(0)
|
||||
|
||||
let originTiles: string[][] = []
|
||||
let originEventTiles: MapEventTile[] = []
|
||||
let originObjects: PlacedMapObjectT[] = []
|
||||
let originObjects = ref<PlacedMapObjectT[]>(mapEditor.currentMap.value.placedMapObjects)
|
||||
|
||||
const {undo, redo, commit, reset, history, canUndo, canRedo} = useRefHistory(originObjects, {clone:true, deep:true, capacity:9})
|
||||
|
||||
//Command Pattern basic interface, extended to store what elements have been changed by each edit
|
||||
export interface EditorCommand {
|
||||
apply: (elements: any[]) => any[]
|
||||
type: 'tile' | 'map_object' | 'event_tile'
|
||||
operation: 'draw' | 'erase' | 'place' | 'move' | 'delete' | 'rotate'
|
||||
operation: 'draw' | 'erase' | 'clear'
|
||||
}
|
||||
|
||||
function applyCommands(tiles: any[], ...commands: EditorCommand[]): any[] {
|
||||
@ -50,57 +53,95 @@ function applyCommands(tiles: any[], ...commands: EditorCommand[]): any[] {
|
||||
return tileVersion
|
||||
}
|
||||
|
||||
watch(() => commandIndex.value!, (val) => {
|
||||
if (val !== undefined) {
|
||||
update(commandStack.slice(0, val))
|
||||
watch(
|
||||
() => mapEditor.shouldClearTiles.value,
|
||||
(shouldClear) => {
|
||||
if (shouldClear && mapEditor.currentMap.value) {
|
||||
mapTiles.value!.clearTiles()
|
||||
eventTiles.value!.clearTiles()
|
||||
mapEditor.currentMap.value.placedMapObjects = []
|
||||
updateAndCommit(mapEditor.currentMap.value)
|
||||
mapEditor.resetClearTilesFlag()
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
function update(commands: EditorCommand[]) {
|
||||
function update(commands: (EditorCommand | number)[]) {
|
||||
if (!mapEditor.currentMap.value) return
|
||||
|
||||
const tileCommands = commands.filter((command) => command.type === 'tile')
|
||||
const eventTileCommands = commands.filter((command) => command.type === 'event_tile')
|
||||
const objectCommands = commands.filter((command) => command.type === 'map_object')
|
||||
if (commandStack.length >= 9) {
|
||||
if (typeof commandStack[0] !== 'number') {
|
||||
const base = commandStack.shift() as EditorCommand
|
||||
if (base.operation !== 'clear') {
|
||||
switch (base.type) {
|
||||
case 'tile':
|
||||
originTiles = base.apply(originTiles) as string[][]
|
||||
break
|
||||
case 'event_tile':
|
||||
originEventTiles = base.apply(originEventTiles) as MapEventTile[]
|
||||
break
|
||||
}
|
||||
}
|
||||
else {
|
||||
commandStack.shift()
|
||||
}
|
||||
}
|
||||
else if (typeof commandStack[0] === 'number') {
|
||||
commandStack.shift()
|
||||
}
|
||||
}
|
||||
|
||||
let tileCommands = commands.filter((item) => typeof item !== 'number' && item.type === 'tile') as EditorCommand[]
|
||||
let eventTileCommands = commands.filter((item) => typeof item !== 'number' && item.type === 'event_tile') as EditorCommand[]
|
||||
|
||||
let modifiedTiles = applyCommands(originTiles, ...tileCommands)
|
||||
placeTiles(tileMap.value!, tileMapLayer.value!, modifiedTiles)
|
||||
|
||||
let eventTiles = applyCommands(originEventTiles, ...eventTileCommands)
|
||||
|
||||
mapEditor.currentMap.value.tiles = modifiedTiles
|
||||
mapEditor.currentMap.value.mapEventTiles = applyCommands(originEventTiles, ...eventTileCommands)
|
||||
mapEditor.currentMap.value.placedMapObjects = applyCommands(originObjects, ...objectCommands)
|
||||
mapEditor.currentMap.value.mapEventTiles = eventTiles
|
||||
}
|
||||
|
||||
function updateMapObjects(map: MapT) {
|
||||
originObjects.value = map.placedMapObjects
|
||||
}
|
||||
|
||||
function updateAndCommit(map?: MapT) {
|
||||
commandStack = commandStack.slice(0, commandIndex.value)
|
||||
if (map) updateMapObjects(map)
|
||||
commit()
|
||||
commandStack.push(0)
|
||||
commandIndex.value = commandStack.length
|
||||
|
||||
console.log(history.value)
|
||||
console.log(commandStack)
|
||||
console.log(commandIndex.value)
|
||||
}
|
||||
|
||||
function addCommand(command: EditorCommand) {
|
||||
commandStack = commandStack.slice(0, commandIndex.value)
|
||||
commandStack.push(command)
|
||||
|
||||
if (commandStack.length >= 9) {
|
||||
switch (commandStack[0].type) {
|
||||
case 'tile':
|
||||
originTiles = commandStack.shift()?.apply(originTiles) as string[][]
|
||||
break
|
||||
case 'map_object':
|
||||
originObjects = commandStack.shift()?.apply(originObjects) as PlacedMapObjectT[]
|
||||
break
|
||||
case 'event_tile':
|
||||
originEventTiles = commandStack.shift()?.apply(originEventTiles) as MapEventTile[]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
commandIndex.value = commandStack.length
|
||||
}
|
||||
|
||||
function undo() {
|
||||
function undoEdit() {
|
||||
if (commandIndex.value > 0) {
|
||||
commandIndex.value--
|
||||
if (typeof(commandStack[--commandIndex.value]) === 'number' && canUndo) {
|
||||
undo()
|
||||
mapEditor.currentMap.value.placedMapObjects = originObjects.value
|
||||
}
|
||||
update(commandStack.slice(0, commandIndex.value))
|
||||
}
|
||||
}
|
||||
|
||||
function redo() {
|
||||
if (commandIndex.value <= 9 && commandIndex.value <= commandStack.length) {
|
||||
commandIndex.value++
|
||||
function redoEdit() {
|
||||
if (commandIndex.value <= 9 && commandIndex.value < commandStack.length) {
|
||||
if (typeof(commandStack[commandIndex.value++]) === 'number' && canRedo) {
|
||||
redo()
|
||||
mapEditor.currentMap.value.placedMapObjects = originObjects.value
|
||||
}
|
||||
update(commandStack.slice(0, commandIndex.value))
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,12 +174,12 @@ function handlePointerDown(pointer: Phaser.Input.Pointer) {
|
||||
function handleKeyDown(event: KeyboardEvent) {
|
||||
//CTRL+Y
|
||||
if (event.key === 'y' && event.ctrlKey) {
|
||||
redo()
|
||||
redoEdit()
|
||||
}
|
||||
|
||||
//CTRL+Z
|
||||
if (event.key === 'z' && event.ctrlKey) {
|
||||
undo()
|
||||
undoEdit()
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,7 +195,7 @@ function handlePointerUp(pointer: Phaser.Input.Pointer) {
|
||||
mapTiles.value!.finalizeCommand()
|
||||
break
|
||||
case 'map_object':
|
||||
mapObjects.value!.finalizeCommand()
|
||||
updateAndCommit()
|
||||
break
|
||||
case 'teleport':
|
||||
eventTiles.value!.finalizeCommand()
|
||||
@ -171,9 +212,10 @@ onMounted(async () => {
|
||||
|
||||
//Clone
|
||||
originTiles = cloneArray(mapValue.tiles)
|
||||
originObjects = cloneArray(mapValue.placedMapObjects)
|
||||
originEventTiles = cloneArray(mapValue.mapEventTiles)
|
||||
|
||||
commit()
|
||||
|
||||
const tileStorage = new TileStorage()
|
||||
const allTiles = await tileStorage.getAll()
|
||||
const allTileIds = allTiles.map((tile) => tile.id)
|
||||
|
@ -13,7 +13,7 @@ import { type EditorCommand } from '@/components/gameMaster/mapEditor/Map.vue'
|
||||
|
||||
const mapEditor = useMapEditorComposable()
|
||||
|
||||
defineExpose({ handlePointer, finalizeCommand })
|
||||
defineExpose({ handlePointer, finalizeCommand, clearTiles})
|
||||
|
||||
const emit = defineEmits(['createCommand'])
|
||||
|
||||
@ -27,7 +27,7 @@ const props = defineProps<{
|
||||
let currentCommand: EventTileCommand | null = null
|
||||
|
||||
class EventTileCommand implements EditorCommand {
|
||||
public operation: 'draw' | 'erase' = 'draw'
|
||||
public operation: 'draw' | 'erase' | 'clear' = 'draw'
|
||||
public type: 'event_tile' = 'event_tile'
|
||||
public affectedTiles: MapEventTile[] = []
|
||||
|
||||
@ -39,15 +39,18 @@ class EventTileCommand implements EditorCommand {
|
||||
else if (this.operation === 'erase') {
|
||||
tileVersion = tileVersion.filter((v) => !this.affectedTiles.includes(v))
|
||||
}
|
||||
else if (this.operation === 'clear') {
|
||||
tileVersion = []
|
||||
}
|
||||
return tileVersion
|
||||
}
|
||||
|
||||
constructor(operation: 'draw' | 'erase') {
|
||||
constructor(operation: 'draw' | 'erase' | 'clear') {
|
||||
this.operation = operation
|
||||
}
|
||||
}
|
||||
|
||||
function createCommandUpdate(tile: MapEventTile, operation: 'draw' | 'erase') {
|
||||
function createCommandUpdate(tile?: MapEventTile, operation: 'draw' | 'erase' | 'clear') {
|
||||
if (!currentCommand) {
|
||||
currentCommand = new EventTileCommand(operation)
|
||||
}
|
||||
@ -149,4 +152,11 @@ function handlePointer(pointer: Phaser.Input.Pointer) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function clearTiles() {
|
||||
if (mapEditor.currentMap.value.mapEventTiles.length === 0) return
|
||||
createCommandUpdate(null, 'clear')
|
||||
finalizeCommand()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@ -11,7 +11,7 @@ import { type EditorCommand } from '@/components/gameMaster/mapEditor/Map.vue'
|
||||
|
||||
const mapEditor = useMapEditorComposable()
|
||||
|
||||
defineExpose({ handlePointer, finalizeCommand })
|
||||
defineExpose({ handlePointer, finalizeCommand, clearTiles })
|
||||
|
||||
const emit = defineEmits(['createCommand'])
|
||||
|
||||
@ -20,32 +20,37 @@ const props = defineProps<{
|
||||
tileMapLayer: Phaser.Tilemaps.TilemapLayer
|
||||
}>()
|
||||
|
||||
|
||||
// *** COMMAND STATE ***
|
||||
|
||||
let currentCommand: TileCommand | null = null
|
||||
|
||||
class TileCommand implements EditorCommand {
|
||||
public operation: 'draw' | 'erase' = 'draw'
|
||||
public operation: 'draw' | 'erase' | 'clear' = 'draw'
|
||||
public type: 'tile' = 'tile'
|
||||
public tileName: string = 'blank_tile'
|
||||
public affectedTiles: number[][] = []
|
||||
|
||||
apply(elements: string[][]) {
|
||||
let tileVersion = cloneArray(elements) as string[][]
|
||||
for (const position of this.affectedTiles) {
|
||||
tileVersion[position[1]][position[0]] = this.tileName
|
||||
let tileVersion
|
||||
if (this.operation === 'clear') {
|
||||
tileVersion = createTileArray(props.tileMapLayer.width, props.tileMapLayer.height, 'blank_tile')
|
||||
}
|
||||
else {
|
||||
tileVersion = cloneArray(elements) as string[][]
|
||||
for (const position of this.affectedTiles) {
|
||||
tileVersion[position[1]][position[0]] = this.tileName
|
||||
}
|
||||
}
|
||||
return tileVersion
|
||||
}
|
||||
|
||||
constructor(operation: 'draw' | 'erase', tileName: string) {
|
||||
constructor(operation: 'draw' | 'erase' | 'clear', tileName: string) {
|
||||
this.operation = operation
|
||||
this.tileName = tileName
|
||||
}
|
||||
}
|
||||
|
||||
function createCommandUpdate(x: number, y: number, tileName: string, operation: 'draw' | 'erase') {
|
||||
function createCommandUpdate(x: number, y: number, tileName: string, operation: 'draw' | 'erase' | 'clear') {
|
||||
if (!currentCommand) {
|
||||
currentCommand = new TileCommand(operation, tileName)
|
||||
}
|
||||
@ -137,21 +142,14 @@ function handlePointer(pointer: Phaser.Input.Pointer) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *** LIFECYCLE ***
|
||||
|
||||
|
||||
watch(
|
||||
() => mapEditor.shouldClearTiles.value,
|
||||
(shouldClear) => {
|
||||
if (shouldClear && mapEditor.currentMap.value) {
|
||||
const blankTiles = createTileArray(props.tileMapLayer.width, props.tileMapLayer.height, 'blank_tile')
|
||||
placeTiles(props.tileMap, props.tileMapLayer, blankTiles)
|
||||
mapEditor.currentMap.value.tiles = blankTiles
|
||||
mapEditor.resetClearTilesFlag()
|
||||
}
|
||||
}
|
||||
)
|
||||
function clearTiles() {
|
||||
const tileArray = createTileArray(props.tileMap.width, props.tileMap.height, 'blank_tile')
|
||||
placeTiles(props.tileMap, props.tileMapLayer, tileArray)
|
||||
createCommandUpdate(0,0,"blank_tile",'clear')
|
||||
finalizeCommand()
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (!mapEditor.currentMap.value) return
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<SelectedPlacedMapObjectComponent v-if="mapEditor.selectedPlacedObject.value" :map :placedMapObject="mapEditor.selectedPlacedObject.value" @move="moveMapObject" @rotate="rotatePlacedMapObject" @delete="deletePlacedMapObject" />
|
||||
<SelectedPlacedMapObjectComponent v-if="mapEditor.selectedPlacedObject.value" :map="mapEditor.currentMap.value!" :placedMapObject="mapEditor.selectedPlacedObject.value" @move="moveMapObject" @rotate="rotatePlacedMapObject" @delete="deletePlacedMapObject" />
|
||||
<PlacedMapObject v-for="placedMapObject in mapEditor.currentMap.value?.placedMapObjects" :tileMap :tileMapLayer :placedMapObject @pointerdown="clickPlacedMapObject(placedMapObject)" />
|
||||
</template>
|
||||
|
||||
@ -7,101 +7,38 @@
|
||||
import type {
|
||||
MapObject,
|
||||
Map as MapT,
|
||||
PlacedMapObject as PlacedMapObjectT,
|
||||
UUID,
|
||||
MapEventTile
|
||||
PlacedMapObject as PlacedMapObjectT
|
||||
} 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'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { cloneArray, getTile } from '@/services/mapService'
|
||||
import { getTile } from '@/services/mapService'
|
||||
import { useScene } from 'phavuer'
|
||||
|
||||
import Tilemap = Phaser.Tilemaps.Tilemap
|
||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer
|
||||
import { computed } from 'vue'
|
||||
import { type EditorCommand } from '@/components/gameMaster/mapEditor/Map.vue'
|
||||
import Vector2 = Phaser.Math.Vector2
|
||||
import Tile = Phaser.Tilemaps.Tile
|
||||
|
||||
const scene = useScene()
|
||||
const mapEditor = useMapEditorComposable()
|
||||
const map = computed(() => mapEditor.currentMap.value!)
|
||||
|
||||
defineExpose({ handlePointer, finalizeCommand })
|
||||
const emit = defineEmits<{(e: 'update', map: MapT): void, (e: 'updateAndCommit', map: MapT): void}>()
|
||||
|
||||
const emit = defineEmits(['createCommand'])
|
||||
defineExpose({ handlePointer })
|
||||
|
||||
const props = defineProps<{
|
||||
tileMap: Tilemap
|
||||
tileMapLayer: TilemapLayer
|
||||
}>()
|
||||
|
||||
|
||||
// *** COMMAND STATE ***
|
||||
|
||||
let currentCommand: MapObjectCommand | null = null
|
||||
|
||||
class MapObjectCommand implements EditorCommand {
|
||||
public operation: 'place' | 'move' | 'delete' | 'rotate' = 'place'
|
||||
public type: 'map_object' = 'map_object'
|
||||
public affectedTiles: PlacedMapObjectT[] = []
|
||||
public targetPosition?: Phaser.Math.Vector2
|
||||
|
||||
apply(elements: PlacedMapObjectT[]) {
|
||||
let tileVersion = cloneArray(elements) as PlacedMapObjectT[]
|
||||
if (this.operation === 'place') {
|
||||
tileVersion = tileVersion.concat(this.affectedTiles)
|
||||
}
|
||||
else if (this.operation === 'delete') {
|
||||
tileVersion = tileVersion.filter((v) => !this.affectedTiles.includes(v))
|
||||
}
|
||||
else if (this.operation === 'move') {
|
||||
const targetObject = tileVersion.find((v) => this.affectedTiles[0].id === v.id)
|
||||
if (targetObject) {
|
||||
targetObject.positionX = this.targetPosition!.x
|
||||
targetObject.positionY = this.targetPosition!.y
|
||||
}
|
||||
}
|
||||
|
||||
return tileVersion
|
||||
}
|
||||
|
||||
constructor(operation: 'place' | 'move' | 'delete' | 'rotate') {
|
||||
this.operation = operation
|
||||
}
|
||||
}
|
||||
|
||||
function createCommandUpdate(object: PlacedMapObjectT, operation: 'place' | 'move' | 'delete' | 'rotate', targetPosition?: Phaser.Math.Vector2) {
|
||||
if (!currentCommand) {
|
||||
currentCommand = new MapObjectCommand(operation)
|
||||
}
|
||||
else {
|
||||
if (targetPosition) {
|
||||
currentCommand.targetPosition = targetPosition
|
||||
}
|
||||
}
|
||||
|
||||
currentCommand.affectedTiles.push(object)
|
||||
}
|
||||
|
||||
function finalizeCommand() {
|
||||
if (!currentCommand) return
|
||||
emit('createCommand', currentCommand)
|
||||
currentCommand = null
|
||||
}
|
||||
|
||||
|
||||
// *** HANDLERS ***
|
||||
|
||||
|
||||
function pencil(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||
const tile = getTile(props.tileMap, pointer.worldX, pointer.worldY)
|
||||
if (!tile) return
|
||||
|
||||
// Check if object already exists on position
|
||||
const existingPlacedMapObject = findObjectByPointer(pointer, map)
|
||||
const existingPlacedMapObject = findObjectByPointer(pointer, mapEditor.currentMap.value!)
|
||||
if (existingPlacedMapObject) return
|
||||
|
||||
if (!mapEditor.selectedMapObject.value) return
|
||||
@ -115,11 +52,10 @@ function pencil(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||
}
|
||||
|
||||
// Add new object to mapObjects
|
||||
mapEditor.selectedPlacedObject.value = newPlacedMapObject
|
||||
map.placedMapObjects.push(newPlacedMapObject)
|
||||
|
||||
createCommandUpdate(newPlacedMapObject, 'place')
|
||||
|
||||
mapEditor.selectedPlacedObject.value = newPlacedMapObject
|
||||
emit('update', map)
|
||||
}
|
||||
|
||||
function eraser(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||
@ -127,10 +63,10 @@ function eraser(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||
const existingPlacedMapObject = findObjectByPointer(pointer, map)
|
||||
if (!existingPlacedMapObject) return
|
||||
|
||||
createCommandUpdate(existingPlacedMapObject, 'delete')
|
||||
|
||||
// Remove existing object
|
||||
map.placedMapObjects = map.placedMapObjects.filter((placedMapObject) => placedMapObject.id !== existingPlacedMapObject.id)
|
||||
|
||||
emit('update', map)
|
||||
}
|
||||
|
||||
function findObjectByPointer(pointer: Phaser.Input.Pointer, map: MapT): PlacedMapObjectT | undefined {
|
||||
@ -152,48 +88,51 @@ function objectPicker(pointer: Phaser.Input.Pointer, map: MapT) {
|
||||
function moveMapObject(id: string, map: MapT) {
|
||||
mapEditor.movingPlacedObject.value = map.placedMapObjects.find((object) => object.id === id) as PlacedMapObjectT
|
||||
|
||||
let t: Tile
|
||||
|
||||
function handlePointerMove(pointer: Phaser.Input.Pointer) {
|
||||
if (!mapEditor.movingPlacedObject.value) return
|
||||
const tile = getTile(props.tileMap, pointer.worldX, pointer.worldY)
|
||||
if (!tile) return
|
||||
|
||||
t = tile
|
||||
|
||||
mapEditor.movingPlacedObject.value.positionX = tile.x
|
||||
mapEditor.movingPlacedObject.value.positionY = tile.y
|
||||
}
|
||||
|
||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
|
||||
|
||||
function handlePointerUp() {
|
||||
function handlePointerUp(pointer: Phaser.Input.Pointer) {
|
||||
scene.input.off(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
|
||||
mapEditor.movingPlacedObject.value = null
|
||||
|
||||
createCommandUpdate(mapEditor.movingPlacedObject.value!, 'move', new Vector2(t.x, t.y))
|
||||
finalizeCommand()
|
||||
const tile = getTile(props.tileMap, pointer.worldX, pointer.worldY)
|
||||
if (!tile) return
|
||||
|
||||
map.placedMapObjects.map((placed) => {
|
||||
if (placed.id === id) {
|
||||
placed.positionX = tile.x
|
||||
placed.positionY = tile.y
|
||||
}})
|
||||
|
||||
mapEditor.movingPlacedObject.value = null
|
||||
}
|
||||
emit('updateAndCommit', map)
|
||||
|
||||
scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp)
|
||||
}
|
||||
|
||||
function rotatePlacedMapObject(id: string, map: MapT) {
|
||||
const matchingObject = map.placedMapObjects.find((placedMapObject) => placedMapObject.id === id)
|
||||
matchingObject!.isRotated = !matchingObject!.isRotated
|
||||
|
||||
map.placedMapObjects.map((placed) => {
|
||||
if (placed.id === id) {
|
||||
console.log(placed.id)
|
||||
placed.isRotated = !placed.isRotated
|
||||
}})
|
||||
|
||||
emit('updateAndCommit', map)
|
||||
}
|
||||
|
||||
function deletePlacedMapObject(id: string, map: MapT) {
|
||||
let mapE = mapEditor.currentMap.value!
|
||||
|
||||
const foundObject = mapE.placedMapObjects.find((obj) => obj.id === id)
|
||||
if (!foundObject) return
|
||||
|
||||
createCommandUpdate(foundObject, 'delete')
|
||||
finalizeCommand()
|
||||
|
||||
mapE.placedMapObjects = map.placedMapObjects.filter((object) => object.id !== id)
|
||||
map.placedMapObjects = map.placedMapObjects.filter((object) => object.id !== id)
|
||||
mapEditor.selectedPlacedObject.value = null
|
||||
emit('updateAndCommit', map)
|
||||
}
|
||||
|
||||
function clickPlacedMapObject(placedMapObject: PlacedMapObjectT) {
|
||||
|
@ -113,7 +113,6 @@ function clear() {
|
||||
if (!mapEditor.currentMap.value) return
|
||||
|
||||
// Clear placed objects, event tiles and tiles
|
||||
mapEditor.clearMap()
|
||||
mapEditor.triggerClearTiles()
|
||||
}
|
||||
</script>
|
||||
|
@ -36,12 +36,6 @@ export function useMapEditorComposable() {
|
||||
}
|
||||
}
|
||||
|
||||
const clearMap = () => {
|
||||
if (!currentMap.value) return
|
||||
currentMap.value.placedMapObjects = []
|
||||
currentMap.value.mapEventTiles = []
|
||||
}
|
||||
|
||||
const toggleActive = () => {
|
||||
if (active.value) reset()
|
||||
active.value = !active.value
|
||||
@ -105,7 +99,6 @@ export function useMapEditorComposable() {
|
||||
// Methods
|
||||
loadMap,
|
||||
updateProperty,
|
||||
clearMap,
|
||||
toggleActive,
|
||||
setTool,
|
||||
setDrawMode,
|
||||
|
Loading…
x
Reference in New Issue
Block a user