Преглед на файлове

blockly编程游戏
1、代码优化、统一配置

liyanbo преди 5 месеца
родител
ревизия
05c3f46993
променени са 1 файла, в които са добавени 348 реда и са изтрити 238 реда
  1. 348 238
      src/views/block/MapGame.vue

+ 348 - 238
src/views/block/MapGame.vue

@@ -22,7 +22,7 @@
             <p v-html="currentGameData?.info"></p>
           </div>
         </div>
-        
+
         <div class="map-container">
           <!-- 地图背景 -->
           <div class="map-background">
@@ -121,104 +121,58 @@ import playerImage from '@/assets/images/blockly/user.png';
 // 游戏接口数据
 import { getMapGameById } from '@/api/blockly/game.js';
 
+// 配置常量
+const CONFIG = {
+  // 动画时长配置(毫秒)
+  ANIMATION: {
+    MOVE_DURATION: 500,      // 移动动画持续时间
+    ROTATE_DURATION: 500,    // 旋转动画持续时间(左转/右转)
+    TURN_AROUND_DURATION: 750, // 向后转动画持续时间
+  },
+  // 延迟配置(毫秒)
+  DELAY: {
+    ACTION_DELAY: 200,       // 每次动作后的延迟时间
+    COLLISION_DELAY: 300,    // 碰撞后的延迟时间
+    RESET_DELAY: 300,        // 重置后的延迟时间
+    MESSAGE_DISPLAY: 3000,   // 消息显示时间
+    COLLISION_RESET: 1000,   // 碰撞状态重置时间
+    LOOP_PREVENTION: 10,     // 循环防止UI阻塞的延迟
+  },
+  // 游戏配置
+  GAME: {
+    MAX_LOOP_COUNT: 100,     // 最大循环次数
+    DIRECTIONS: {
+      UP: 0,
+      RIGHT: 1,
+      DOWN: 2,
+      LEFT: 3
+    }
+  },
+  // 样式配置
+  STYLES: {
+    DEFAULT_TILE_SIZE: 110,  // 默认瓦片大小
+    PLAYER_SIZE_RATIO: 0.8   // 玩家大小占瓦片的比例
+  }
+};
 
+// 路由和游戏状态
 const router = useRouter();
 const route = useRoute();
 const gameTitle = ref('地图游戏编程'); // 默认标题
-const gameSort = ref('Game1'); // 默认排序
 const currentGameData = ref(null);
-//人物初始朝向
-const playerInitialDirection = ref(0);
-
-onMounted(async () => {
-  //数据
-  await fetchGameData();
-
-  // 初始化可行走点集合
-  initWalkablePointsSet();
-  // 注册自定义积木
-  registerCustomBlocks();
-  // 注册JavaScript生成器
-  registerJavaScriptGenerators();
-  // 初始化Blockly工作区
-  initBlockly();
-  // 重置玩家位置
-  resetPlayer();
-
-  // 获取路由参数中的gameName
-  const nameFromRoute = route.query.gameName;
-  if (nameFromRoute) {
-    gameTitle.value = nameFromRoute;
-  }
-})
-
-// 获取游戏数据
-const fetchGameData = async () => {
-  try {
-    const gameId = route.query.gameId;
-    const nameFromRoute = route.query.gameName;
-    const sortFromRoute = route.query.gameSort;
-
-    if (nameFromRoute) {
-      gameTitle.value = nameFromRoute;
-    }
-    
-    // 优先使用路由参数中的排序信息
-    if (sortFromRoute) {
-      gameSort.value = sortFromRoute;
-    }
-
-    let mapGameData = await getMapGameById(gameId);
-    if (mapGameData.code === 0) {
-      currentGameData.value = mapGameData?.data;
-      
-      // 使用接口数据
-      if (currentGameData.value && currentGameData.value.sort) {
-        let sortNum = currentGameData.value.sort;
-        gameSort.value = sortNum > 9 ? `Game${sortNum}` : `Game${sortNum}`;
-      }
-       updateGameStateFromData(currentGameData.value);
-    }
-  } catch (error) {
-    console.error('获取游戏数据失败:', error);
-  }
-};
-
-// 根据获取到的数据更新游戏状态
-const updateGameStateFromData = (gameData) => {
-  try {
-    // 更新地图配置
-    gameState.mapConfig.background = gameData.mapBackground ? gameData.mapBackground.trim() : mapBackgroundImage;
-    gameState.mapConfig.tileSize = gameData.mapTileSize;
-
-    // 更新玩家位置和方向
-    if (gameData.userDirection) {
-      playerInitialDirection.value = gameData.userDirection;
-    }
+const playerInitialDirection = ref(0); // 人物初始朝向
+const gameSort = ref('Game1'); // 默认排序
 
-    // 更新地图数据
-    // 地图起点
-    if (gameData.mapStartPoint) {
-      const startPoint = JSON.parse(gameData.mapStartPoint);
-      gameState.mapData.startPoint = { x: startPoint.x, y: startPoint.y };
-      gameState.player.position = { x: startPoint.x, y: startPoint.y };
-    }
-    // 地图终点
-    if (gameData.mapEndPoint) {
-      const endPoint = JSON.parse(gameData.mapEndPoint);
-      gameState.mapData.endPoint = { x: endPoint.x, y: endPoint.y };
-    }
-    if (gameData.mapWalkablePoints) {
-      gameState.mapData.walkablePoints = JSON.parse(gameData.mapWalkablePoints);
-    }
-    // 重新初始化可行走点集合
-    initWalkablePointsSet();
-  } catch (error) {
-    console.error('更新游戏状态失败:', error);
-  }
-};
+// 运行控制标志
+let shouldStopExecution = false;
+let currentExecutionPromise = null;
+let executionAbortController = null;
 
