Files
text-adventure-game/components/drawers/EventDrawer.vue

148 lines
2.8 KiB
Vue
Raw Normal View History

<template>
<view class="event-drawer">
<view class="event-header">
<text class="event-title">{{ eventData.title }}</text>
<text class="event-close" @click="close">×</text>
</view>
<view class="event-content">
<!-- NPC信息 -->
<view v-if="eventData.npc" class="npc-info">
<text class="npc-name">{{ eventData.npc.name }}</text>
</view>
<!-- 对话文本 -->
<scroll-view class="dialogue-text" scroll-y>
<text class="dialogue-content">{{ eventData.text }}</text>
</scroll-view>
<!-- 选项按钮 -->
<view class="dialogue-choices">
<TextButton
v-for="choice in eventData.choices"
:key="choice.text"
:text="choice.text"
@click="selectChoice(choice)"
/>
</view>
</view>
</view>
</template>
<script setup>
import { computed } from 'vue'
import { useGameStore } from '@/store/game'
import { usePlayerStore } from '@/store/player'
import { handleDialogueChoice } from '@/utils/eventSystem'
import TextButton from '@/components/common/TextButton.vue'
const game = useGameStore()
const player = usePlayerStore()
const emit = defineEmits(['close'])
const eventData = computed(() => {
if (!game.currentEvent) {
return {
title: '事件',
npc: null,
text: '暂无事件',
choices: []
}
}
return {
title: game.currentEvent.npc?.name || '事件',
npc: game.currentEvent.npc,
text: game.currentEvent.text || '',
choices: game.currentEvent.choices || []
}
})
function close() {
emit('close')
}
function selectChoice(choice) {
const result = handleDialogueChoice(game, player, choice)
if (result.closeEvent) {
close()
}
}
</script>
<style lang="scss" scoped>
.event-drawer {
height: 100%;
display: flex;
flex-direction: column;
background-color: $bg-secondary;
}
.event-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx;
border-bottom: 1rpx solid $border-color;
}
.event-title {
color: $text-primary;
font-size: 32rpx;
font-weight: bold;
}
.event-close {
color: $text-secondary;
font-size: 48rpx;
padding: 0 16rpx;
&:active {
color: $text-primary;
}
}
.event-content {
flex: 1;
display: flex;
flex-direction: column;
padding: 24rpx;
}
.npc-info {
padding: 16rpx;
background-color: $bg-primary;
border-radius: 8rpx;
margin-bottom: 16rpx;
}
.npc-name {
color: $accent;
font-size: 28rpx;
font-weight: bold;
}
.dialogue-text {
flex: 1;
max-height: 400rpx;
margin-bottom: 24rpx;
padding: 16rpx;
background-color: $bg-primary;
border-radius: 8rpx;
}
.dialogue-content {
color: $text-primary;
font-size: 28rpx;
line-height: 1.8;
}
.dialogue-choices {
display: flex;
flex-direction: column;
gap: 16rpx;
}
</style>