Browse Source

引导修改

lalalashen 2 months ago
parent
commit
db11c412ec
3 changed files with 399 additions and 74 deletions
  1. 259 62
      components/guide/GuideManager.vue
  2. 115 10
      pages/isLand/homeLand.vue
  3. 25 2
      pages/isLand/talkGuide.vue

+ 259 - 62
components/guide/GuideManager.vue

@@ -32,51 +32,135 @@ export default {
       currentStepIndex: 0,
       // 已完成阶段
       completedStages: [],
+      // 已完成的主线
+      completedMainLines: [],
       // 引导配置
       guideConfig: {
-        // 主岛引导
-        mainLand: {
-          id: 'mainLand',
-          steps: [
-            {
-              target: '.house-image',
-              tips: '这是你的房屋,点击可以进入查看',
-              position: 'bottom'
-            },
-            {
-              target: '.farm-image',
-              tips: '这是农场,可以种植作物',
-              position: 'bottom'
-            },
-            {
-              target: '.shop-image',
-              tips: '这是商店,可以购买物品',
-              position: 'bottom'
-            }
-          ]
-        },
-        // 家园引导
-        homeLand: {
-          id: 'homeLand',
-          steps: [
-            {
-              target: '.house-image',
-              tips: '这是你的家,点击可以进入',
-              position: 'bottom'
-            },
-            {
-              target: '.table-image',
-              tips: '这是工作台,可以制作物品',
-              position: 'bottom'
-            },
-            {
-              target: '.taskBoard-image',
-              tips: '这是任务板,可以查看任务',
-              position: 'bottom'
-            }
-          ]
-        }
-      }
+        mainLines: [
+          {
+            name: "new immigrant",
+            stage: "homeLand",
+            steps: [
+              {
+                arrow: null,
+                talkData: [
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '这位大人,这里太大了吧....',
+                    position: 'left',
+                    isMirror: true
+                  },
+                  {
+                    characterImage: '/static/island/building/1.png',
+                    characterName: '我',
+                    text: '好的,我马上上会教付清',
+                    position: 'right',
+                    isMirror: false
+                  },
+                  {
+                    characterImage: '/static/island/building/1.png',
+                    characterName: '我',
+                    text: '很奇怪不是吗?',
+                    position: 'right',
+                    isMirror: false
+                  },
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '怎么回事',
+                    position: 'left',
+                    isMirror: true
+                  }
+                ]
+              },
+              {
+                arrow: {x: 350, y: 460, r: 0},
+                talkData: [
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '工作台在这里呢',
+                    position: 'left',
+                    isMirror: true
+                  },
+                  {
+                    characterImage: '/static/island/building/1.png',
+                    characterName: '我',
+                    text: '好的,我去看看',
+                    position: 'right',
+                    isMirror: false
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            name: "new craftsman",
+            stage: "mainLand_table",
+            steps: [
+              {
+                arrow: null,
+                talkData: [
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '工作台在这里呢!',
+                    position: 'left',
+                    isMirror: true
+                  },
+                  {
+                    characterImage: '/static/island/building/1.png',
+                    characterName: '我',
+                    text: '好像可以有好多工具,但是好像没有材料呢~',
+                    position: 'right',
+                    isMirror: false
+                  },
+
+                ]
+              },
+              {
+                arrow: {x: 750, y: 660, r: 270},
+                talkData: [
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '是的呀,也可以去看看别人发布的任务,获取材料呢!',
+                    position: 'left',
+                    isMirror: true
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            name: "new flower farmer",
+            stage: "mainLand",
+            steps: [
+              {
+                arrow: {x: 50, y: 50, r: 90},
+                talkData: [
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '这里可以种花呦....',
+                    position: 'left',
+                    isMirror: true
+                  }
+                ]
+              }
+            ]
+          }
+        ]
+      },
+      // 当前主线ID
+      currentMainLineId: 0,
+      // 当前主线
+      currentMainLine: null,
+      // 对话数据
+      currentTalkData: [],
+      // 当前对话索引
+      currentTalkIndex: 0
     }
   },
   computed: {
@@ -180,31 +264,122 @@ export default {
   },
   methods: {
     // 开始引导
-    startGuide(stageId) {
-      // 检查是否已完成
-      if (this.completedStages.includes(stageId)) {
-        return
+    startGuide(stage) {
+      // 获取当前主线
+      const mainLine = this.guideConfig.mainLines[this.currentMainLineId];
+      
+      // 检查主线是否存在且场景是否匹配
+      if (!mainLine || mainLine.stage !== stage) {
+        return false;
       }
+
+      // 检查主线是否已完成
+      if (this.completedMainLines.includes(this.currentMainLineId)) {
+        return false;
+      }
+
+      // 设置当前主线
+      this.currentMainLine = mainLine;
+      this.currentStepIndex = 0;
+      this.currentTalkIndex = 0;
       
-      // 设置当前阶段
-      this.currentStage = this.guideConfig[stageId]
-      this.currentStepIndex = 0
+      // 初始化对话数据
+      this.initTalkData();
       
-      // 等待DOM更新后更新位置
-      this.$nextTick(() => {
-        this.updatePositions()
-      })
+      return true;
+    },
+    // 设置当前主线ID
+    setMainLineId(id) {
+      if (id >= 0 && id < this.guideConfig.mainLines.length) {
+        this.currentMainLineId = id;
+        // 保存到本地存储
+        this.saveCurrentMainLineId();
+      }
+    },
+    // 保存当前主线ID
+    saveCurrentMainLineId() {
+      uni.setStorageSync('currentGuideMainLineId', this.currentMainLineId);
+    },
+    // 加载当前主线ID
+    loadCurrentMainLineId() {
+      const id = uni.getStorageSync('currentGuideMainLineId');
+      if (id !== '') {
+        this.currentMainLineId = id;
+      }
+    },
+    // 初始化对话数据
+    initTalkData() {
+      if (this.currentMainLine && this.currentMainLine.steps[this.currentStepIndex]) {
+        this.currentTalkData = this.currentMainLine.steps[this.currentStepIndex].talkData;
+      }
     },
     // 下一步
     nextStep() {
-      if (this.isLastStep) {
-        this.completeStage()
+      console.log("-------- next step", {
+        currentMainLine: this.currentMainLine,
+        currentStepIndex: this.currentStepIndex,
+        currentTalkIndex: this.currentTalkIndex,
+        currentTalkData: this.currentTalkData
+      });
+      
+      if (!this.currentMainLine) return;
+
+      // 如果当前步骤是最后一步
+      if (this.currentStepIndex === this.currentMainLine.steps.length - 1) {
+        this.completeMainLine();
       } else {
-        this.currentStepIndex++
-        this.$nextTick(() => {
-          this.updatePositions()
-        })
+        // 进入下一步
+        this.currentStepIndex++;
+        this.currentTalkIndex = 0;
+        this.initTalkData();
       }
+
+      console.log("-------- next step2", {
+        currentMainLine: this.currentMainLine,
+        currentStepIndex: this.currentStepIndex,
+        currentTalkIndex: this.currentTalkIndex,
+        currentTalkData: this.currentTalkData
+      });
+      
+    },
+    // 完成主线
+    completeMainLine() {
+      if (this.currentMainLine) {
+        // 添加到已完成列表
+        this.completedMainLines.push(this.currentMainLine.name);
+        
+        // 保存到本地存储
+        this.saveCompletedMainLines();
+        
+        // 重置状态
+        this.currentMainLine = null;
+        this.currentStepIndex = 0;
+        this.currentTalkIndex = 0;
+        this.currentTalkData = [];
+      }
+    },
+    // 保存已完成主线
+    saveCompletedMainLines() {
+      uni.setStorageSync('completedGuideMainLines', this.completedMainLines);
+    },
+    // 加载已完成主线
+    loadCompletedMainLines() {
+      const mainLines = uni.getStorageSync('completedGuideMainLines');
+      if (mainLines) {
+        this.completedMainLines = mainLines;
+      }
+    },
+    // 获取当前箭头位置
+    getCurrentArrowPosition() {
+      if (!this.currentMainLine || !this.currentMainLine.steps[this.currentStepIndex]) {
+        return null;
+      }
+      return this.currentMainLine.steps[this.currentStepIndex].arrow;
+    },
+    // 获取当前对话数据
+    getCurrentTalkData() {
+      if (!this.currentTalkData.length) return null;
+      return this.currentTalkData;
     },
     // 跳过当前阶段
     skipStage() {
@@ -215,8 +390,29 @@ export default {
       if (this.currentStage) {
         // 添加到已完成列表
         this.completedStages.push(this.currentStage.id)
+        
+        // 如果当前阶段有主线ID,检查该主线的所有阶段是否都已完成
+        if (this.currentStage.mainLineId) {
+          const mainLineId = this.currentStage.mainLineId
+          const mainLineStages = Object.values(this.guideConfig).filter(
+            stage => stage.mainLineId === mainLineId
+          )
+          
+          // 检查该主线的所有阶段是否都已完成
+          const isMainLineCompleted = mainLineStages.every(
+            stage => this.completedStages.includes(stage.id)
+          )
+          
+          // 如果主线完成,添加到已完成主线列表
+          if (isMainLineCompleted && !this.completedMainLines.includes(mainLineId)) {
+            this.completedMainLines.push(mainLineId)
+          }
+        }
+        
         // 保存到本地存储
         this.saveCompletedStages()
+        this.saveCompletedMainLines()
+        
         // 重置状态
         this.currentStage = null
         this.currentStepIndex = 0
@@ -251,8 +447,9 @@ export default {
     }
   },
   mounted() {
-    // 加载已完成阶段
-    this.loadCompletedStages()
+    // 加载已完成主线和当前主线ID
+    this.loadCompletedMainLines();
+    this.loadCurrentMainLineId();
   }
 }
 </script>

+ 115 - 10
pages/isLand/homeLand.vue

@@ -22,11 +22,16 @@
         <image class="taskBoard-image" src="/static/island/building/taskBoard.png" mode="widthFix" style="width:670rpx; position: static;" @click="showTask" :animation="taskAnimationData">	</image>
       </view>
 
+      <!-- 引导箭头 -->
+      <view class="guide-arrow" v-if="showGuideArrow" :style="{ left: guideArrowPosition.x + 'rpx', bottom: guideArrowPosition.y + 'rpx', transform: `rotate(${guideArrowPosition.r}deg)` }">
+        <image src="/static/island/arrow.png" mode="aspectFit"></image>
+      </view>
+
       <!-- 主岛箭头 -->
       <view class="main-arrow" @click="goToMainLand" :animation="mainArrowAnimation" :style="{ opacity: mainArrowVisible ? 1 : 0 }">
         <!-- <image src="/static/island/main_arrow.png" mode="widthFix" style="width: 100rpx;"></image> -->
 		<view class="arrow" ></view>
-        <text class="main-text">主岛</text>
+        <text class="main-text">主岛{{ showGuideArrow }}</text>
 
       </view>
     </view>
@@ -59,9 +64,11 @@
     
     <!-- 引导对话组件 -->
     <talk-guide 
-      :guide-data="guideData"
+      v-if="showTalkGuide"
+      :guide-data="currentTalkData"
       :player-name="playerName"
-      @guide-complete="onGuideComplete"
+      :visible="showTalkGuide"
+      @talk-complete="onTalkComplete"
     ></talk-guide>
 
     <!-- 制造台对话框组件 -->
@@ -156,6 +163,11 @@ export default {
 				num_gmg: 0,
 			},
 			moneyTimer: null, // 添加定时器变量
+			showTalkGuide: false,
+			currentTalkData: [],
+			// 引导箭头相关
+			showGuideArrow: false,
+			guideArrowPosition: { x: 0, y: 0, r: 0 }
 		}
 	},
 	onLoad() {
@@ -446,17 +458,27 @@ export default {
 				url: '/pages/isLand/mainLand'
 			});
 		},
-		onGuideComplete() {
-			console.log('引导完成')
-			// 这里可以添加引导完成后的逻辑
-			uni.setStorageSync('isGuideCompleted', true)
-		},
 		// 检查并显示引导
 		checkAndShowGuide() {
 			// 延迟执行以确保DOM已经渲染
 			setTimeout(() => {
-				this.$refs.guideManager && this.$refs.guideManager.startGuide('homeLand');
-			}, 500);
+				if (this.$refs.guideManager) {
+					const hasGuide = this.$refs.guideManager.startGuide('homeLand');
+					if (hasGuide) {
+						this.currentTalkData = this.$refs.guideManager.getCurrentTalkData();
+						console.log('checkAndShowGuide currentTalkData :', this.currentTalkData);
+						if (this.currentTalkData) {
+							this.showTalkGuide = true;
+							// 检查是否需要显示引导箭头
+							this.checkAndShowGuideArrow();
+						}else{
+							console.log('currentTalkData err:', this.currentTalkData);
+						}
+
+						
+					}
+				}
+			}, 200);
 		},
 		// 获取用户铃钱
 		getUserMoney() {
@@ -478,6 +500,57 @@ export default {
 				}
 			})
 		},