+// Blockly相关状态
+let workspace = null;
 
+// 使用 Map 存储可行走点及其类型,提高查询效率
+let walkablePointsMap = new Map();
 
 // 创建游戏状态的响应式对象
 const gameState = reactive({
@@ -227,7 +181,7 @@ const gameState = reactive({
     // 地图背景图片路径
     background: mapBackgroundImage,
     // 每个瓦片的尺寸(像素)
-    tileSize: 110,
+    tileSize: CONFIG.STYLES.DEFAULT_TILE_SIZE,
   },
 
   // 玩家相关状态
@@ -263,7 +217,6 @@ const gameState = reactive({
       { x: 1, y: 1, type: 'ice' }, { x: 2, y: 1, type: 'ice' }, { x: 3, y: 1 }, { x: 4, y: 1 },
       { x: 1, y: 2 }, { x: 2, y: 2 }, { x: 3, y: 2, type: 'ice' }, { x: 4, y: 2 },
       { x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 3 }, { x: 4, y: 3 },
-      { x: 4, y: 3 },
     ],
   }
 });
@@ -280,6 +233,7 @@ const isColliding = computed(() => gameState.player.isColliding);
 const hasReachedEnd = computed(() => gameState.player.hasReachedEnd);
 const gameMessage = computed(() => gameState.status.message);
 const messageType = computed(() => gameState.status.messageType);
+const isSliding = computed(() => gameState.player.isSliding);
 
 // 计算玩家图片路径,优先使用接口数据
 const playerImageSrc = computed(() => {
@@ -288,14 +242,87 @@ const playerImageSrc = computed(() => {
   }
   return playerImage;
 });
-const isSliding = computed(() => gameState.player.isSliding);
 
+// 生命周期钩子
+onMounted(async () => {
+  // 获取游戏数据
+  await fetchGameData();
+  // 初始化可行走点集合
+  initWalkablePointsSet();
+  // 注册自定义积木
+  registerCustomBlocks();
+  // 注册JavaScript生成器
+  registerJavaScriptGenerators();
+  // 初始化Blockly工作区
+  initBlockly();
+  // 重置玩家位置
+  resetPlayer();
+});
 
-// Blockly相关状态
-let workspace = null;
+// 获取游戏数据
+const fetchGameData = async () => {
+  try {
+    const gameId = route.query.gameId;
+    const nameFromRoute = route.query.gameName;
+    const sortFromRoute = route.query.gameSort;
 
-// 使用 Map 存储可行走点及其类型,提高查询效率
-let walkablePointsMap = new Map();
+    if (nameFromRoute) {
+      gameTitle.value = nameFromRoute;
+    }
+    if (sortFromRoute) {
+      gameSort.value = sortFromRoute;
+    }
+
+    let mapGameData = await getMapGameById(gameId);
+    if (mapGameData.code === 0) {
+      currentGameData.value = mapGameData?.data;
+
+      // 使用接口数据
+      if (currentGameData.value && currentGameData.value.sort) {
+        let sortNum = currentGameData.value.sort;
+        gameSort.value = sortNum > 9 ? `Game${sortNum}` : `Game${sortNum}`;
+      }
+
+      await updateGameStateFromData(currentGameData.value);
+    }
+  } catch (error) {
+    console.error('获取游戏数据失败:', error);
+  }
+};
+
+// 根据获取到的数据更新游戏状态
+const updateGameStateFromData = (gameData) => {
+  try {
+    // 更新地图配置
+    gameState.mapConfig.background = gameData.mapBackground ? gameData.mapBackground.trim() : mapBackgroundImage;
+    gameState.mapConfig.tileSize = gameData.mapTileSize || CONFIG.STYLES.DEFAULT_TILE_SIZE;
+
+    // 更新玩家方向
+    if (gameData.userDirection) {
+      playerInitialDirection.value = gameData.userDirection;
+    }
+
+    // 更新地图数据
+    // 地图起点
+    if (gameData.mapStartPoint) {
+      const startPoint = JSON.parse(gameData.mapStartPoint);
+      gameState.mapData.startPoint = { x: startPoint.x, y: startPoint.y };
+      gameState.player.position = { x: startPoint.x, y: startPoint.y };
+    }
+    // 地图终点
+    if (gameData.mapEndPoint) {
+      const endPoint = JSON.parse(gameData.mapEndPoint);
+      gameState.mapData.endPoint = { x: endPoint.x, y: endPoint.y };
+    }
+    if (gameData.mapWalkablePoints) {
+      gameState.mapData.walkablePoints = JSON.parse(gameData.mapWalkablePoints);
+    }
+    // 重新初始化可行走点集合
+    initWalkablePointsSet();
+  } catch (error) {
+    console.error('更新游戏状态失败:', error);
+  }
+};
 
 // 初始化可行走点映射
 function initWalkablePointsSet() {
@@ -337,9 +364,9 @@ const playerStyle = computed(() => ({
   transform: `rotate(${playerDirection.value * 90}deg)`,
   '--player-rotation': `${playerDirection.value * 90}deg`,
   '--player-image': `url(${playerImageSrc.value})`,
-  width: (tileSize.value * 0.8) + 'px',
-  height: (tileSize.value * 0.8) + 'px',
-  margin: (tileSize.value * 0.1) + 'px',
+  width: (tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO) + 'px',
+  height: (tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO) + 'px',
+  margin: (tileSize.value * (1 - CONFIG.STYLES.PLAYER_SIZE_RATIO) / 2) + 'px',
 }));
 
 // 显示游戏消息
@@ -347,10 +374,10 @@ function showGameMessage(message, type = 'info') {
   gameState.status.message = message;
   gameState.status.messageType = type;
 
-  // 3秒后自动清除消息
+  // 消息显示时间后自动清除消息
   setTimeout(() => {
     gameState.status.message = '';
-  }, 3000);
+  }, CONFIG.DELAY.MESSAGE_DISPLAY);
 }
 
 // 导航返回
@@ -494,11 +521,11 @@ function registerJavaScriptGenerators() {
     // 修复变量作用域问题,使用IIFE包装循环
     let code = '(async function() {\n';
     code += '  let loopCount = 0;\n';
-    code += until ? '  while (!((' + condition + ')) && loopCount < 100) {\n' :
-        '  while (((' + condition + ')) && loopCount < 100) {\n';
+    code += until ? '  while (!((' + condition + ')) && loopCount < ' + CONFIG.GAME.MAX_LOOP_COUNT + ') {\n' :
+        '  while (((' + condition + ')) && loopCount < ' + CONFIG.GAME.MAX_LOOP_COUNT + ') {\n';
     code += javascriptGenerator.prefixLines(branch, javascriptGenerator.INDENT + '  ');
     code += '    loopCount++';
-    code += '    await new Promise(resolve => setTimeout(resolve, 10));\n'; // 防止UI阻塞
+    code += '    await new Promise(resolve => setTimeout(resolve, ' + CONFIG.DELAY.LOOP_PREVENTION + '));\n'; // 防止UI阻塞
     code += '  }\n';
     code += '})();\n';
 
@@ -551,44 +578,47 @@ function initBlockly() {
 async function smoothMoveTo(targetX, targetY) {
   const startX = playerPosition.value.x;
   const startY = playerPosition.value.y;
-  const duration = 500; // 移动动画持续时间(毫秒)
+
   const startTime = performance.now();
 
-  // 使用 requestAnimationFrame 实现平滑动画
+  // 使用Promise包装动画过程,使其可以await
   return new Promise(resolve => {
     function animate(currentTime) {
-      const elapsedTime = currentTime - startTime;
-
-      // 计算进度,确保不会超过1
-      const progress = Math.min(elapsedTime / duration, 1);
+      // 检查是否应该停止执行
+      if (shouldStopExecution) {
+        resolve();
+        return;
+      }
 
-      // 使用缓动函数使动画更自然
-      const easedProgress = progress * (2 - progress); // easeOutQuad 缓动
+      const elapsed = currentTime - startTime;
+      const progress = Math.min(elapsed / CONFIG.ANIMATION.MOVE_DURATION, 1); // 计算进度,最大为1
 
-      // 计算当前位置
-      const currentX = startX + (targetX - startX) * easedProgress;
-      const currentY = startY + (targetY - startY) * easedProgress;
+      // 线性插值计算当前位置
+      const currentX = startX + (targetX - startX) * progress;
+      const currentY = startY + (targetY - startY) * progress;
 
-      // 更新玩家位置
-      gameState.player.position = { x: currentX, y: currentY };
+      gameState.player = {
+        ...gameState.player,
+        position: { x: currentX, y: currentY }
+      };
 
-      // 如果动画未完成,继续下一帧
+      // 检查是否到达终点
       if (progress < 1) {
+        // 继续动画
         requestAnimationFrame(animate);
       } else {
-        // 动画完成后解析Promise
-        resolve();
+        resolve(); // 动画完成
       }
     }
 
-    // 开始动画
+    // 启动动画
     requestAnimationFrame(animate);
   });
 }
 
 // 创建通用的移动函数
 async function move(direction) {
-  if (isColliding.value || isSliding.value) {
+  if (shouldStopExecution || isColliding.value || isSliding.value) {
     return;
   }
 
@@ -599,18 +629,18 @@ async function move(direction) {
   if (direction === 1) {
     // 向前移动
     switch(playerDirection.value) {
-      case 0: newY--; break;
-      case 1: newX++; break;
-      case 2: newY++; break;
-      case 3: newX--; break;
+      case CONFIG.GAME.DIRECTIONS.UP: newY--; break;
+      case CONFIG.GAME.DIRECTIONS.RIGHT: newX++; break;
+      case CONFIG.GAME.DIRECTIONS.DOWN: newY++; break;
+      case CONFIG.GAME.DIRECTIONS.LEFT: newX--; break;
     }
   } else {
     // 向后移动
     switch(playerDirection.value) {
-      case 0: newY++; break;
-      case 1: newX--; break;
-      case 2: newY--; break;
-      case 3: newX++; break;
+      case CONFIG.GAME.DIRECTIONS.UP: newY++; break;
+      case CONFIG.GAME.DIRECTIONS.RIGHT: newX--; break;
+      case CONFIG.GAME.DIRECTIONS.DOWN: newY--; break;
+      case CONFIG.GAME.DIRECTIONS.LEFT: newX++; break;
     }
   }
 
@@ -623,6 +653,8 @@ async function move(direction) {
     if (isIce(newX, newY)) {
       await handleIceSliding();
     }
+
+    await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ACTION_DELAY));
   } else {
     // 发生碰撞
     gameState.player.isColliding = true;
@@ -633,13 +665,13 @@ async function move(direction) {
       executionAbortController.abort();
     }
 
-    // 1秒后取消碰撞状态
+    // 碰撞状态重置时间后取消碰撞状态
     setTimeout(() => {
       gameState.player.isColliding = false;
-    }, 1000);
+    }, CONFIG.DELAY.COLLISION_RESET);
 
     // 添加碰撞延迟
-    await new Promise(resolve => setTimeout(resolve, 500));
+    await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.COLLISION_DELAY));
   }
 }
 
