544 lines
15 KiB
XML
544 lines
15 KiB
XML
<template>
|
|
<div class="page" @swipe="back" @click="nextDialogue">
|
|
<image src="internal://files/{{Img}}"></image>
|
|
<image
|
|
style="position: absolute; top: 300px; left: 0"
|
|
src="/common/text_bg.png"
|
|
if="{{gameData.scenes[currentScene].choices == undefined && Img !== 'bg.png'}}"></image>
|
|
<text
|
|
style="
|
|
position: absolute;
|
|
height: 50px;
|
|
top: 250px;
|
|
left: 8px;
|
|
font-size: 28px;
|
|
color: #ffffff;
|
|
font-weight: bold;
|
|
"
|
|
if="{{gameData.scenes[currentScene].choices == undefined && Img !== 'bg.png'}}">
|
|
{{ character }}
|
|
</text>
|
|
<scroll
|
|
scroll-y="true"
|
|
bounces="true"
|
|
class="scroll"
|
|
id="scroll"
|
|
if="{{gameData.scenes[currentScene].choices == undefined && Img !== 'bg.png'}}">
|
|
<text
|
|
style="color: #FFFFFF;font-weight: bold;width: 100%;text-align: left;font-size: {{settings.textSize}}px;">
|
|
{{ showText }}
|
|
</text>
|
|
</scroll>
|
|
<div
|
|
class="page"
|
|
style="background-color: #000000"
|
|
@click="nextDialogue"></div>
|
|
<!--选项页-->
|
|
<div
|
|
class="page"
|
|
style="position: absolute"
|
|
if="{{gameData.scenes[currentScene].choices !== undefined}}">
|
|
<!--选项1-->
|
|
<text class="choice" @click="selectChoice(0)">
|
|
{{ gameData.scenes[currentScene].choices[0].text }}
|
|
</text>
|
|
<!--选项2-->
|
|
<text class="choice" style="top: 210px" @click="selectChoice(1)">
|
|
{{ gameData.scenes[currentScene].choices[1].text }}
|
|
</text>
|
|
</div>
|
|
<!--菜单页-->
|
|
<div
|
|
class="page"
|
|
style="
|
|
position: absolute;
|
|
flex-wrap: nowrap;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: #ffffff;
|
|
"
|
|
if="{{menu}}">
|
|
<text class="menu-btn" @click="toRecoveryPage(1)">保存</text>
|
|
<text class="menu-btn" @click="toRecoveryPage(2)">加载</text>
|
|
<text class="menu-btn" @click="skipScene(1)">跳过场景</text>
|
|
<text class="menu-btn" @click="skipChapter(chapter + 1)">跳过章节</text>
|
|
<text class="menu-btn" @click="back('m')">返回</text>
|
|
</div>
|
|
<div
|
|
class="page"
|
|
style="position: absolute; background-color: #ffffff"
|
|
if="{{recovery===1}}"
|
|
@swipe="back()">
|
|
<scroll scroll-y="true" bounces="true" class="scroll1 page">
|
|
<text class="menu-btn">长按删除存档</text>
|
|
<text class="menu-btn">点击存档覆盖</text>
|
|
<text
|
|
class="menu-btn"
|
|
for="{{recoveryData}}"
|
|
style="font-size: 30px"
|
|
@click="saveRecoveryData($idx)"
|
|
@longpress="deleteRecoveryData($idx)">
|
|
存档{{ $idx + 1 }}
|
|
</text>
|
|
<text class="menu-btn" @click="saveRecoveryData('new')">+</text>
|
|
</scroll>
|
|
</div>
|
|
<div
|
|
class="page"
|
|
style="position: absolute; background-color: #ffffff"
|
|
if="{{recovery===2}}"
|
|
@swipe="back()">
|
|
<scroll scroll-y="true" bounces="true" class="scroll1 page">
|
|
<text class="menu-btn">点击读取存档</text>
|
|
<text
|
|
class="menu-btn"
|
|
for="{{recoveryData}}"
|
|
style="font-size: 30px"
|
|
@click="loadRecoveryData($idx)"
|
|
@longpress="consoleData($idx)">
|
|
存档{{ $idx + 1 }}
|
|
</text>
|
|
</scroll>
|
|
</div>
|
|
<div
|
|
class="page"
|
|
style="
|
|
position: absolute;
|
|
background-color: #ffffff;
|
|
flex-wrap: nowrap;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
"
|
|
if="{{END != ''}}"
|
|
@swipe="back()">
|
|
<text style="font-size: 30px; text-align: center; color: #000000">
|
|
达成结局:{{ END }}
|
|
</text>
|
|
<text
|
|
style="font-size: 30px; text-align: center; color: #000000"
|
|
@click="back('e')">
|
|
返回主页
|
|
</text>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import router from '@blueos.app.appmanager.router'
|
|
import storage from '@blueos.storage.storage'
|
|
import prompt from '@blueos.window.prompt'
|
|
import file from '@blueos.storage.file'
|
|
let t1, t2, t3
|
|
export default {
|
|
data: {
|
|
gameData: {
|
|
scenes: [],
|
|
},
|
|
index: 0,
|
|
canContinue: true,
|
|
currentScene: 0,
|
|
currentDialogue: 0,
|
|
Img: 'bg.png',
|
|
showText: '',
|
|
character: '',
|
|
settings: {
|
|
textSpeed: 40,
|
|
textSize: 22,
|
|
},
|
|
chapter: 0,
|
|
menu: false,
|
|
recovery: 0,
|
|
choice: [],
|
|
recoveryData: [],
|
|
load: null,
|
|
END: '',
|
|
jsonDataList: [
|
|
'b999.json',
|
|
'b101.json',
|
|
'b102.json',
|
|
'b103.json',
|
|
'b111.json',
|
|
'b112.json',
|
|
'b113.json',
|
|
'b114.json',
|
|
'b121.json',
|
|
'b122.json',
|
|
'b123.json',
|
|
'b124.json',
|
|
'b200.json',
|
|
'b201.json',
|
|
'b202.json',
|
|
'b203.json',
|
|
'b204.json',
|
|
'b205.json',
|
|
'b206.json',
|
|
'b207.json',
|
|
'b301.json',
|
|
'b302.json',
|
|
'b303.json',
|
|
'b304.json',
|
|
'b401.json',
|
|
'b402.json',
|
|
'b403.json',
|
|
'b404.json',
|
|
'b405.json',
|
|
'b406.json',
|
|
'b407.json',
|
|
'b501.json',
|
|
'b601.json',
|
|
'b701.json',
|
|
],
|
|
},
|
|
onInit() {
|
|
//
|
|
router.clear()
|
|
storage.get({
|
|
key: 'recoveryData',
|
|
success: (data) => {
|
|
if (data) {
|
|
this.recoveryData = JSON.parse(data)
|
|
if (this.load) {
|
|
if (this.load === 'TE') {
|
|
this.loadData('TE')
|
|
this.loadScene(this.currentScene)
|
|
} else {
|
|
this.loadRecoveryData(this.load)
|
|
}
|
|
} else {
|
|
this.loadData(this.chapter)
|
|
this.loadScene(this.currentScene)
|
|
}
|
|
} else {
|
|
this.loadData(this.chapter)
|
|
this.loadScene(this.currentScene)
|
|
}
|
|
},
|
|
fail: () => {},
|
|
})
|
|
storage.get({
|
|
key: 'settings',
|
|
success: (data) => {
|
|
if (data) {
|
|
this.settings = JSON.parse(data)
|
|
}
|
|
},
|
|
fail: () => {},
|
|
})
|
|
},
|
|
async loadData(chapter) {
|
|
let num
|
|
if (chapter == 'BE') {
|
|
num = 'b601.json'
|
|
} else if (chapter == 'TE') {
|
|
num = 'b701.json'
|
|
} else {
|
|
num = this.jsonDataList[chapter]
|
|
}
|
|
|
|
console.log(num)
|
|
await file.readText({
|
|
uri: `internal://files/${num}`,
|
|
success: (data) => {
|
|
this.gameData.scenes = JSON.parse(data.text)
|
|
//storage.getSync({ key: 'data' });
|
|
},
|
|
fail: function (_, code) {
|
|
prompt.showToast({ message: code.toString() })
|
|
},
|
|
})
|
|
},
|
|
// 显示背景图
|
|
showBackground(image) {
|
|
this.Img = image
|
|
},
|
|
// 显示对话
|
|
showDialogue(dialogue) {
|
|
this.showText = ''
|
|
this.character = dialogue.character
|
|
this.canContinue = false
|
|
this.index = 0
|
|
this.zhuzi(dialogue.text)
|
|
},
|
|
zhuzi(text) {
|
|
if (this.index < text.length) {
|
|
this.showText += text.charAt(this.index)
|
|
this.index++
|
|
t1 = setTimeout(() => {
|
|
this.zhuzi(text)
|
|
}, this.settings.textSpeed)
|
|
} else {
|
|
this.canContinue = true
|
|
}
|
|
},
|
|
onDestroy() {
|
|
// 解除内存占用
|
|
clearTimeout(t1)
|
|
clearTimeout(t2)
|
|
clearTimeout(t3)
|
|
},
|
|
// 加载场景
|
|
loadScene(sceneIndex) {
|
|
const scene = this.gameData.scenes[sceneIndex]
|
|
this.showBackground(scene.background)
|
|
this.currentDialogue = 0
|
|
if (scene.choices) {
|
|
return
|
|
}
|
|
this.showDialogue(scene.dialogues[this.currentDialogue])
|
|
},
|
|
// 下一段对话
|
|
nextDialogue() {
|
|
if (this.canContinue) {
|
|
this.scrollToTop() //避免显示bug
|
|
this.canContinue = false
|
|
const scene = this.gameData.scenes[this.currentScene]
|
|
if (this.currentDialogue < scene.dialogues.length - 1) {
|
|
this.currentDialogue++
|
|
this.showDialogue(scene.dialogues[this.currentDialogue])
|
|
} else if (this.currentScene < this.gameData.scenes.length - 1) {
|
|
if (scene.dialogues[this.currentDialogue].toScenes !== undefined) {
|
|
console.log('跳转场景[选项]')
|
|
this.currentScene += scene.dialogues[this.currentDialogue].toScenes
|
|
this.loadScene(this.currentScene)
|
|
} else {
|
|
console.log('跳转场景')
|
|
this.currentScene++
|
|
this.loadScene(this.currentScene)
|
|
}
|
|
} else {
|
|
if (scene.dialogues[this.currentDialogue].END !== undefined) {
|
|
this.END = scene.dialogues[this.currentDialogue].END
|
|
this.getFin(this.END)
|
|
// 分支
|
|
} else if (
|
|
scene.dialogues[this.currentDialogue].branch !== undefined
|
|
) {
|
|
console.log(this.choice)
|
|
console.log(scene.dialogues[this.currentDialogue].branch.choices)
|
|
if (
|
|
JSON.stringify(this.choice) ===
|
|
JSON.stringify(
|
|
scene.dialogues[this.currentDialogue].branch.choices
|
|
)
|
|
) {
|
|
console.log('跳转章节[HE]')
|
|
this.chapter =
|
|
scene.dialogues[this.currentDialogue].branch.toChapter
|
|
this.loadData(this.chapter)
|
|
this.currentScene = 0
|
|
this.currentDialogue = 0
|
|
this.loadScene(this.currentScene)
|
|
} else {
|
|
console.log('跳转章节[BE]')
|
|
this.chapter = 'BE'
|
|
this.loadData(this.chapter)
|
|
this.currentScene = 0
|
|
this.currentDialogue = 0
|
|
this.loadScene(this.currentScene)
|
|
}
|
|
} else {
|
|
this.Img = 'bg.png'
|
|
t2 = setTimeout(() => {
|
|
this.chapter++
|
|
this.loadData(this.chapter)
|
|
this.currentScene = 0
|
|
this.currentDialogue = 0
|
|
this.loadScene(this.currentScene)
|
|
}, 3000)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
back(a) {
|
|
if (a == 'm' && this.menu) {
|
|
this.menu = false
|
|
} else if (a.direction == 'right' && this.recovery !== 0) {
|
|
this.recovery = 0
|
|
} else if (a.direction == 'right' || a == 'e') {
|
|
router.replace({ uri: '/pages/index' })
|
|
} else if (a.direction == 'left') {
|
|
this.menu = true
|
|
}
|
|
},
|
|
// 选择选项
|
|
selectChoice(choiceIndex) {
|
|
console.log('选择选项', choiceIndex)
|
|
this.choice.push(choiceIndex)
|
|
console.log(this.choice)
|
|
const nextSceneIndex =
|
|
this.gameData.scenes[this.currentScene].choices[choiceIndex].nextScene
|
|
this.currentScene += nextSceneIndex
|
|
this.loadScene(this.currentScene)
|
|
},
|
|
toRecoveryPage(a) {
|
|
this.recovery = a
|
|
},
|
|
saveRecoveryData(idx) {
|
|
const data = {
|
|
chapter: this.chapter,
|
|
currentScene: this.currentScene,
|
|
currentDialogue: this.currentDialogue,
|
|
choice: this.choice,
|
|
}
|
|
if (idx === 'new') {
|
|
this.recoveryData.push(data)
|
|
} else {
|
|
this.recoveryData[idx] = data
|
|
}
|
|
this.saveData()
|
|
prompt.showToast({
|
|
message: '存档成功',
|
|
})
|
|
},
|
|
deleteRecoveryData(idx) {
|
|
this.recoveryData.splice(idx, 1)
|
|
this.saveData()
|
|
prompt.showToast({ message: '删除成功' })
|
|
},
|
|
loadRecoveryData(idx) {
|
|
const data = this.recoveryData[parseInt(idx)]
|
|
console.log('加载存档', data)
|
|
this.chapter = data.chapter
|
|
this.currentScene = data.currentScene
|
|
this.currentDialogue = data.currentDialogue
|
|
this.choice = data.choice
|
|
this.recovery = 0
|
|
this.menu = false
|
|
this.loadData(this.chapter)
|
|
this.loadScene(this.currentScene)
|
|
},
|
|
skipScene(a) {
|
|
if (
|
|
this.gameData.scenes[this.currentScene].dialogues[
|
|
this.gameData.scenes[this.currentScene].dialogues.length - 1
|
|
].toScenes == undefined &&
|
|
this.gameData.scenes[this.currentScene].choices == undefined &&
|
|
this.gameData.scenes[this.currentScene].dialogues[
|
|
this.gameData.scenes[this.currentScene].dialogues.length - 1
|
|
].END == undefined &&
|
|
this.gameData.scenes[this.currentScene].dialogues[
|
|
this.gameData.scenes[this.currentScene].dialogues.length - 1
|
|
].branch == undefined &&
|
|
this.currentScene + a < this.gameData.scenes.length
|
|
) {
|
|
this.currentScene += a
|
|
this.loadScene(this.currentScene)
|
|
this.menu = false
|
|
} else {
|
|
this.menu = false
|
|
prompt.showToast({ message: '无法跳过' })
|
|
}
|
|
},
|
|
skipChapter(a) {
|
|
this.Img = 'bg.png'
|
|
this.menu = false
|
|
t3 = setTimeout(() => {
|
|
this.chapter = a
|
|
this.loadData(this.chapter)
|
|
this.currentScene = 0
|
|
this.currentDialogue = 0
|
|
this.loadScene(this.currentScene)
|
|
}, 3000)
|
|
},
|
|
saveData() {
|
|
storage.set({
|
|
key: 'recoveryData',
|
|
value: JSON.stringify(this.recoveryData),
|
|
success: () => {},
|
|
fail: () => {},
|
|
})
|
|
},
|
|
getFin(a) {
|
|
let fin = {}
|
|
storage.get({
|
|
key: 'fin',
|
|
success: (data) => {
|
|
if (data) {
|
|
fin = JSON.parse(data)
|
|
} else {
|
|
fin = { HE: false, BE: false }
|
|
}
|
|
if (a == 'Happy Ending') {
|
|
fin.HE = true
|
|
} else if (a == 'Bad Ending') {
|
|
fin.BE = true
|
|
}
|
|
this.saveFin(fin)
|
|
},
|
|
fail: () => {},
|
|
})
|
|
},
|
|
saveFin(a) {
|
|
storage.set({
|
|
key: 'fin',
|
|
value: JSON.stringify(a),
|
|
success: () => {},
|
|
fail: () => {},
|
|
})
|
|
},
|
|
consoleData(idx) {
|
|
console.log('存档数据', this.recoveryData[idx])
|
|
},
|
|
scrollToTop() {
|
|
this.$element('scroll').scrollTo({
|
|
top: 0,
|
|
left: 0,
|
|
behavior: 'instant',
|
|
})
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.page {
|
|
width: 390px;
|
|
height: 450px;
|
|
}
|
|
.scroll {
|
|
position: absolute;
|
|
bottom: 0;
|
|
top: 300px;
|
|
left: 8px;
|
|
right: 8px;
|
|
width: 390px;
|
|
height: 155px;
|
|
text-overflow: ellipsis;
|
|
flex-wrap: wrap;
|
|
}
|
|
.scroll1 {
|
|
position: absolute;
|
|
bottom: 0;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
text-overflow: ellipsis;
|
|
flex-wrap: nowrap;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
.choice {
|
|
position: absolute;
|
|
width: 250px;
|
|
height: 61px;
|
|
left: 43px;
|
|
top: 100px;
|
|
background-color: rgba(80, 192, 231, 0.7);
|
|
color: #ffffff;
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
text-align: center;
|
|
}
|
|
.menu-btn {
|
|
width: 250px;
|
|
height: 61px;
|
|
background-color: rgba(80, 192, 231, 0.7);
|
|
color: #ffffff;
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
text-align: center;
|
|
margin-bottom: 20px;
|
|
}
|
|
</style>
|