Kaynağa Gözat

blockly编程游戏
1、优化逻辑处理移动前、移动后的逻辑处理
2、明确分类:冰块、物品、任务(是否限制通行)、陷阱

liyanbo 7 ay önce
ebeveyn
işleme
7ca4c623b0
1 değiştirilmiş dosya ile 99 ekleme ve 64 silme
  1. 99 64
      src/views/block/MapGame.vue

+ 99 - 64
src/views/block/MapGame.vue

@@ -170,6 +170,11 @@ const CONFIG = {
     NO_ENTRY: '当前位置无通路,无法移动',
     UNFINISHED: '任务未完成!',
     FINISH: '恭喜你到达终点!',
+    PICKUP_ITEM: '拾取物品成功!',
+    NULL_PICKUP_ITEM: '当前位置没有可拾取的物品',
+    USE_ITEM_SUCCESS: '使用物品成功',
+    USE_SPECIAL_ITEM: '需要特殊物品才能使用',
+    NO_USE_ITEM: '当前位置不需要使用物品',
   }
 };
 
@@ -242,7 +247,10 @@ const gameState = reactive({
 });
 const BLOCKLY_MAP_TYPE_DICT = {
   ICE: 'ice',//冰块
-  YC: 'yaoshi',//钥匙
+  TASK: 'task',//钥匙
+  ITEM: 'item',//物品
+  TRAP: 'trap',//陷阱
+
 };
 
 // 计算属性 - 提高性能和可读性
@@ -711,8 +719,8 @@ async function smoothMoveTo(targetX, targetY) {
   });
 }
 
