Browse Source

增加一个游戏指南

master
秦汉 1 month ago
parent
commit
4995f001ec
  1. 1
      Build_God_Game/src/assets/icons/equipment/登龙剑.svg
  2. 1
      Build_God_Game/src/assets/icons/pill/渡厄丹.svg
  3. 6
      Build_God_Game/src/assets/images/bag.svg
  4. 6
      Build_God_Game/src/router/index.ts
  5. 3
      Build_God_Game/src/views/CharacterView.vue
  6. 24
      Build_God_Game/src/views/GameView.vue
  7. 318
      Build_God_Game/src/views/TutorialView.vue
  8. 74
      docs/superpowers/specs/2026-04-11-tutorial-feature-design.md

1
Build_God_Game/src/assets/icons/equipment/登龙剑.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.0 KiB

1
Build_God_Game/src/assets/icons/pill/渡厄丹.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775889570255" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8059" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M865.664 158.4a213.056 213.056 0 0 0-301.28 0L158.4 564.352a213.056 213.056 0 0 0 301.28 301.248l406.048-405.952a213.216 213.216 0 0 0-0.064-301.248z m-451.2 661.952a149.024 149.024 0 1 1-210.816-210.752L384 429.248 594.784 640l-180.352 180.352zM820.416 414.4L640 594.752 429.28 384l180.384-180.352a149.056 149.056 0 0 1 210.784 210.752z m-61.728-85.024a32.032 32.032 0 0 1 0 45.28l-96 96a32.064 32.064 0 0 1-52.192-10.432 32.032 32.032 0 0 1 6.944-34.88l96-96a32 32 0 0 1 45.248 0z" p-id="8060" data-spm-anchor-id="a313x.search_index.0.i6.36043a81u4mIW1" class="selected" fill="#1296db"></path></svg>

After

Width:  |  Height:  |  Size: 934 B

6
Build_God_Game/src/assets/images/bag.svg

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 6.4 KiB

6
Build_God_Game/src/router/index.ts