@@ -656,10 +688,10 @@ async function handleIceSliding() {
 
       // 根据当前方向计算下一个位置
       switch(playerDirection.value) {
-        case 0: nextY--; break;
-        case 1: nextX++; break;
-        case 2: nextY++; break;
-        case 3: nextX--; break;
+        case CONFIG.GAME.DIRECTIONS.UP: nextY--; break;
+        case CONFIG.GAME.DIRECTIONS.RIGHT: newX++; break;
+        case CONFIG.GAME.DIRECTIONS.DOWN: newY++; break;
+        case CONFIG.GAME.DIRECTIONS.LEFT: newX--; break;
       }
 
       // 检查下一个位置是否可行走
@@ -672,9 +704,6 @@ async function handleIceSliding() {
           // 如果不是冰块,结束滑行
           break;
         }
-
-        // 添加滑行间隔时间
-        await new Promise(resolve => setTimeout(resolve, 500));
       } else {
         // 下一个位置不可行走,检查是否是墙体
         gameState.player.isColliding = true;
@@ -685,13 +714,10 @@ async function handleIceSliding() {
           executionAbortController.abort();
         }
 
-        // 1秒后取消碰撞状态
+        // 碰撞状态重置时间后取消碰撞状态
         setTimeout(() => {
           gameState.player.isColliding = false;
-        }, 1000);
-
-        // 添加碰撞延迟
-        await new Promise(resolve => setTimeout(resolve, 500));
+        }, CONFIG.DELAY.COLLISION_RESET);
 
         break;
       }
