Explorar o código

1、blockly多条路线按顺序执行,全部通关后才会触发通关逻辑和特效

liyanbo hai 4 meses
pai
achega
6f35e7b245
Modificáronse 1 ficheiros con 90 adicións e 27 borrados
  1. 90 27
      src/components/blockly/MapGame.vue

+ 90 - 27
src/components/blockly/MapGame.vue

@@ -9,7 +9,6 @@
           :key="index"
           class="game-badge"
           :class="{ 'active': currentRouteIndex === index }"
-          @click="switchRoute(index)"
         >
           {{ gameSort }}{{ index + 1 }}
         </button>
@@ -43,7 +42,7 @@
               class="walkable-point"
               :style="getPointStyle(point)"
           >
-          </div>
+</div>
 
           <!-- 玩家角色 -->
           <div
@@ -156,7 +155,6 @@ import errorMp3 from '@/assets/music/blockly/error.MP3'
 import { registerCustomBlocks, registerJavaScriptGenerators, registerPythonGenerators, initBlockly } from '@/api/blockly/blockly.js';
 import {playMp3} from "@/api/blockly/music.js";
 
-
 import cupbg from '@/assets/blockly/cupbg.png' // 通关后奖杯底图
 import nocupbg from '@/assets/blockly/nocupbg.png' // 通关失败后奖杯底图
 import goldcup from '@/assets/blockly/goldcup.png' // 金杯
@@ -178,7 +176,6 @@ const passConfig = ref({
   passBackground: "",// 通关后奖杯底图
 });
 
-
 // 定义emits
 const emits = defineEmits(['saveProgress'])
 // 定义组件属性