+		// 对话完成回调
+		onTalkComplete() {
+			// 调用引导管理器的下一步
+			console.log('----------- onTalkComplete');
+			this.$refs.guideManager && this.$refs.guideManager.nextStep();
+			
+			// 获取新的对话数据
+			const newTalkData = this.$refs.guideManager.getCurrentTalkData();
+			console.log('----------- onTalkComplete newTalkData:', newTalkData);
+			if (newTalkData) {
+				// 先隐藏对话组件
+				this.showTalkGuide = false;
+				// 更新对话数据
+				this.currentTalkData = newTalkData;
+				// 使用 nextTick 确保数据更新后再显示对话组件
+				this.$nextTick(() => {
+					this.showTalkGuide = true;
+					// 检查是否需要显示引导箭头
+					this.checkAndShowGuideArrow();
+				});
+			} else {
+				// 如果没有新的对话数据,隐藏对话组件
+				this.showTalkGuide = false;
+				// 隐藏引导箭头
+				// this.showGuideArrow = false;
+			}
+		},
+		// 检查并显示引导箭头
+		checkAndShowGuideArrow() {
+			if (this.$refs.guideManager) {
+				const arrowPosition = this.$refs.guideManager.getCurrentArrowPosition();
+				console.log('----------- checkAndShowGuideArrow arrowPosition:', arrowPosition);
+				
+				if (arrowPosition) {
+					// 显示引导箭头
+					this.showGuideArrow = true;
+					// 设置箭头位置
+					this.guideArrowPosition = {
+						x: arrowPosition.x,
+						y: arrowPosition.y,
+						r: arrowPosition.r || 0
+					};
+					
+					console.log('----------- guideArrowPosition:', this.guideArrowPosition);
+					console.log('----------- showGuideArrow:', this.showGuideArrow);
+				} else {
+					// 隐藏引导箭头
+					this.showGuideArrow = false;
+				}
+			}
+		}
 	},
 	beforeDestroy() {
 		this.mainArrowAnimating = false;
@@ -538,6 +611,38 @@ export default {
   }
 }
 
