234 lines
7.6 KiB
Vue
234 lines
7.6 KiB
Vue
<template>
|
|
<Controls v-if="tileLayer" :layer="tileLayer" :depth="0" />
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import config from '@/application/config'
|
|
import Controls from '@/components/utilities/Controls.vue'
|
|
import { createTileArray, getTile, placeTile, setLayerTiles } from '@/composables/mapComposable'
|
|
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
|
import { TileStorage } from '@/storage/storages'
|
|
import { useScene } from 'phavuer'
|
|
import { onMounted, onUnmounted, shallowRef, watch } from 'vue'
|
|
|
|
import Tileset = Phaser.Tilemaps.Tileset
|
|
|
|
const emit = defineEmits(['tileMap:create'])
|
|
|
|
const scene = useScene()
|
|
const mapEditor = useMapEditorComposable()
|
|
const tileStorage = new TileStorage()
|
|
|
|
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
|
const tileLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
|
|
|
function createTileMap() {
|
|
const mapData = new Phaser.Tilemaps.MapData({
|
|
width: mapEditor.currentMap.value?.width,
|
|
height: mapEditor.currentMap.value?.height,
|
|
tileWidth: config.tile_size.width,
|
|
tileHeight: config.tile_size.height,
|
|
orientation: Phaser.Tilemaps.Orientation.ISOMETRIC,
|
|
format: Phaser.Tilemaps.Formats.ARRAY_2D
|
|
})
|
|
|
|
const newTileMap = new Phaser.Tilemaps.Tilemap(scene, mapData)
|
|
emit('tileMap:create', newTileMap)
|
|
return newTileMap
|
|
}
|
|
|
|
async function createTileLayer(currentTileMap: Phaser.Tilemaps.Tilemap) {
|
|
const tiles = await tileStorage.getAll()
|
|
const tilesetImages = []
|
|
|
|
for (const tile of tiles) {
|
|
tilesetImages.push(currentTileMap.addTilesetImage(tile.id, tile.id, config.tile_size.width, config.tile_size.height, 1, 2, tilesetImages.length + 1, { x: 0, y: -config.tile_size.height }))
|
|
}
|
|
|
|
// Add blank tile
|
|
tilesetImages.push(currentTileMap.addTilesetImage('blank_tile', 'blank_tile', config.tile_size.width, config.tile_size.height, 1, 2, 0, { x: 0, y: -config.tile_size.height }))
|
|
|
|
const layer = currentTileMap.createBlankLayer('tiles', tilesetImages as Tileset[], 0, config.tile_size.height) as Phaser.Tilemaps.TilemapLayer
|
|
|
|
layer.setDepth(0)
|
|
layer.setCullPadding(2, 2)
|
|
return layer
|
|
}
|
|
|
|
function pencil(pointer: Phaser.Input.Pointer) {
|
|
if (!tileMap.value || !tileLayer.value) return
|
|
|
|
// Check if map is set
|
|
if (!mapEditor.currentMap.value) return
|
|
console.log(mapEditor.tool.value)
|
|
|
|
// Check if tool is pencil
|
|
if (mapEditor.tool.value !== 'pencil') return
|
|
|
|
// Check if draw mode is tile
|
|
if (mapEditor.drawMode.value !== 'tile') return
|
|
|
|
// Check if there is a selected tile
|
|
if (!mapEditor.selectedTile.value) return // Changed this line to access .value
|
|
|
|
// Check if left mouse button is pressed
|
|
if (!pointer.isDown) return
|
|
|
|
// Check if shift is not pressed, this means we are moving the camera
|
|
if (pointer.event.shiftKey) return
|
|
|
|
// Check if there is a tile
|
|
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
|
if (!tile) return
|
|
|
|
// Place tile
|
|
placeTile(tileMap.value, tileLayer.value, tile.x, tile.y, mapEditor.selectedTile.value)
|
|
|
|
// Adjust mapEditor tiles
|
|
mapEditor.currentMap.value.tiles[tile.y][tile.x] = mapEditor.selectedTile.value
|
|
}
|
|
|
|
function eraser(pointer: Phaser.Input.Pointer) {
|
|
if (!tileMap.value || !tileLayer.value) return
|
|
|
|
// Check if map is set
|
|
if (!mapEditor.currentMap.value) return
|
|
|
|
// Check if tool is pencil
|
|
if (mapEditor.tool.value !== 'eraser') return
|
|
|
|
// Check if draw mode is tile
|
|
if (mapEditor.eraserMode.value !== 'tile') return
|
|
|
|
// Check if left mouse button is pressed
|
|
if (!pointer.isDown) return
|
|
|
|
// Check if shift is not pressed, this means we are moving the camera
|
|
if (pointer.event.shiftKey) return
|
|
|
|
// Check if alt is pressed
|
|
if (pointer.event.altKey) return
|
|
|
|
// Check if there is a tile
|
|
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
|
if (!tile) return
|
|
|
|
// Place tile
|
|
placeTile(tileMap.value, tileLayer.value, tile.x, tile.y, 'blank_tile')
|
|
|
|
// Adjust mapEditor.map.tiles
|
|
mapEditor.currentMap.value.tiles[tile.y][tile.x] = 'blank_tile'
|
|
}
|
|
|
|
function paint(pointer: Phaser.Input.Pointer) {
|
|
if (!tileMap.value || !tileLayer.value) return
|
|
|
|
// Check if map is set
|
|
if (!mapEditor.currentMap.value) return
|
|
|
|
// Check if tool is pencil
|
|
if (mapEditor.tool.value !== 'paint') return
|
|
|
|
// Check if there is a selected tile
|
|
if (!mapEditor.selectedTile.value) return
|
|
|
|
// Check if left mouse button is pressed
|
|
if (!pointer.isDown) return
|
|
|
|
// Check if shift is not pressed, this means we are moving the camera
|
|
if (pointer.event.shiftKey) return
|
|
|
|
// Check if alt is pressed
|
|
if (pointer.event.altKey) return
|
|
|
|
// Set new tileArray with selected tile
|
|
setLayerTiles(tileMap.value, tileLayer.value, createTileArray(tileMap.value.width, tileMap.value.height, mapEditor.selectedTile.value))
|
|
|
|
// Adjust mapEditor.map.tiles
|
|
mapEditor.currentMap.value.tiles = createTileArray(tileMap.value.width, tileMap.value.height, mapEditor.selectedTile.value)
|
|
}
|
|
|
|
// When alt is pressed, and the pointer is down, select the tile that the pointer is over
|
|
function tilePicker(pointer: Phaser.Input.Pointer) {
|
|
if (!tileMap.value || !tileLayer.value) return
|
|
|
|
// Check if map is set
|
|
if (!mapEditor.currentMap.value) return
|
|
|
|
// Check if tool is pencil
|
|
if (mapEditor.tool.value !== 'pencil') return
|
|
|
|
// Check if draw mode is tile
|
|
if (mapEditor.drawMode.value !== 'tile') return
|
|
|
|
// Check if left mouse button is pressed
|
|
if (!pointer.isDown) return
|
|
|
|
// Check if shift is not pressed, this means we are moving the camera
|
|
if (pointer.event.shiftKey) return
|
|
|
|
// Check if alt is pressed
|
|
if (!pointer.event.altKey) return
|
|
|
|
// Check if there is a tile
|
|
const tile = getTile(tileLayer.value, pointer.worldX, pointer.worldY)
|
|
if (!tile) return
|
|
|
|
// Select the tile
|
|
mapEditor.setSelectedTile(mapEditor.currentMap.value.tiles[tile.y][tile.x])
|
|
}
|
|
|
|
watch(
|
|
() => mapEditor.shouldClearTiles.value,
|
|
(shouldClear) => {
|
|
if (shouldClear && mapEditor.currentMap.value && tileMap.value && tileLayer.value) {
|
|
const blankTiles = createTileArray(tileMap.value.width, tileMap.value.height, 'blank_tile')
|
|
setLayerTiles(tileMap.value, tileLayer.value, blankTiles)
|
|
mapEditor.currentMap.value.tiles = blankTiles
|
|
mapEditor.resetClearTilesFlag()
|
|
}
|
|
}
|
|
)
|
|
|
|
onMounted(async () => {
|
|
if (!mapEditor.currentMap.value?.tiles) return
|
|
console.log(mapEditor.currentMap.value)
|
|
|
|
tileMap.value = createTileMap()
|
|
tileLayer.value = await createTileLayer(tileMap.value)
|
|
|
|
// First fill the entire map with blank tiles using current map dimensions
|
|
const blankTiles = createTileArray(mapEditor.currentMap.value.width, mapEditor.currentMap.value.height, 'blank_tile')
|
|
|
|
// Then overlay the map tiles, but only within the current map dimensions
|
|
const mapTiles = mapEditor.currentMap.value.tiles
|
|
for (let y = 0; y < mapEditor.currentMap.value.height; y++) {
|
|
for (let x = 0; x < mapEditor.currentMap.value.width; x++) {
|
|
if (mapTiles[y] && mapTiles[y][x] !== undefined) {
|
|
blankTiles[y][x] = mapTiles[y][x]
|
|
}
|
|
}
|
|
}
|
|
|
|
setLayerTiles(tileMap.value, tileLayer.value, blankTiles)
|
|
|
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
|
|
scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser)
|
|
scene.input.on(Phaser.Input.Events.POINTER_DOWN, paint)
|
|
scene.input.on(Phaser.Input.Events.POINTER_DOWN, tilePicker)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
|
|
scene.input.off(Phaser.Input.Events.POINTER_MOVE, eraser)
|
|
scene.input.off(Phaser.Input.Events.POINTER_DOWN, paint)
|
|
scene.input.off(Phaser.Input.Events.POINTER_DOWN, tilePicker)
|
|
|
|
if (tileMap.value) {
|
|
tileMap.value.destroyLayer('tiles')
|
|
tileMap.value.removeAllLayers()
|
|
tileMap.value.destroy()
|
|
}
|
|
})
|
|
</script>
|