-// 处理冰块滑行逻辑(根据人物当前位置判断)
-async function switchMapType(isMapType = null) {
+// 处理地图类型逻辑
+async function switchMapType(type, isMapType = null) {
   //取人物当前位置
   let x = playerPosition.value.x;
   let y = playerPosition.value.y;
@@ -723,47 +731,46 @@ async function switchMapType(isMapType = null) {
     return isMapType === tileMap.type;
   }
 
-  //判断方块类型并处理逻辑
-  switch (tileMap.type) {
-    case BLOCKLY_MAP_TYPE_DICT.ICE:
-      do {
-        showGameMessage(tileMap.tip, 'warning',300)
-        await handleIceSliding();
-
-        tileMap = walkablePointsMap.get(`${playerPosition.value.x},${playerPosition.value.y}`);
-      }while (tileMap.type === BLOCKLY_MAP_TYPE_DICT.ICE && !isColliding.value)
-      break;
-    case BLOCKLY_MAP_TYPE_DICT.YC:
-      // showGameMessage(tileMap.tip, 'warning', 1000)
-      // // 处理携带物品逻辑
-      // if (tileMap && tileMap.img) {
-      //   // 将物品添加到玩家携带物品中
-      //   gameState.player.carriedItems.push({
-      //     ...tileMap,
-      //     originalX: x,
-      //     originalY: y
-      //   });
-      //
-      //   // 从地图上移除图标(但保留点的可通行性)
-      //   const pointIndex = gameState.mapData.walkablePoints.findIndex(
-      //       p => p.x === x && p.y === y
-      //   );
-      //   if (pointIndex !== -1) {
-      //     // 保留点但移除img属性
-      //     const updatedPoint = { ...gameState.mapData.walkablePoints[pointIndex] };
-      //     delete updatedPoint.img;
-      //     gameState.mapData.walkablePoints.splice(pointIndex, 1, updatedPoint);
-      //     // 更新映射
-      //     walkablePointsMap.set(`${x},${y}`, updatedPoint);
-      //   }
-      // }
-
-      break;
+  //移动前置
+  if (type === 0) {
+    //判断方块类型并处理逻辑
+    switch (tileMap.type) {
+      case BLOCKLY_MAP_TYPE_DICT.TASK:
+        await taskLogic(tileMap);
+        break;
+    }
+
+  }else {//移动后置
+
+    //判断方块类型并处理逻辑
+    switch (tileMap.type) {
+      case BLOCKLY_MAP_TYPE_DICT.ICE:
+        do {
+
+          showGameMessage(tileMap.tip, 'warning',300)
+
+
+          // 处理方块类型逻辑
+          await switchMapType(0);
+
+          await slidingLogic();
+
+          // 处理方块类型逻辑
+          await switchMapType(1);
+
+          tileMap = walkablePointsMap.get(`${playerPosition.value.x},${playerPosition.value.y}`);
+        }while (tileMap.type === BLOCKLY_MAP_TYPE_DICT.ICE && !isColliding.value)
+        break;
+      case BLOCKLY_MAP_TYPE_DICT.TRAP:
+        showGameMessage(tileMap.tip, 'error')
+        await handleWallCollision(tileMap.tip);
+        break;
+    }
   }
 }
 
 // 处理冰块滑行逻辑
-async function handleIceSliding() {
+async function slidingLogic() {
   if (shouldStopExecution || isColliding.value) {
     return;
   }
@@ -784,11 +791,12 @@ async function handleIceSliding() {
 
     // 检查下一个位置是否可行走
     if (isWalkable(nextX, nextY)) {
+
       // 执行平滑移动到下一个位置
       await smoothMoveTo(nextX, nextY);
 
     } else {
-      // 使用统一的碰撞处理方法,但不等待延迟(因为handleIceSliding不需要这个延迟)
+      // 使用统一的碰撞处理方法,但不等待延迟(因为slidingLogic不需要这个延迟)
       await handleWallCollision();
     }
   } catch (error) {
@@ -799,6 +807,22 @@ async function handleIceSliding() {
   }
 }
 
+// 处理陷阱逻辑
+async function taskLogic(tileMap) {
+  if (shouldStopExecution || isColliding.value) {
+    return;
+  }
+
+  try {
+    // 判断当前位置是否有特殊需求
+    if (tileMap && tileMap.type === BLOCKLY_MAP_TYPE_DICT.TASK && tileMap.must === true && tileMap.status !== true) {
+      await handleWallCollision(tileMap.unfinishedTip);
+    }
+  } catch (error) {
+    console.error('处理陷阱逻辑发生错误:', error);
+  }
+}
+
 // 拾取物品函数
 window.pickupItem = async function()  {
   //取人物当前位置
@@ -807,8 +831,8 @@ window.pickupItem = async function()  {
   let tileMap = walkablePointsMap.get(`${x},${y}`);
 
   // 判断是否是要拾取的方块类型
-  if (tileMap && tileMap.type) {
-    showGameMessage(tileMap.tip || '成功拾取物品!', 'warning')
+  if (tileMap && tileMap.type === BLOCKLY_MAP_TYPE_DICT.ITEM) {
+    showGameMessage(tileMap.tip || CONFIG.TIPS.PICKUP_ITEM, 'warning')
 
     // 处理携带物品逻辑
     if (tileMap && tileMap.img) {
@@ -833,7 +857,7 @@ window.pickupItem = async function()  {
       }
     }
   } else {
-    showGameMessage('当前位置没有可拾取的物品', 'info')
+    showGameMessage(CONFIG.TIPS.NULL_PICKUP_ITEM, 'info')
   }
 
   await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ACTION_DELAY));
@@ -847,21 +871,26 @@ window.useItem = async function() {
   let tileMap = walkablePointsMap.get(`${x},${y}`);
 
   // 判断当前位置是否有特殊需求
-  if (tileMap && tileMap.need) {
+  if (tileMap && tileMap.type === BLOCKLY_MAP_TYPE_DICT.TASK) {
     // 检查玩家是否携带了需要的物品
-    const requiredItems = tileMap.need;
-    debugger
+    const requiredItems = tileMap.type;
+
     let hasRequiredItem = false;
     let itemIndex = -1;
 
-    // 检查玩家携带的物品中是否有满足需求的物品
-    for (let i = 0; i < gameState.player.carriedItems.length; i++) {
-      const item = gameState.player.carriedItems[i];
-      if (requiredItems.includes(item.type)) {
-        hasRequiredItem = true;
-        itemIndex = i;
-        break;
-      }
+    // 检查玩家携带的物品中是否有满足需求的物品【目前后端只配置了按顺序使用物品,没有指定物品】
+    // for (let i = 0; i < gameState.player.carriedItems.length; i++) {
+    //   const item = gameState.player.carriedItems[i];
+    //   if (requiredItems.includes(item.type)) {
+    //     hasRequiredItem = true;
+    //     itemIndex = i;
+    //     break;
+    //   }
+    // }
+
+    if (gameState.player.carriedItems.length > 0) {
+          hasRequiredItem = true;
+          itemIndex = 0;
     }
 
     if (hasRequiredItem) {
@@ -873,7 +902,7 @@ window.useItem = async function() {
       if (pointIndex !== -1) {
         // 保留点但移除img属性
         const updatedPoint = { ...gameState.mapData.walkablePoints[pointIndex] };
-        updatedPoint.img = updatedPoint.needImg;
+        updatedPoint.img = updatedPoint.endImg;
         updatedPoint.status = true;
         gameState.mapData.walkablePoints.splice(pointIndex, 1, updatedPoint);
 
@@ -882,17 +911,17 @@ window.useItem = async function() {
       }
 
       // 使用物品成功
-      showGameMessage('物品使用成功!', 'success');
+      showGameMessage(tileMap.finishedTip || CONFIG.TIPS.USE_ITEM_SUCCESS, 'success');
 
       // 从携带物品中移除已使用的物品
       gameState.player.carriedItems.splice(itemIndex, 1);
 
     } else {
       // 提示缺少所需物品
-      showGameMessage(tileMap.tip || `需要特殊物品才能使用`, 'warning');
+      showGameMessage(tileMap.unfinishedTip || CONFIG.TIPS.USE_SPECIAL_ITEM, 'warning');
     }
   } else {
-    showGameMessage('当前位置不需要使用物品', 'info');
+    showGameMessage(CONFIG.TIPS.NO_USE_ITEM, 'info');
   }
 
   await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ACTION_DELAY));
@@ -917,11 +946,15 @@ window.moveForward = async function() {
 
   // 检查是否可以移动
   if (isWalkable(newX, newY)) {
+
+    // 处理方块类型逻辑
+    await switchMapType(0);
+
     // 使用平滑移动动画
     await smoothMoveTo(newX, newY);
 
     // 处理方块类型逻辑
-    await switchMapType();
+    await switchMapType(1);
 
     await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ACTION_DELAY));
   } else {
@@ -1091,7 +1124,7 @@ window.isFinish = async function() {
 
     //检查是否有未完成的任务点
     const pointIndex = gameState.mapData.walkablePoints.findIndex(
-        p => p.need !== undefined && p.need !== null && p.need !== "" && p.status !== true
+        p => p.type === BLOCKLY_MAP_TYPE_DICT.TASK && p.status !== true
     );
     if (pointIndex !== -1) {
       showGameMessage(CONFIG.TIPS.UNFINISHED, 'error');
@@ -1235,7 +1268,6 @@ function updateMapContainerDimensions() {
   }
 };
 
-
 // 显示游戏消息
 function showGameMessage(message, type = 'info', duration = CONFIG.DELAY.MESSAGE_DISPLAY) {
   gameState.status.message = message;
@@ -1248,17 +1280,20 @@ function showGameMessage(message, type = 'info', duration = CONFIG.DELAY.MESSAGE
 }
 
 // 统一处理撞到墙时的停止逻辑
-async function handleWallCollision() {
+async function handleWallCollision(endMsg = CONFIG.TIPS.NO_ENTRY) {
   // 设置碰撞状态
   gameState.player.isColliding = true;
   // 显示错误消息
-  showGameMessage(CONFIG.TIPS.NO_ENTRY, 'error');
+  showGameMessage(endMsg, 'error');
 
   // 立即中止整个代码执行
   if (executionAbortController) {
     executionAbortController.abort();
   }
 
+  // 所有动画和移动操作立即停止
+  shouldStopExecution = true;
+
   // 碰撞状态重置时间后取消碰撞状态
   setTimeout(() => {
     gameState.player.isColliding = false;