@ -33,6 +33,12 @@ const router = createRouter({
component: () => import('@/views/GameView.vue'), component: () => import('@/views/GameView.vue'),
meta: { requiresAuth: true } meta: { requiresAuth: true }
}, },
{
path: '/tutorial',
name: 'tutorial',
component: () => import('@/views/TutorialView.vue'),
meta: { requiresAuth: true }
},
{ {
path: '/training', path: '/training',
name: 'training', name: 'training',

3
Build_God_Game/src/views/CharacterView.vue

@ -74,6 +74,9 @@ const handleCreateCharacter = async () => {
newCharacterName.value = '' newCharacterName.value = ''
newCharacterProfessionId.value = null newCharacterProfessionId.value = null
showProfessionSelection.value = false showProfessionSelection.value = false
if (!localStorage.getItem('has_seen_tutorial')) {
router.push('/tutorial')
}
} else { } else {
errorMsg.value = '创建失败,可能名称已存在或已达角色数量上限(3个)' errorMsg.value = '创建失败,可能名称已存在或已达角色数量上限(3个)'
} }

24
Build_God_Game/src/views/GameView.vue

@ -61,6 +61,10 @@ const handleSwitchCharacter = () => {
window.location.href = '/character' window.location.href = '/character'
} }
const navigateToTutorial = () => {
router.push('/tutorial')
}
const navigateTo = (item: { label: string }) => { const navigateTo = (item: { label: string }) => {
if (item.label === '打坐' || item.label === '打坐中') { if (item.label === '打坐' || item.label === '打坐中') {
router.push('/training') router.push('/training')
@ -103,6 +107,9 @@ const handleBreakthrough = async () => {
<ShinyText class="welcome-text" text="✨ 欢迎来到我的世界" :speed="2" :delay="0.5" :disabled="false" :color="'#b5b5b5'" <ShinyText class="welcome-text" text="✨ 欢迎来到我的世界" :speed="2" :delay="0.5" :disabled="false" :color="'#b5b5b5'"
:shine-color="'#34fef1'" :spread="120" :direction="'left'" :yoyo="false" :pause-on-hover="false" /> :shine-color="'#34fef1'" :spread="120" :direction="'left'" :yoyo="false" :pause-on-hover="false" />
</div> </div>
<div style="text-align: center; margin-bottom: 16px;">
<button class="tutorial-btn" @click="navigateToTutorial">游戏指南</button>
</div>
<div class="menu-grid"> <div class="menu-grid">
<GlareHover v-for="item in menuItems" :key="item.label" width="100%" height="100px" <GlareHover v-for="item in menuItems" :key="item.label" width="100%" height="100px"
@ -257,6 +264,23 @@ const handleBreakthrough = async () => {
margin-bottom: 32px; margin-bottom: 32px;
} }
.tutorial-btn {
padding: 8px 20px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px;
color: #888888;
font-size: 0.85rem;
cursor: pointer;
transition: all 0.2s ease;
}
.tutorial-btn:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.2);
color: #ffffff;
}
.menu-card { .menu-card {
cursor: pointer; cursor: pointer;
} }

318
Build_God_Game/src/views/TutorialView.vue

@ -0,0 +1,318 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useCharacterStore } from '@/stores/character'
import Particles from '@/components/Particles/Particles.vue'
import TextType from '@/components/TextType/TextType.vue'
import StarBorder from '@/components/StarBorder/StarBorder.vue'
const router = useRouter()
const characterStore = useCharacterStore()
const currentPage = ref(0)
interface TutorialPage {
title: string
content: string[]
}
const tutorialPages: TutorialPage[] = [
{
title: '世界观',
content: [
'天地未开,混沌一片。',
'亿万年前,域外天魔入侵,引发了远古神战。',
'战神以身化道,封印天魔于无尽虚空。',
'天地灵气开始复苏,修炼之道由此大兴。',
'玩家降临此界,将踏上修炼之路,寻求成仙之道。'
]
},
{
title: '装备系统',
content: [
'装备分为三大类:武器、防具、饰品。',
'武器增加攻击,如飞剑、长刀、长枪等。',
'防具增加防御和生命,如铠甲、法袍等。',
'饰品附加特殊属性,如戒指、项链、玉佩等。',
'装备品质分为:凡品、上品、精品、极品、仙器、神器。',
'高品质装备可通过锻造、掉落或交易获得。'
]
},
{
title: '丹药系统',
content: [
'丹药是修炼者不可或缺的资源。',
'修炼类:聚气丹、破境丹,帮助快速提升修为。',
'战斗类:回血丹、爆发丹,战斗时使用。',
'辅助类:隐身丹、传送符,特殊场合使用。',
'丹药可通过炼丹炉炼制,或击杀怪物掉落。',
'高品质丹药需要珍稀药材才能炼制。'
]
},
{
title: '境界体系',
content: [
'修炼境界分为:炼气、筑基、金丹、元婴、化神、大乘、飞升。',
'每境界有九层,需积累足够经验才能突破。',
'突破需要满足境界条件,如修为、丹药等。',
'境界越高,属性加成越高,能力越强。',
'达到飞升境界,即可飞升仙界,寻求更高的道。'
]
}
]
const totalPages = computed(() => tutorialPages.length)
const currentPageData = computed(() => tutorialPages[currentPage.value])
const isLastPage = computed(() => currentPage.value === tutorialPages.length - 1)
const goToNextPage = () => {
if (currentPage.value < tutorialPages.length - 1) {
currentPage.value++
}
}
const goToPrevPage = () => {
if (currentPage.value > 0) {
currentPage.value--
}
}
const skipTutorial = () => {
localStorage.setItem('has_seen_tutorial', 'true')
router.push('/game')
}
const startGame = () => {
localStorage.setItem('has_seen_tutorial', 'true')
router.push('/game')
}
onMounted(async () => {
await characterStore.fetchCharacters()
})
</script>
<template>
<div class="tutorial-page">
<Particles :particle-count="50" :particle-colors="['#ffffff', '#cccccc']" class="particles-bg" />
<div class="tutorial-container">
<div class="page-header">
<TextType
:key="`title-${currentPage}`"
:text="[currentPageData.title]"
:typingSpeed="80"
:pauseDuration="1500"
:showCursor="false"
class="page-title"
/>
<span class="page-indicator">{{ currentPage + 1 }} / {{ totalPages }}</span>
</div>
<div class="content-area">
<div v-for="(line, lineIndex) in currentPageData.content" :key="`${currentPage}-${lineIndex}`" class="content-line">
<TextType
:text="[line]"
:typingSpeed="30"
:pauseDuration="1000"
:initialDelay="lineIndex * 300"
:showCursor="false"
class="content-text"
/>
</div>
</div>
<div class="pagination">
<div class="page-dots">
<span
v-for="(_, index) in tutorialPages"
:key="index"
class="dot"
:class="{ active: index === currentPage }"
@click="currentPage = index"
/>
</div>
</div>
<div class="page-actions">
<button
class="nav-btn prev-btn"
:disabled="currentPage === 0"
@click="goToPrevPage"
>
上一页
</button>
<StarBorder as="div" color="#22c55e" speed="5s" :thickness="2">
<button
v-if="isLastPage"
class="start-btn"
@click="startGame"
>
开始游戏
</button>
<button
v-else
class="skip-btn"
@click="skipTutorial"
>
跳过
</button>
</StarBorder>
<button
class="nav-btn next-btn"
:disabled="currentPage === totalPages - 1"
@click="goToNextPage"
>
下一页
</button>
</div>
</div>
</div>
</template>
<style scoped>
.tutorial-page {
min-height: 100vh;
background: #000000;
position: relative;
overflow: hidden;
}
.particles-bg {
position: fixed !important;
top: 0;
left: 0;
width: 100% !important;
height: 100% !important;
}
.tutorial-container {
position: relative;
z-index: 10;
max-width: 600px;
margin: 0 auto;
padding: 40px 20px;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 32px;
}
.page-title {
font-size: 1.5rem;
font-weight: bold;
color: #ffffff;
}
.page-indicator {
color: #888888;
font-size: 0.875rem;
}
.content-area {
flex: 1;
padding: 20px 0;
}
.content-line {
margin-bottom: 16px;
}
.content-text {
font-size: 1rem;
line-height: 1.8;
color: #cccccc;
}
.pagination {
display: flex;
justify-content: center;
margin: 24px 0;
}
.page-dots {
display: flex;
gap: 12px;
}
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.2);
cursor: pointer;
transition: all 0.3s ease;
}
.dot:hover {
background: rgba(255, 255, 255, 0.4);
}
.dot.active {
background: #22c55e;
transform: scale(1.2);
}
.page-actions {
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
margin-top: 24px;
}
.nav-btn {
padding: 12px 20px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 10px;
color: #888888;
font-size: 0.9rem;
cursor: pointer;
transition: all 0.2s ease;
min-width: 80px;
}
.nav-btn:hover:not(:disabled) {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.2);
color: #ffffff;
}
.nav-btn:disabled {
opacity: 0.3;
cursor: not-allowed;
}
.start-btn,
.skip-btn {
padding: 12px 32px;
background: transparent;
border: none;
border-radius: 10px;
font-size: 1rem;
cursor: pointer;
transition: all 0.2s ease;
}
.start-btn {
color: #22c55e;
}
.skip-btn {
color: #888888;
}
.start-btn:hover,
.skip-btn:hover {
transform: translateY(-2px);
}
</style>

