4 Commits 100a0ad732 ... 717f42eb90

Author SHA1 Message Date
  lalalashen 717f42eb90 Merge branch 'master' of http://150.158.33.144:3000/lalalashen/MoeNovaClient 2 months ago
  lalalashen 6291a28b29 上传老家引导的部分 2 months ago
  lalalashen a7483dc6b1 Merge branch 'master' of http://150.158.33.144:3000/lalalashen/MoeNovaClient 2 months ago
  lalalashen db11c412ec 引导修改 2 months ago
3 changed files with 426 additions and 77 deletions
  1. 279 62
      components/guide/GuideManager.vue
  2. 121 12
      pages/isLand/homeLand.vue
  3. 26 3
      pages/isLand/talkGuide.vue

+ 279 - 62
components/guide/GuideManager.vue

@@ -32,51 +32,149 @@ 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
+                  }
+                ]
+              },
+              {
+                arrow: {x: 350, y: 460, r: 0},
+                talkData: [
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '这里是工具台 ,它可以制作各实用和非常棒的工具和装饰物,千万不要错过哟。',
+                    position: 'left',
+                    isMirror: true
+                  },
+                ]
+              }
+            ]
+          },
+          {
+            name: "new craftsman",
+            stage: "homeLand_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
+                  },
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '材料确实不太容易获取呢,可以去看看公告栏。',
+                    position: 'left',
+                    isMirror: true
+                  }
+
+                ]
+              },
+              {
+                arrow: {x: 885, y: 535, r: 270},
+                talkData: [
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '看到小箭头指示的地方了么...那是任务看板,可以获取一些稀有道具和铃钱哦。',
+                    position: 'left',
+                    isMirror: true
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            name: "oh, taskBoard",
+            stage: "homeLand_TaskBoard",
+            steps: [
+              {
+                arrow: null,
+                talkData: [
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '这里就是任务面板呦....',
+                    position: 'left',
+                    isMirror: true
+                  },
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '顺便说一下,你的移民计划正式开启目前您需要缴纳移民费用为388888元。也在任务面板发布了呦~',
+                    position: 'left',
+                    isMirror: true
+                  },
+                  {
+                    characterImage: '/static/island/building/1.png',
+                    characterName: '我',
+                    text: '什么!移民费用388888铃钱,这也太贵了吧...',
+                    position: 'right',
+                    isMirror: false
+                  },
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '移民本就是一件不容易的事呢...',
+                    position: 'left',
+                    isMirror: true
+                  },
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '对了,听说近期市政厅那边的花田正在招募园丁,报酬丰厚,',
+                    position: 'left',
+                    isMirror: true
+                  },
+                  {
+                    characterImage: '/static/island/npc.png',
+                    characterName: '罗宾',
+                    text: '相信以你的能力完全是没问题的,右侧过桥后就到了。',
+                    position: 'left',
+                    isMirror: true
+                  }
+                ]
+              }
+            ]
+          }
+        ]
+      },
+      // 当前主线ID
+      currentMainLineId: 0,
+      // 当前主线
+      currentMainLine: null,
+      // 对话数据
+      currentTalkData: [],
+      // 当前对话索引
+      currentTalkIndex: 0
     }
   },
   computed: {
@@ -180,31 +278,126 @@ 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.currentMainLineId);
+        
+        // 保存到本地存储
+        // this.saveCompletedMainLines();
+        
+        // 重置状态
+        this.currentMainLine = null;
+        this.currentStepIndex = 0;
+        this.currentTalkIndex = 0;
+        this.currentTalkData = [];
+        
+        // 增加主线ID
+        this.currentMainLineId++;
+        this.saveCurrentMainLineId();
+      }
+    },
+    // 保存已完成主线
+    // 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 +408,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 +465,11 @@ export default {
     }
   },
   mounted() {
-    // 加载已完成阶段
-    this.loadCompletedStages()
+    // 加载已完成主线和当前主线ID
+    // this.loadCompletedMainLines();
+    this.loadCurrentMainLineId();
+    //测试重置主线
+    this.currentMainLineId=0;
   }
 }
 </script>

+ 121 - 12
pages/isLand/homeLand.vue

@@ -22,6 +22,11 @@
         <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> -->
@@ -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() {
@@ -176,7 +188,7 @@ export default {
 	},
 	onShow() {
 		// 检查是否需要显示引导
-		this.checkAndShowGuide();
+		this.checkAndShowGuide('homeLand');
 	},
 	onReady() {
 		// 在组件渲染完成后获取图片尺寸
@@ -316,6 +328,8 @@ export default {
 			
 			// 显示制造台界面
 			this.craftingVisible = true;
+
+			this.checkAndShowGuide('homeLand_table');
 		},
 
 		onTaskClick(event) {
@@ -406,7 +420,9 @@ export default {
 		},
 		showTask() {
 			console.log('Opening task board...')
-			this.taskVisible = true
+			this.taskVisible = true;
+			this.checkAndShowGuide('homeLand_TaskBoard');
+
 		},
 		onTaskClose() {
 			console.log('Closing task board...')
@@ -446,17 +462,27 @@ export default {
 				url: '/pages/isLand/mainLand'
 			});
 		},
-		onGuideComplete() {
-			console.log('引导完成')
-			// 这里可以添加引导完成后的逻辑
-			uni.setStorageSync('isGuideCompleted', true)
-		},
 		// 检查并显示引导
-		checkAndShowGuide() {
+		checkAndShowGuide(stageId) {
+			console.log('checkAndShowGuide stageId :', stageId);
 			// 延迟执行以确保DOM已经渲染
 			setTimeout(() => {
-				this.$refs.guideManager && this.$refs.guideManager.startGuide('homeLand');
-			}, 500);
+				if (this.$refs.guideManager) {
+					const hasGuide = this.$refs.guideManager.startGuide(stageId);
+					console.log('checkAndShowGuide hasGuide :', hasGuide);
+					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 +504,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 +615,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;

+ 26 - 3
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()
       }
@@ -72,7 +95,7 @@ export default {
   width: 100%;
   height: 100%;
   background-color: rgba(0, 0, 0, 0.5);
-  z-index: 999;
+  z-index: 99999;
 
   .guide-content {
     position: absolute;