@@ -716,48 +742,156 @@ window.moveBackward = async function() {
 //向左转(逆时针旋转90度)
 window.turnLeft = async function() {
   // 如果已经发生过碰撞,不再执行任何旋转
-  if (isColliding.value) {
+  if (shouldStopExecution || isColliding.value) {
     return;
   }
 
-  // 向左转(逆时针旋转90度)
-  gameState.player.direction = (playerDirection.value - 1 + 4) % 4;
+  // 记录起始方向和目标方向
+  const startDirection = playerDirection.value;
+  const targetDirection = (playerDirection.value - 1 + 4) % 4;
+
+  // 实现平滑旋转
+  const startTime = performance.now();
+
+  // 使用 requestAnimationFrame 实现平滑动画
+  await new Promise(resolve => {
+    function animate(currentTime) {
+      // 检查是否应该停止执行
+      if (shouldStopExecution) {
+        resolve();
+        return;
+      }
 
-  // 添加旋转延迟
-  await new Promise(resolve => setTimeout(resolve, 500));
+      const elapsedTime = currentTime - startTime;
+      const progress = Math.min(elapsedTime / CONFIG.ANIMATION.ROTATE_DURATION, 1);
+
+      // 在动画过程中更新方向
+      gameState.player.direction = startDirection - progress;
+
+      // 如果动画未完成,继续下一帧
+      if (progress < 1) {
+        requestAnimationFrame(animate);
+      } else {
+        // 动画完成后设置最终方向
+        gameState.player.direction = targetDirection;
+        resolve();
+      }
+    }
+    // 开始动画
+    requestAnimationFrame(animate);
+  });
+
+  await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ACTION_DELAY));
 };
 
 //向右转(顺时针旋转90度)
 window.turnRight = async function() {
   // 如果已经发生过碰撞,不再执行任何旋转
-  if (isColliding.value) {
+  if (shouldStopExecution || isColliding.value) {
     return;
   }
 
-  // 向右转(顺时针旋转90度)
-  gameState.player.direction = (playerDirection.value + 1) % 4;
+  // 记录起始方向和目标方向
+  const startDirection = playerDirection.value;
+  const targetDirection = (playerDirection.value + 1) % 4;
+
+  // 实现平滑旋转
+  const startTime = performance.now();
+
+  // 使用 requestAnimationFrame 实现平滑动画
+  await new Promise(resolve => {
+    function animate(currentTime) {
+      // 检查是否应该停止执行
+      if (shouldStopExecution) {
+        resolve();
+        return;
+      }
+
+      const elapsedTime = currentTime - startTime;
+      const progress = Math.min(elapsedTime / CONFIG.ANIMATION.ROTATE_DURATION, 1);
+
+      // 处理从3到0的边界情况,确保顺时针旋转
+      let currentDirection;
+      if (startDirection === 3 && targetDirection === 0) {
+        // 对于从3到0的顺时针旋转,我们需要模拟+1的效果而不是-3
+        currentDirection = startDirection + progress;
+        // 当超过3.99时,设置为0(避免显示4)
+        if (currentDirection > 3.99) {
+          currentDirection = 0;
+        }
+      } else {
+        // 正常情况下的线性插值
+        currentDirection = startDirection + (targetDirection - startDirection) * progress;
+      }
+
+      // 在动画过程中更新方向
+      gameState.player.direction = currentDirection;
+
+      // 如果动画未完成,继续下一帧
+      if (progress < 1) {
+        requestAnimationFrame(animate);
+      } else {
+        // 动画完成后设置最终方向
+        gameState.player.direction = targetDirection;
+        resolve();
+      }
+    }
+
+    // 开始动画
+    requestAnimationFrame(animate);
+  });
 
-  // 添加旋转延迟
-  await new Promise(resolve => setTimeout(resolve, 500));
+  await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ACTION_DELAY));
 };
 
 // 向后转(旋转180度)
 window.turnAround = async function() {
   // 如果已经发生过碰撞,不再执行任何旋转
-  if (isColliding.value) {
+  if (shouldStopExecution || isColliding.value) {
     return;
   }
 
-  // 向后转(旋转180度)
-  gameState.player.direction = (playerDirection.value + 2) % 4;
+  // 记录起始方向和目标方向
+  const startDirection = playerDirection.value;
+  const targetDirection = (playerDirection.value + 2) % 4;
 
-  // 添加旋转延迟
-  await new Promise(resolve => setTimeout(resolve, 500));
+  // 实现平滑旋转
+  const startTime = performance.now();
+
+  // 使用 requestAnimationFrame 实现平滑动画
+  await new Promise(resolve => {
+    function animate(currentTime) {
+      // 检查是否应该停止执行
+      if (shouldStopExecution) {
+        resolve();
+        return;
+      }
+
+      const elapsedTime = currentTime - startTime;
+      const progress = Math.min(elapsedTime / CONFIG.ANIMATION.TURN_AROUND_DURATION, 1);
+
+      // 在动画过程中更新方向
+      gameState.player.direction = startDirection + 2 * progress;
+
+      // 如果动画未完成,继续下一帧
+      if (progress < 1) {
+        requestAnimationFrame(animate);
+      } else {
+        // 动画完成后设置最终方向
+        gameState.player.direction = targetDirection;
+        resolve();
+      }
+    }
+    // 开始动画
+    requestAnimationFrame(animate);
+  });
+
+  await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ACTION_DELAY));
 };
 
 //校验是否到达终点
 window.isFinish = async function() {
-  // 如果已经发生过碰撞,不再执行任何旋转
+  // 如果已经发生过碰撞,不再执行任何检查
   if (isColliding.value) {
     return;
   }
@@ -768,14 +902,13 @@ window.isFinish = async function() {
   }
 };
 