+.guide-arrow {
+  position: absolute;
+  z-index: 10;
+  width: 100rpx;
+  height: 100rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  pointer-events: none; /* 防止箭头阻挡点击事件 */
+  
+  image {
+    width: 100rpx;
+    height: 100rpx;
+    animation: pulse 1.5s infinite; /* 添加脉冲动画 */
+  }
+}
+
+@keyframes pulse {
+  0% {
+    transform: scale(1);
+    opacity: 1;
+  }
+  50% {
+    transform: scale(1.2);
+    opacity: 0.8;
+  }
+  100% {
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+
 .main-arrow {
 //   background: rgba(255, 255, 255, 0.9);
   position: absolute;

+ 25 - 2
pages/isLand/talkGuide.vue

@@ -30,12 +30,16 @@ export default {
     playerName: {
       type: String,
       default: '主角'
+    },
+    visible: {
+      type: Boolean,
+      default: false
     }
   },
   data() {
     return {
       currentIndex: 0,
-      isShow: true
+      isShow: false
     }
   },
   computed: {
@@ -46,11 +50,30 @@ export default {
       return this.currentIndex === this.guideData.length - 1
     }
   },
+  watch: {
+    visible: {
+      immediate: true,
+      handler(newVal) {
+        this.isShow = newVal;
+        if (newVal) {
+          this.currentIndex = 0;
+        }
+      }
+    },
+    guideData: {
+      handler(newVal) {
+        if (newVal && newVal.length > 0) {
+          this.currentIndex = 0;
+        }
+      },
+      deep: true
+    }
+  },
   methods: {
     handleClick() {
       if (this.isLastStep) {
         this.isShow = false
-        this.$emit('guide-complete')
+        this.$emit('talk-complete')
       } else {
         this.nextStep()
       }