@@ -228,11 +225,6 @@ const props = defineProps({
     type: String,
     default: ''
   },
-  // 游戏标题
-  gameTitle: {
-    type: String,
-    default: ''
-  },
   // 路线列表
   routeList: {
     type: [String, Array],
@@ -255,12 +247,6 @@ const props = defineProps({
   }
 });
 
-// 关闭遮罩层
-const closeOverlay = () => {
-  gameState.player.hasReachedEnd = false;
-  showOverlay.value = false;
-};
-
 // 配置常量
 const CONFIG = {
   // 动画时长配置(毫秒)
@@ -315,6 +301,7 @@ const CONFIG = {
     NO_ENTRY: '当前位置无通路,无法移动',
     UNFINISHED: '任务未完成!',
     EFFORT: '再接再厉!',
+    PASS_ROUTE: '恭喜你通过了当前路线,进入下一条路线!',
     FINISH: '恭喜你到达终点!',
     PICKUP_ITEM: '拾取物品成功!',
     NULL_PICKUP_ITEM: '当前位置没有可拾取的物品',
@@ -326,19 +313,28 @@ const CONFIG = {
 };
 
 // 路由和游戏状态
-const gameTitle = computed(() => props.gameTitle);
 const currentGameData = ref(null);
 const playerInitialDirection = ref(0); // 人物初始朝向
 const gameSort = ref('Game'); // 默认排序
 const currentRouteIndex = ref(0); // 当前线路索引
 
+// 路线通过状态:存储各路线的通过状态
+const routePassedStatus = ref([]);
+
 // 解析routeList
 const parsedRouteList = computed(() => {
   if (!props.routeList) return [];
   try {
     const routeData = typeof props.routeList === 'string' ? JSON.parse(props.routeList) : props.routeList;
-    return Array.isArray(routeData) ? routeData : [];
-  } catch (error) {
+    const routes = Array.isArray(routeData) ? routeData : [];
+    
+    // 初始化路线通过状态
+    if (routePassedStatus.value.length === 0 && routes.length > 0) {
+      routePassedStatus.value = routes.map((_, index) => index === 0); // 第一条路线默认可用
+    }
+    
+    return routes;
+} catch (error) {
     console.error('解析routeList失败:', error);
     return [];
   }
@@ -623,7 +619,8 @@ const fetchGameData = async () => {
 
 // 切换线路
 const switchRoute = (index) => {
-  if (index < 0 || index >= parsedRouteList.value.length) return;
+  // 检查路线是否可用
+  if (index < 0 || index >= parsedRouteList.value.length || !isRouteAvailable(index)) return;
   
   currentRouteIndex.value = index;
   const route = parsedRouteList.value[index];
@@ -647,8 +644,16 @@ const switchRoute = (index) => {
     gameState.mapData.endPoint = { x: endPoint.x, y: endPoint.y };
   }
   
-  // 重新初始化可行走点集合
-  initWalkablePointsSet();
+  // 重新初始化可行走点集合【目前没有单独配置路线的可行走集合,一张地图通用】
+  // initWalkablePointsSet();
+};
+
+// 检查路线是否可用
+const isRouteAvailable = (index) => {
+  // 第一条路线始终可用
+  if (index === 0) return true;
+  // 其他路线需要前一条路线通过
+  return routePassedStatus.value[index - 1];
 };
 
 // 根据获取到的数据更新游戏状态
@@ -975,6 +980,12 @@ function showGameMessage(message, type = 'info', duration = CONFIG.DELAY.MESSAGE
   }, duration);
 }
 
+// 关闭遮罩层
+const closeOverlay = () => {
+  gameState.player.hasReachedEnd = false;
+  showOverlay.value = false;
+};
+
 //================积木组件方法=====================
 
 // 向前移动
@@ -1345,7 +1356,19 @@ window.isFinish = async function() {
   if (isColliding.value) {
     return;
   }
+
+  // 校验是否到达终点
   if (gameState.player.position.x === endPoint.value.x && gameState.player.position.y === endPoint.value.y) {
+
+    // 如果通过了当前路线,标记为已通过并自动切换到下一个路线(true:切换下一关,false:全部通关)
+    if (markCurrentRouteAsPassed()){
+      //通关路线提示
+      showGameMessage(CONFIG.TIPS.PASS_ROUTE, 'success');
+      return;
+    }
+
+    // 全部通关
+
     // 统计所有类型为TASK的任务点总数||必须完成拾取物品的人物总数
     const totalTasks = gameState.mapData.walkablePoints.filter(
         p => p.type === BLOCKLY_MAP_TYPE_DICT.TASK ||
@@ -1356,6 +1379,7 @@ window.isFinish = async function() {
         p => p.type === BLOCKLY_MAP_TYPE_DICT.TASK && p.status === true
                 || p.type === BLOCKLY_MAP_TYPE_DICT.ITEM && p.must === true && p.status === true
     ).length;
+
     //blockly总星星数量
     //无任务情况下直接完成
     if (totalTasks === 0 || completedTasks === totalTasks) {
@@ -1850,15 +1874,14 @@ async function animateItemUse(item, itemIndex, finishAnimation) {
 }
 
 // 展示通过动画
-async function showPass(passStar){
-
+async function showPass(passStar) {
   // 记录通过的星星数量
   passConfig.value.passStar = passStar;
 
   passConfig.value.title = 'YOU WIN!';
   passConfig.value.passBackground = cupbg;
 
-  switch (passStar){
+  switch (passStar) {
     case 0:
       passConfig.value.title = 'YOU LOSE!';
       passConfig.value.passTrophy = nocup;
@@ -1882,6 +1905,22 @@ async function showPass(passStar){
   showOverlay.value = true;
 }
 
+// 标记当前路线为已通过
+const markCurrentRouteAsPassed = () => {
+  routePassedStatus.value[currentRouteIndex.value] = true;
+
+  // 自动切换到下一个可用路线
+  if (currentRouteIndex.value < parsedRouteList.value.length - 1) {
+    // 解锁下一个路线
+    routePassedStatus.value[currentRouteIndex.value + 1] = true;
+    // 自动切换到下一个路线
+    switchRoute(currentRouteIndex.value + 1);
+
+    return true;
+  }
+  return false;
+};
+
 //================卸载区=====================
 // 组件卸载时清理
 onUnmounted(() => {
@@ -2696,10 +2735,34 @@ button {
   transition: all 0.3s ease;
 }
 
-button:hover {
-  background: #2980b9;
+.game-badge:hover {
+  background-color: #3498db;
   transform: translateY(-2px);
-  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
+  box-shadow: 0 rpx(5) rpx(10) rgba(0, 0, 0, 0.1);
+}
+
+.game-badge.active {
+  background-color: #e74c3c;
+  color: #fff;
+  font-weight: bold;
+}
+
+.game-badge.passed {
+  background-color: #27ae60;
+  color: #fff;
+}
+
+.game-badge.disabled {
+  background-color: #bdc3c7;
+  color: #7f8c8d;
+  cursor: not-allowed;
+  pointer-events: none;
+}
+
+.game-badge.disabled:hover {
+  background-color: #bdc3c7;
+  transform: none;
+  box-shadow: none;
 }
 
 #runCode {