Centered camera & Modal position changes
- Able to give position to modal other then centered. - Camera now centered on character when - Character joins zone - Character teleports on to zone - Window resize
This commit is contained in:
parent
cfb3e427cf
commit
d0bf622443
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal :isModalOpen="true" :closable="false" :is-resizable="false" :modal-width="200" :modal-height="160">
|
<Modal :isModalOpen="true" :closable="false" :is-resizable="false" :modal-width="modalWidth" :modal-height="modalHeight" :modal-position-x="posXY.x" :modal-position-y="posXY.y">
|
||||||
<template #modalHeader>
|
<template #modalHeader>
|
||||||
<h3 class="m-0 font-medium shrink-0">GM tools</h3>
|
<h3 class="m-0 font-medium shrink-0">GM tools</h3>
|
||||||
</template>
|
</template>
|
||||||
@ -15,7 +15,33 @@
|
|||||||
import Modal from '@/components/utilities/Modal.vue'
|
import Modal from '@/components/utilities/Modal.vue'
|
||||||
import { useZoneEditorStore } from '@/stores/zoneEditor'
|
import { useZoneEditorStore } from '@/stores/zoneEditor'
|
||||||
import { useGameStore } from '@/stores/game'
|
import { useGameStore } from '@/stores/game'
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
|
||||||
const zoneEditorStore = useZoneEditorStore()
|
const zoneEditorStore = useZoneEditorStore()
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
|
const modalWidth = ref(200);
|
||||||
|
const modalHeight = ref(160);
|
||||||
|
|
||||||
|
let posXY = ref({x: 0, y: 0});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
posXY.value = customPositionGmPanel(modalWidth.value);
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
const customPositionGmPanel = (modalWidth: number) => {
|
||||||
|
const padding = 25
|
||||||
|
const width = window.innerWidth
|
||||||
|
|
||||||
|
const x = width - (modalWidth+4) - 25
|
||||||
|
const y = padding
|
||||||
|
|
||||||
|
return { x, y }
|
||||||
|
}
|
||||||
|
|
||||||
|
posXY.value = customPositionGmPanel(modalWidth.value)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -16,11 +16,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Container, Image, RoundRectangle, Sprite, Text } from 'phavuer'
|
import { Container, Image, RoundRectangle, Sprite, Text, useScene } from 'phavuer'
|
||||||
import { type ExtendedCharacter as CharacterT } from '@/types'
|
import { type ExtendedCharacter as CharacterT } from '@/types'
|
||||||
import { calculateIsometricDepth, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
|
import { calculateIsometricDepth, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
|
||||||
import { watch, computed, ref, onMounted, onUnmounted } from 'vue'
|
import { watch, computed, ref, onMounted, onUnmounted } from 'vue'
|
||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
|
import { useGameStore } from '@/stores/game'
|
||||||
|
|
||||||
enum Direction {
|
enum Direction {
|
||||||
POSITIVE,
|
POSITIVE,
|
||||||
@ -40,9 +41,11 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
const isometricDepth = ref(calculateIsometricDepth(props.character.positionX, props.character.positionY, 28, 94, true))
|
const isometricDepth = ref(calculateIsometricDepth(props.character.positionX, props.character.positionY, 28, 94, true))
|
||||||
const currentX = ref(0)
|
const currentX = ref(0)
|
||||||
const currentY = ref(0)
|
const currentY = ref(0)
|
||||||
|
const gameStore = useGameStore();
|
||||||
const tween = ref<Phaser.Tweens.Tween | null>(null)
|
const tween = ref<Phaser.Tweens.Tween | null>(null)
|
||||||
const isInitialPosition = ref(true)
|
const isInitialPosition = ref(true)
|
||||||
|
|
||||||
|
|
||||||
const calculateLocalDepth = (x: number, y: number, width: number, height: number, isCharacter: boolean) => {
|
const calculateLocalDepth = (x: number, y: number, width: number, height: number, isCharacter: boolean) => {
|
||||||
isometricDepth.value = calculateIsometricDepth(x, y, width, height, isCharacter)
|
isometricDepth.value = calculateIsometricDepth(x, y, width, height, isCharacter)
|
||||||
}
|
}
|
||||||
@ -51,6 +54,11 @@ const updatePosition = (x: number, y: number, direction: Direction) => {
|
|||||||
const targetX = tileToWorldX(props.layer, x, y)
|
const targetX = tileToWorldX(props.layer, x, y)
|
||||||
const targetY = tileToWorldY(props.layer, x, y)
|
const targetY = tileToWorldY(props.layer, x, y)
|
||||||
|
|
||||||
|
// Used for camera resize calculation to center on Character.
|
||||||
|
if(gameStore.character) {
|
||||||
|
gameStore.character.relativePosition = { x: targetX, y: targetY };
|
||||||
|
}
|
||||||
|
|
||||||
if (isInitialPosition.value) {
|
if (isInitialPosition.value) {
|
||||||
currentX.value = targetX
|
currentX.value = targetX
|
||||||
currentY.value = targetY
|
currentY.value = targetY
|
||||||
|
@ -43,6 +43,14 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
modalPositionX: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
modalPositionY: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
modalWidth: {
|
modalWidth: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 500
|
default: 500
|
||||||
@ -149,9 +157,16 @@ function handleResize() {
|
|||||||
function initializePosition() {
|
function initializePosition() {
|
||||||
width.value = Math.min(props.modalWidth, window.innerWidth)
|
width.value = Math.min(props.modalWidth, window.innerWidth)
|
||||||
height.value = Math.min(props.modalHeight, window.innerHeight)
|
height.value = Math.min(props.modalHeight, window.innerHeight)
|
||||||
|
if(props.modalPositionX !== 0 && props.modalPositionY !== 0) {
|
||||||
|
console.log(props.modalPositionX)
|
||||||
|
console.log(props.modalPositionY)
|
||||||
|
x.value = props.modalPositionX
|
||||||
|
y.value = props.modalPositionY
|
||||||
|
} else {
|
||||||
x.value = (window.innerWidth - width.value) / 2
|
x.value = (window.innerWidth - width.value) / 2
|
||||||
y.value = (window.innerHeight - height.value) / 2
|
y.value = (window.innerHeight - height.value) / 2
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleFullScreen() {
|
function toggleFullScreen() {
|
||||||
if (isFullScreen.value) {
|
if (isFullScreen.value) {
|
||||||
@ -192,12 +207,28 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modalPositionX,
|
||||||
|
(value) => {
|
||||||
|
x.value = value
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modalPositionY,
|
||||||
|
(value) => {
|
||||||
|
y.value = value
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
window.addEventListener('mousemove', drag)
|
window.addEventListener('mousemove', drag)
|
||||||
window.addEventListener('mouseup', stopDrag)
|
window.addEventListener('mouseup', stopDrag)
|
||||||
window.addEventListener('mousemove', resizeModal)
|
window.addEventListener('mousemove', resizeModal)
|
||||||
window.addEventListener('mouseup', stopResize)
|
window.addEventListener('mouseup', stopResize)
|
||||||
|
if(props.modalPositionX !== 0 && props.modalPositionY !== 0) {
|
||||||
window.addEventListener('resize', handleResize)
|
window.addEventListener('resize', handleResize)
|
||||||
|
}
|
||||||
initializePosition()
|
initializePosition()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -206,6 +237,8 @@ onUnmounted(() => {
|
|||||||
window.removeEventListener('mouseup', stopDrag)
|
window.removeEventListener('mouseup', stopDrag)
|
||||||
window.removeEventListener('mousemove', resizeModal)
|
window.removeEventListener('mousemove', resizeModal)
|
||||||
window.removeEventListener('mouseup', stopResize)
|
window.removeEventListener('mouseup', stopResize)
|
||||||
|
if(props.modalPositionX !== 0 && props.modalPositionY !== 0) {
|
||||||
window.removeEventListener('resize', handleResize)
|
window.removeEventListener('resize', handleResize)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -13,7 +13,7 @@ import type { Character as CharacterT, Zone as ZoneT, ExtendedCharacter as Exten
|
|||||||
import Tiles from '@/components/zone/Tiles.vue'
|
import Tiles from '@/components/zone/Tiles.vue'
|
||||||
import Objects from '@/components/zone/Objects.vue'
|
import Objects from '@/components/zone/Objects.vue'
|
||||||
import Characters from '@/components/zone/Characters.vue'
|
import Characters from '@/components/zone/Characters.vue'
|
||||||
import { loadAssets } from '@/composables/zoneComposable'
|
import { loadAssets, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
|
||||||
|
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
const zoneStore = useZoneStore()
|
const zoneStore = useZoneStore()
|
||||||
@ -26,19 +26,23 @@ type zoneLoadData = {
|
|||||||
characters: CharacterT[]
|
characters: CharacterT[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gameStore.connection!.emit('zone:character:join', { zoneId: gameStore.character!.zoneId }, async (response: zoneLoadData) => {
|
gameStore.connection!.emit('zone:character:join', { zoneId: gameStore.character!.zoneId }, async (response: zoneLoadData) => {
|
||||||
// Fetch assets for new zone
|
// Fetch assets for new zone
|
||||||
await gameStore.fetchZoneAssets(response.zone.id)
|
await gameStore.fetchZoneAssets(response.zone.id)
|
||||||
await loadAssets(scene)
|
await loadAssets(scene)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Set zone and characters
|
// Set zone and characters
|
||||||
zoneStore.setZone(response.zone)
|
zoneStore.setZone(response.zone)
|
||||||
zoneStore.setCharacters(response.characters)
|
zoneStore.setCharacters(response.characters)
|
||||||
|
scene.cameras.main.setScroll(-(scene.cameras.main.worldView.width/2) - gameStore.character.relativePosition.x, -(scene.cameras.main.worldView.height/2) + gameStore.character.relativePosition.y)
|
||||||
|
console.log('--- CHARACTER JOIN')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Event listeners
|
// Event listeners
|
||||||
gameStore.connection!.on('zone:character:teleport', async (data: zoneLoadData) => {
|
gameStore.connection!.on('zone:character:teleport', async (data: zoneLoadData) => {
|
||||||
console.log('eeee');
|
|
||||||
/**
|
/**
|
||||||
* This is the cause of the bug
|
* This is the cause of the bug
|
||||||
*/
|
*/
|
||||||
@ -56,6 +60,12 @@ gameStore.connection!.on('zone:character:teleport', async (data: zoneLoadData) =
|
|||||||
|
|
||||||
zoneStore.setZone(data.zone)
|
zoneStore.setZone(data.zone)
|
||||||
zoneStore.setCharacters(data.characters)
|
zoneStore.setCharacters(data.characters)
|
||||||
|
|
||||||
|
const character = gameStore.character;
|
||||||
|
// Position character centered on zone change or teleport
|
||||||
|
const posX = tileToWorldX(tileMap.value, character.positionX, character.positionY)
|
||||||
|
const posY = tileToWorldY(tileMap.value, character.positionX, character.positionY)
|
||||||
|
scene.cameras.main.setScroll(-(scene.cameras.main.worldView.width/2) + posX, -(scene.cameras.main.worldView.height/2) + posY)
|
||||||
})
|
})
|
||||||
|
|
||||||
gameStore.connection!.on('zone:character:join', async (data: ExtendedCharacterT) => {
|
gameStore.connection!.on('zone:character:join', async (data: ExtendedCharacterT) => {
|
||||||
|
@ -6,6 +6,15 @@ export function useCameraControls(scene: Phaser.Scene): any {
|
|||||||
const camera = ref(scene.cameras.main)
|
const camera = ref(scene.cameras.main)
|
||||||
const isDragging = ref(false)
|
const isDragging = ref(false)
|
||||||
|
|
||||||
|
// Resize center camera on character.
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
console.log('woep')
|
||||||
|
// Need to change camera position next frame
|
||||||
|
setTimeout(() => {
|
||||||
|
scene.cameras.main.setScroll(-(scene.cameras.main.worldView.width/2) + gameStore.character.relativePosition.x, -(scene.cameras.main.worldView.height/2) + gameStore.character.relativePosition.y)
|
||||||
|
}, 0)
|
||||||
|
})
|
||||||
|
|
||||||
function onPointerDown(pointer: Phaser.Input.Pointer) {
|
function onPointerDown(pointer: Phaser.Input.Pointer) {
|
||||||
if (pointer.event instanceof MouseEvent || pointer.event.shiftKey) {
|
if (pointer.event instanceof MouseEvent || pointer.event.shiftKey) {
|
||||||
isDragging.value = true
|
isDragging.value = true
|
||||||
|
@ -142,6 +142,7 @@ export type Character = {
|
|||||||
role: string
|
role: string
|
||||||
positionX: number
|
positionX: number
|
||||||
positionY: number
|
positionY: number
|
||||||
|
relativePosition: {x: number, y: number}
|
||||||
rotation: number
|
rotation: number
|
||||||
zoneId: number
|
zoneId: number
|
||||||
zone: Zone
|
zone: Zone
|
||||||
|
Loading…
x
Reference in New Issue
Block a user