1
0
forked from noxious/client

Zone editor GUI (WIP), added a few helper functions

This commit is contained in:
2024-06-10 17:46:25 +02:00
parent 8227dfe4b3
commit 58bff2010f
12 changed files with 190 additions and 47 deletions

View File

@ -11,4 +11,5 @@ $light-gray: #d3d3d3;
$blue-gray: #778899;
$cyan: #368f8b;
$dark-cyan: #376362;
$light-cyan: #00b3b3;
$green: #09ad19;

View File

@ -1,7 +1,9 @@
<template>
<div class="game-container">
<GmUtilityWindow />
<div class="top-ui"><Hud /></div>
<GmTools />
<div class="top-ui" v-if="!zone.getEditorIsOpen">
<Hud />
</div>
<Game :config="gameConfig" class="game" @create="createGame">
<Scene name="main" @preload="preloadScene" @create="createScene" @play="playScene">
@ -10,8 +12,13 @@
</Game>
<div class="bottom-ui">
<Chat />
<Menubar />
<div v-if="!zone.getEditorIsOpen">
<Chat />
<Menubar />
</div>
<div v-else>
<ZoneEditorToolbar />
</div>
</div>
</div>
</template>
@ -28,9 +35,12 @@ import Menubar from '@/components/game/Menu.vue'
import { onUnmounted } from 'vue'
import ZoneEditor from '@/components/utilities/zoneEditor/ZoneEditor.vue'
import Modal from '@/components/utilities/Modal.vue'
import GmUtilityWindow from '@/components/utilities/gmTools/GmUtilityWindow.vue'
import GmTools from '@/components/utilities/GmTools.vue'
import { useZoneStore } from '@/stores/zone'
import ZoneEditorToolbar from '@/components/utilities/zoneEditor/ZoneEditorToolbar.vue'
const socket = useSocketStore()
const zone = useZoneStore()
onUnmounted(() => {
socket.disconnectSocket()

View File

@ -1,9 +1,9 @@
<template>
<TilemapLayerC v-if="zoneStore.isLoaded" :tilemap="tileMap" :tileset="zoneStore.getTiles" ref="tilemapLayer" :layerIndex="0" :cull-padding-x="10" :cull-padding-y="10" />
<Controls :layer="layer" />
<Container v-if="zoneStore.isLoaded && !zoneEditorStore.isLoaded">
<Character :layer="layer" v-for="character in zoneStore.getCharacters" :key="character.id" :character="character" />
</Container>
<!-- <Container v-if="zoneStore.isLoaded && !zoneEditorStore.isLoaded">-->
<!-- <Character :layer="layer" v-for="character in zoneStore.getCharacters" :key="character.id" :character="character" />-->
<!-- </Container>-->
</template>
<script setup lang="ts">

View File

@ -1,8 +1,8 @@
<template>
<Container>
<Rectangle
:x="tileToWorldXY(layer, props.character?.position_x, props.character?.position_y).position_x"
:y="tileToWorldXY(layer, props.character?.position_x, props.character?.position_y).position_y"
:x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)"
:y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)"
:origin-x="0.5"
:origin-y="10.5"
:fillColor="0xFFFFFF"
@ -10,8 +10,8 @@
:height="8"
>
<Rectangle
:x="tileToWorldXY(layer, props.character?.position_x, props.character?.position_y).position_x"
:y="tileToWorldXY(layer, props.character?.position_x, props.character?.position_y).position_y"
:x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)"
:y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)"
:origin-x="0.5"
:origin-y="20.5"
:fillColor="0x09ad19"
@ -22,8 +22,8 @@
<Text
@create="createText"
:text="props.character?.name"
:x="tileToWorldXY(layer, props.character?.position_x, props.character?.position_y).position_x"
:y="tileToWorldXY(layer, props.character?.position_x, props.character?.position_y).position_y"
:x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)"
:y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)"
:origin-x="0.5"
:origin-y="4.5"
:style="{
@ -34,8 +34,8 @@
/>
<Sprite
ref="sprite"
:x="tileToWorldXY(layer, props.character?.position_x, props.character?.position_y).position_x"
:y="tileToWorldXY(layer, props.character?.position_x, props.character?.position_y).position_y"
:x="tileToWorldX(layer, props.character?.position_x, props.character?.position_y)"
:y="tileToWorldY(layer, props.character?.position_x, props.character?.position_y)"
play="walk" />
</Container>
</template>
@ -45,7 +45,7 @@ import { Container, Rectangle, Sprite, Text, useScene } from 'phavuer'
import { onMounted, ref } from 'vue'
import { useSocketStore } from '@/stores/socket'
import { type Character as CharacterT } from '@/types'
import { getTile, tileToWorldXY } from '@/services/zone'
import { getTile, tileToWorldX, tileToWorldXY, tileToWorldY } from '@/services/zone'
const socket = useSocketStore()

View File