-// 添加一个变量来跟踪当前执行的代码
-let currentExecutionPromise = null;
-let executionAbortController = null;
 // 运行代码
 const runCode = async () => {
   try {
     await resetPlayer();
-    await new Promise(resolve => setTimeout(resolve, 500));
+    await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.RESET_DELAY));
+    // 重置执行标志,允许新的执行
+    shouldStopExecution = false;
 
     // 创建新的AbortController用于取消执行
     executionAbortController = new AbortController();
@@ -851,6 +984,9 @@ const clearWorkspace = () => {
 
 // 重置玩家位置和状态
 const resetPlayer = () => {
+  // 设置标志强制停止所有执行
+  shouldStopExecution = true;
+
   // 取消任何正在执行的代码
   if (executionAbortController) {
     executionAbortController.abort();
@@ -862,7 +998,7 @@ const resetPlayer = () => {
   }
 
   gameState.player.position = { ...startPoint.value };
-  gameState.player.direction = playerInitialDirection.value; // 重置为向上方向
+  gameState.player.direction = playerInitialDirection.value; // 重置为初始方向
   gameState.player.isColliding = false; //碰撞标志
   gameState.player.hasReachedEnd = false;
   gameState.player.isSliding = false; // 重置滑行状态
@@ -878,10 +1014,46 @@ onUnmounted(() => {
 
 <style scoped lang="scss">
 @use "sass:math";
+
 @function rpx($px) {
   @return math.div($px, 750) * 100vw;
 }
-/* 信息提示框样式 */
+
+//将tileSize属性绑定到CSS变量上
+:root {
+  --tile-size: v-bind('tileSize + "px"');
+}
+
+.map-game-container {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: transparent;
+  overflow-y: auto;
+}
+
+/* 自定义滚动条样式 */
+.map-game-container::-webkit-scrollbar {
+  width: rpx(2); /* 滚动条宽度 */
+}
+
+.map-game-container::-webkit-scrollbar-track {
+  background: #f1effd; /* 滚动条轨道背景色 */
+  border-radius: rpx(4);
+}
+
+.map-game-container::-webkit-scrollbar-thumb {
+  background: #e2ddfc; /* 滚动条滑块颜色 */
+  border-radius: rpx(4);
+}
+
+.map-game-container::-webkit-scrollbar-thumb:hover {
+  background: #e2ddfc; /* 滚动条滑块 hover 状态颜色 */
+}
+
+/* 游戏简介样式 */
 .info-message-container {
   display: flex;
   flex-direction: column;
@@ -927,46 +1099,10 @@ onUnmounted(() => {
   margin-bottom: 0;
 }
 
-
-//将tileSize属性绑定到CSS变量上
-:root {
-  --tile-size: v-bind('tileSize + "px"');
-}
-
-.map-game-container {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: transparent;
-  overflow-y: auto;
-}
-
-/* 自定义滚动条样式 */
-.map-game-container::-webkit-scrollbar {
-  width: rpx(2); /* 滚动条宽度 */
-}
-
-.map-game-container::-webkit-scrollbar-track {
-  background: #f1effd; /* 滚动条轨道背景色 */
-  border-radius: rpx(4);
-}
-
-.map-game-container::-webkit-scrollbar-thumb {
-  background: #e2ddfc; /* 滚动条滑块颜色 */
-  border-radius: rpx(4);
-}
-
-.map-game-container::-webkit-scrollbar-thumb:hover {
-  background: #e2ddfc; /* 滚动条滑块 hover 状态颜色 */
-}
-
 .title-box {
   position: relative;
   top: rpx(5);
   padding-left: 15px;
-  // margin-bottom: 20px;
   z-index: 10;
   display: flex;
   flex-direction: column;
@@ -1028,20 +1164,10 @@ onUnmounted(() => {
   border-radius: 15px;
 }
 
-.map-section h2 {
-  margin-bottom: 15px;
-  color: #2c3e50;
-  border-bottom: 2px solid #3498db;
-  padding-bottom: 8px;
-}
-
 .map-container {
-  //position: relative;
-  //width: 100%;
-  //height: 100%  ;
-  //display: flex;
-  //justify-content: center;
-  //align-items: center;
+  position: relative;
+  width: 100%;
+  height: 100%;
 }
 
 .map-background {
@@ -1051,12 +1177,6 @@ onUnmounted(() => {
   background-size: cover;
   background-position: center;
   background-repeat: no-repeat;
-  //margin: 0 auto;
-  //border: 2px solid #ddd;
-  //border-radius: 8px;
-  //overflow: hidden;
-  //background-color: #f0f0f0;
-
 }
 
 .map-image {
@@ -1083,7 +1203,6 @@ onUnmounted(() => {
   background-repeat: no-repeat;
   background-position: center;
   border-radius: 5px;
-  transition: all 0.3s ease;
   z-index: 10;
 }
 
@@ -1168,16 +1287,15 @@ onUnmounted(() => {
   gap: 20px;
 }
 
-.toolbox-section {
+// 合并重复的区块样式
+.map-section, .toolbox-section, .workspace-section {
   background: rgba(248, 249, 250, 0.82);
   padding: 15px;
   border-radius: 15px;
+  height: 100%;
 }
 
-// 合并重复的区块标题样式
-.map-section h2,
-.toolbox-section h2,
-.workspace-section h2 {
+.map-section h2, .toolbox-section h2, .workspace-section h2 {
   margin-bottom: 15px;
   color: #2c3e50;
   border-bottom: 2px solid #3498db;
@@ -1191,14 +1309,6 @@ onUnmounted(() => {
   background: rgba(248, 249, 250, 0.82);
   padding: 15px;
   border-radius: 15px;
-  height: 100%;
-}
-
-.workspace-section h2 {
-  margin-bottom: 15px;
-  color: #2c3e50;
-  border-bottom: 2px solid #3498db;
-  padding-bottom: 8px;
 }
 
 #blocklyDiv {