74
docs/superpowers/specs/2026-04-11-tutorial-feature-design.md

@ -0,0 +1,74 @@
# 游戏教程功能设计
## 概述
创建一个游戏教程/介绍界面,在玩家创建角色后自动弹出,展示游戏世界观、装备系统、丹药系统、境界等级等信息,采用分页展示,使用 TextType 组件逐字显示文字。
## 功能需求
1. **自动触发**:玩家创建角色成功后自动弹出教程
2. **手动触发**:游戏主界面有"游戏指南"按钮可再次查看
3. **全屏弹窗**:覆盖整个屏幕的模态窗口
4. **分页展示**:多个页面分别为世界观、装备、丹药、境界等
5. **退出方式**:底部"跳过"按钮关闭
## UI/UX 设计
### 布局
- 全屏覆盖弹窗(`position: fixed`)
- 顶部:页面标题 + 页码指示器(如 1/4)
- 中间:内容区域,支持滚动
- 底部:"跳过"按钮
### 分页结构
1. **第一页:世界观**
- 游戏背景介绍
- 修炼体系说明
2. **第二页:装备系统**
- 装备分类(武器、防具、饰品等)
- 装备品质说明
3. **第三页:丹药系统**
- 各类丹药介绍
- 丹药用途
4. **第四页:境界等级**
- 境界划分
- 修炼路线
### 交互
- 左右滑动或按钮切换页面
- TextType 组件逐字显示文字
- 最后一页显示"开始游戏"按钮
## 技术实现
### 文件结构
```
Build_God_Game/src/views/TutorialView.vue # 新建
Build_God_Game/src/router/index.ts # 修改
```
### 路由
- 路径:`/tutorial`
- 需要认证:`requiresAuth: true`
### 组件设计
- 使用 TextType 组件显示文字
- 使用分页组件管理多页内容
- 支持键盘/按钮导航
## 验收标准
1. 创建角色后自动跳转到教程页面
2. 教程使用 TextType 动画显示文字
3. 可通过分页按钮切换页面
4. 点击"跳过"或"开始游戏"进入游戏主界面
5. GameView 有"游戏指南"按钮可重新查看
Loading…
Cancel
Save