Files
cultivation-world-simulator/web/src/components/game/GameCanvas.vue
2025-12-06 15:52:28 +08:00

89 lines
2.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { Application } from 'vue3-pixi'
import { ref, onMounted } from 'vue'
import { useElementSize } from '@vueuse/core'
import Viewport from './Viewport.vue'
import MapLayer from './MapLayer.vue'
import EntityLayer from './EntityLayer.vue'
import CloudLayer from './CloudLayer.vue'
import { useTextures } from './composables/useTextures'
const container = ref<HTMLElement>()
const { width, height } = useElementSize(container)
const { loadBaseTextures, isLoaded } = useTextures()
const mapSize = ref({ width: 2000, height: 2000 })
const emit = defineEmits<{
(e: 'avatarSelected', payload: { type: 'avatar'; id: string; name?: string }): void
(e: 'regionSelected', payload: { type: 'region'; id: string; name?: string }): void
}>()
function onMapLoaded(size: { width: number, height: number }) {
mapSize.value = size
}
function handleAvatarSelected(payload: { type: 'avatar'; id: string; name?: string }) {
emit('avatarSelected', payload)
}
function handleRegionSelected(payload: { type: 'region'; id: string; name?: string }) {
emit('regionSelected', payload)
}
const devicePixelRatio = 1 // 强制为 1避免像素风游戏在高分屏下的坐标和缩放问题
onMounted(() => {
loadBaseTextures()
})
</script>
<template>
<div ref="container" class="game-canvas-container">
<!--
antialias: false (像素风必须关闭)
resolution: devicePixelRatio (保证清晰度)
background-color: 0x000000
-->
<Application
v-if="width > 0 && height > 0"
:width="width"
:height="height"
:background-color="0x000000"
:antialias="false"
:resolution="devicePixelRatio"
>
<Viewport
v-if="isLoaded"
:screen-width="width"
:screen-height="height"
:world-width="mapSize.width"
:world-height="mapSize.height"
>
<!--
注意之前使用的 store.worldVersion 已移除
如果需要重新渲染 MapLayer例如读档后
现在依赖于 worldStore.initialize() 触发 mapData 变更
以及 MapLayer 内部对 worldStore.isLoaded 的监听
如果发现读档不刷新的问题可以在 MapLayer 增加 key
-->
<MapLayer
@mapLoaded="onMapLoaded"
@regionSelected="handleRegionSelected"
/>
<EntityLayer @avatarSelected="handleAvatarSelected" />
<CloudLayer :width="mapSize.width" :height="mapSize.height" />
</Viewport>
</Application>
</div>
</template>
<style scoped>
.game-canvas-container {
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
}
</style>