@ -1,13 +1,14 @@
<template>
<Image texture="waypoint" :x="waypoint.x" :y="waypoint.y" :visible="waypoint.visible" />
</template>
<script setup lang="ts">
import { Image, useScene } from 'phavuer'
import { ref } from 'vue'
import config from '@/config'
import { getTile, tileToWorldXY } from '@/services/zone'
const scene = useScene()
const pointer_tile = ref(undefined)
const props = defineProps({
layer: Phaser.Tilemaps.TilemapLayer
})
@ -21,34 +22,19 @@ function onPointerMove(pointer: Phaser.Input.Pointer) {
const px = scene.cameras.main.worldView.x + pointer.x
const py = scene.cameras.main.worldView.y + pointer.y
pointer_tile.value = getTile(px, py, props.layer)
if (pointer_tile.value) {
waypoint.value.visible = true
// Convert tile coordinates to world coordinates
const worldPoint = props.layer.tileToWorldXY(pointer_tile.value.x, pointer_tile.value.y)
waypoint.value.x = worldPoint.x + config.tile_size.y
waypoint.value.y = worldPoint.y + config.tile_size.y + 15
} else {
const pointer_tile = getTile(px, py, props.layer) as Phaser.Tilemaps.Tile
if (!pointer_tile) {
waypoint.value.visible = false
return
}
waypoint.value.visible = true
// Convert tile coordinates to world coordinates
const worldPoint = tileToWorldXY(props.layer, pointer_tile.x, pointer_tile.y)
waypoint.value.x = worldPoint.position_x
waypoint.value.y = worldPoint.position_y + config.tile_size.y + 15
}
scene.input.on(Phaser.Input.Events.POINTER_MOVE, onPointerMove)
function getTile(x: number, y: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
const tile: Phaser.Tilemaps.Tile = layer.getTileAtWorldXY(x, y)
if (!tile) return undefined;
return tile
}
function getTileAt(iX: number, iY: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
const tile: Phaser.Tilemaps.Tile = layer.getTileAt(iX, iY)
if (tile) return tile
else return undefined
}
function getDepth(tile: Phaser.Tilemaps.Tile): number {
return 32
}
</script>

View File

@ -16,9 +16,10 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import config from '@/config'
const tileWidth = 64;
const tileHeight = 32;
const tileWidth = config.tile_size.x;
const tileHeight = config.tile_size.y;
const tiles = ref([]);
const selectedTile = ref(null);
const tileCanvas = ref(null);

View File

@ -0,0 +1,81 @@
<template>
<div class="toolbar">
<div class="tools">
<button :class="{ active: activeTool === 'tiles' }" @click="activeTool = 'tiles'">
<img src="/assets/icons/zoneEditor/tiles.svg" alt="Eraser tool" />
</button>
<div class="divider"></div>
<button :class="{ active: activeTool === 'eraser' }" @click="activeTool = 'eraser'">
<img src="/assets/icons/zoneEditor/eraser-tool.svg" alt="Eraser tool" />
</button>
</div>
<div class="buttons">
<button class="btn-cyan">Save</button>
<button class="btn-cyan">Load</button>
<button class="btn-cyan">Clear</button>
<button class="btn-cyan">Exit</button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const activeTool = ref('tiles');
</script>
<style scoped lang="scss">
@import '@/assets/scss/main';
.toolbar {
position: absolute;
border-radius: 5px;
opacity: 0.8;
display: flex;
background: $dark-gray;
border: 2px solid $cyan;
color: $light-gray;
padding: 5px;
min-width: 100%;
height: 40px;
.tools {
display: flex;
gap: 10px;
.divider {
width: 1px;
background: $cyan;
}
// vertical center
button {
display: flex;
justify-content: center;
align-items: center;
&.active {
border-bottom: 3px solid $light-cyan;
border-radius: 5px;
}
}
img {
filter: invert(1);
width: 35px;
height: 35px;
}
}
.buttons {
display: flex;
gap: 10px;
margin-left: auto;
button {
padding-left: 10px;
padding-right: 10px;
}
}
}
</style>

View File

@ -6,6 +6,16 @@ export function getTile(x: number, y: number, layer: Phaser.Tilemaps.TilemapLaye
return tile
}
export function tileToWorldX(layer: Phaser.Tilemaps.TilemapLayer, pos_x: number, pos_y: number) {
const worldPoint = layer.tileToWorldXY(pos_x, pos_y)
return worldPoint.x + config.tile_size.y
}
export function tileToWorldY(layer: Phaser.Tilemaps.TilemapLayer, pos_x: number, pos_y: number) {
const worldPoint = layer.tileToWorldXY(pos_x, pos_y)
return worldPoint.y
}
export function tileToWorldXY(layer: Phaser.Tilemaps.TilemapLayer, pos_x: number, pos_y: number) {
const worldPoint = layer.tileToWorldXY(pos_x, pos_y)
const position_x = worldPoint.x + config.tile_size.y

View File

@ -5,12 +5,14 @@ export const useZoneStore = defineStore('zone', {
state: () => ({
loaded: false,
tiles: undefined,
characters: [] as Character[]
characters: [] as Character[],
editorIsOpen: true
}),
getters: {
isLoaded: (state) => state.loaded,
getTiles: (state) => state.tiles,
getCharacters: (state) => state.characters
getCharacters: (state) => state.characters,
getEditorIsOpen: (state) => state.editorIsOpen
},
actions: {
loadTiles(tiles: any) {
@ -33,6 +35,9 @@ export const useZoneStore = defineStore('zone', {
} else {
console.error(`Character with id ${character.id} not found`)
}
},
setEditorIsOpen(isOpen: boolean) {
this.editorIsOpen = isOpen
}
}
})