Files
shoot-miniprograms/src/pages/first-try.vue

244 lines
7.1 KiB
Vue
Raw Normal View History

2025-05-01 16:36:24 +08:00
<script setup>
2025-05-31 18:39:41 +08:00
import { ref, onMounted, onUnmounted } from "vue";
2025-05-01 22:58:02 +08:00
import Guide from "@/components/Guide.vue";
2025-05-10 16:57:36 +08:00
import SButton from "@/components/SButton.vue";
import Swiper from "@/components/Swiper.vue";
import BowTarget from "@/components/BowTarget.vue";
import ShootProgress from "@/components/ShootProgress.vue";
import ScoreResult from "@/components/ScoreResult.vue";
import ScorePanel from "@/components/ScorePanel.vue";
2025-05-23 21:20:38 +08:00
import Container from "@/components/Container.vue";
2025-06-17 16:58:24 +08:00
import Avatar from "@/components/Avatar.vue";
import BowPower from "@/components/BowPower.vue";
2025-06-17 21:34:41 +08:00
import { createPractiseAPI, getHomeData } from "@/apis";
2025-05-30 13:58:43 +08:00
import { MESSAGETYPES } from "@/constants";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user } = storeToRefs(store);
2025-06-17 21:34:41 +08:00
const { updateUser } = store;
2025-05-30 13:58:43 +08:00
const scores = ref([]);
2025-05-10 16:57:36 +08:00
const step = ref(0);
2025-05-30 13:58:43 +08:00
const showScore = ref(false);
const total = 12;
2025-05-10 16:57:36 +08:00
const stepButtonTexts = [
"开始",
"进入下一个任务",
"进入下一个任务",
"我准备好了,开始",
"",
"退出新手试炼",
];
2025-06-16 11:26:57 +08:00
const title = ref("新手试炼场");
2025-05-31 14:57:25 +08:00
const start = ref(false);
const practiseResult = ref({});
const power = ref(0);
2025-05-31 18:39:41 +08:00
const btnDisabled = ref(false);
2025-05-30 13:58:43 +08:00
2025-05-31 18:39:41 +08:00
const createPractise = async (arrows) => {
const result = await createPractiseAPI(arrows);
};
2025-06-05 21:32:15 +08:00
async function onReceiveMessage(content) {
const messages = JSON.parse(content).data.updates || [];
messages.forEach((msg) => {
if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
scores.value.push(msg.target);
2025-06-17 16:58:24 +08:00
power.value = msg.target.battery;
2025-06-05 21:32:15 +08:00
if (scores.value.length === total) {
showScore.value = true;
2025-05-30 13:58:43 +08:00
}
2025-06-05 21:32:15 +08:00
// if (step.value === 2 && msg.target.dst / 100 > 5) {
if (step.value === 2 && msg.target.dst > 5) {
btnDisabled.value = false;
2025-05-31 14:57:25 +08:00
}
2025-06-05 21:32:15 +08:00
}
if (msg.constructor === MESSAGETYPES.ShootSyncMePracticeID) {
practiseResult.value = {
...msg.practice,
arrows: JSON.parse(msg.practice.arrows),
};
}
2025-05-30 13:58:43 +08:00
});
2025-06-05 21:32:15 +08:00
}
onMounted(() => {
uni.$on("socket-inbox", onReceiveMessage);
2025-05-31 18:39:41 +08:00
});
2025-05-30 13:58:43 +08:00
onUnmounted(() => {
2025-06-05 21:32:15 +08:00
uni.$off("socket-inbox", onReceiveMessage);
2025-05-30 13:58:43 +08:00
});
2025-05-31 18:39:41 +08:00
const nextStep = async () => {
2025-05-10 16:57:36 +08:00
if (step.value === 0) {
step.value = 1;
2025-06-16 11:26:57 +08:00
title.value = "凹造型";
2025-05-10 16:57:36 +08:00
} else if (step.value === 1) {
2025-05-31 18:39:41 +08:00
btnDisabled.value = true;
2025-05-10 16:57:36 +08:00
step.value = 2;
2025-06-16 11:26:57 +08:00
title.value = "感知距离";
2025-05-10 16:57:36 +08:00
} else if (step.value === 2) {
step.value = 3;
2025-06-16 11:26:57 +08:00
title.value = "小试牛刀";
2025-05-10 16:57:36 +08:00
} else if (step.value === 3) {
2025-06-16 11:26:57 +08:00
title.value = "新手试炼场";
2025-05-31 18:39:41 +08:00
scores.value = [];
await createPractise(total);
2025-05-10 16:57:36 +08:00
step.value = 4;
2025-06-15 20:55:34 +08:00
setTimeout(() => {
start.value = true;
}, 500);
2025-05-10 16:57:36 +08:00
} else if (step.value === 5) {
2025-06-17 21:34:41 +08:00
const result = await getHomeData();
if (result.user) updateUser(result.user);
2025-05-10 16:57:36 +08:00
uni.navigateBack({
delta: 1,
});
}
};
2025-05-30 13:58:43 +08:00
2025-05-10 16:57:36 +08:00
const onClose = () => {
showScore.value = false;
setTimeout(() => {
step.value = 5;
}, 500);
};
2025-05-01 16:36:24 +08:00
</script>
<template>
2025-06-16 11:26:57 +08:00
<Container :bgType="1" :title="title">
2025-06-02 14:42:07 +08:00
<view class="container">
2025-06-16 11:26:57 +08:00
<Guide
v-if="step !== 4"
:tall="
(step === 1 && user.nickName.length > 6) || step === 2 || step === 5
"
>
2025-06-02 14:42:07 +08:00
<text v-if="step === 0">
hi<text :style="{ color: '#fed847' }">{{ user.nickName }}</text>
这是新人必刷小任务0基础小白也能快速掌握弓箭技巧和游戏规则哦~
</text>
<text v-if="step === 1"
>这是我们人帅技高的高教练首先请按教练示范尝试自己去做这些动作和手势吧</text
>
<view v-if="step === 2">
<view :style="{ display: 'flex', flexDirection: 'column' }">
<text :style="{ color: '#fed847' }">你知道5米射程有多远吗</text>
<text>
在我们的排位赛中射程小于5米的成绩无效建议平时练习距离至少5米现在来边射箭边调整你的站位点吧
</text>
</view>
2025-05-15 12:43:40 +08:00
</view>
2025-06-02 14:42:07 +08:00
<view v-if="step === 3">
<view :style="{ display: 'flex', flexDirection: 'column' }">
<text :style="{ color: '#fed847' }">一切准备就绪</text>
<text>试着完成一个真正的弓箭手任务吧</text>
</view>
2025-05-15 12:43:40 +08:00
</view>
2025-06-02 14:42:07 +08:00
<view v-if="step === 5">
<view
:style="{ display: 'flex', flexDirection: 'column', marginTop: 20 }"
2025-05-15 12:43:40 +08:00
>
2025-06-02 14:42:07 +08:00
<text :style="{ color: '#fed847' }">新手试炼场通关啦优秀</text>
<text
>反曲弓运动基本知识和射灵世界系统规则你已Get是不是挺容易呀</text
>
<!-- 这行是占位用的 -->
<text :style="{ opacity: 0 }">新手试炼场通关啦优秀</text>
</view>
2025-05-15 12:43:40 +08:00
</view>
2025-06-02 14:42:07 +08:00
</Guide>
<image
src="../static/first-try-tip.png"
class="try-tip"
mode="widthFix"
v-if="step === 0"
/>
<image
src="../static/first-try-tip2.png"
class="try-tip"
mode="widthFix"
v-if="step === 3"
/>
<image
src="../static/first-try-tip3.png"
class="try-tip"
mode="widthFix"
v-if="step === 5"
/>
<view style="height: 570px" v-if="step === 1">
<Swiper
:data="[
'../static/first-try-tip.png',
'../static/first-try-tip.png',
'../static/first-try-tip.png',
]"
/>
2025-05-10 16:57:36 +08:00
</view>
2025-06-02 14:42:07 +08:00
<ShootProgress
v-if="step === 4"
tips="请开始连续射箭"
:total="100"
:start="start"
/>
2025-06-17 16:58:24 +08:00
<view class="infos" v-if="step === 4">
<Avatar :src="user.avatar" :size="35" />
<BowPower :power="power" />
</view>
2025-06-02 14:42:07 +08:00
<BowTarget
2025-06-17 16:58:24 +08:00
:avatar="step === 2 ? user.avatar : ''"
:power="step === 2 ? power : 0"
2025-06-02 14:42:07 +08:00
:debug="step === 2"
v-if="step === 2 || step === 4"
2025-06-17 16:58:24 +08:00
:currentRound="step === 4 ? scores.length : 0"
:totalRound="step === 4 ? total : 0"
2025-06-02 14:42:07 +08:00
:tips="
step === 2 && scores.length > 0
? `本次射程${scores[scores.length - 1].dst / 100}米,${
scores[scores.length - 1].dst / 100 >= 5 ? '已' : '未'
}达到距离要求`
: ''
"
:scores="scores"
/>
<ScorePanel
v-if="step === 4"
:total="total"
:rowCount="6"
:scores="scores.map((s) => s.ring)"
2025-05-10 16:57:36 +08:00
/>
2025-06-02 14:42:07 +08:00
<ScoreResult
:total="total"
:rowCount="6"
:show="showScore"
v-if="step === 4"
:onClose="onClose"
:result="practiseResult"
/>
</view>
2025-06-18 21:30:54 +08:00
<view :style="{ marginBottom: '20px' }">
2025-06-15 15:53:57 +08:00
<SButton v-if="step !== 4" :onClick="nextStep" :disabled="btnDisabled">{{
stepButtonTexts[step]
}}</SButton>
</view>
2025-05-23 21:20:38 +08:00
</Container>
2025-05-01 16:36:24 +08:00
</template>
<style scoped>
2025-06-02 14:42:07 +08:00
.container {
width: 100%;
}
2025-05-01 22:58:02 +08:00
.try-tip {
width: calc(100% - 20px);
margin: 10px 10px;
2025-05-01 16:36:24 +08:00
}
2025-06-17 16:58:24 +08:00
.infos {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 15px;
padding-top: 15px;
}
2025-05-01 16:36:24 +08:00
</style>