|
|
@@ -51,7 +51,7 @@
|
|
|
:key="index"
|
|
|
class="carried-item"
|
|
|
:style="getCarriedItemStyle(index, item)"
|
|
|
- ></div>
|
|
|
+ ></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
@@ -77,28 +77,18 @@
|
|
|
<block type="use_item"></block>
|
|
|
</category>
|
|
|
|
|
|
- <!-- 逻辑控制积木 -->
|
|
|
<category name="逻辑" colour="%{BKY_LOGIC_HUE}">
|
|
|
<block type="controls_if"></block>
|
|
|
<block type="logic_compare"></block>
|
|
|
<block type="logic_operation"></block>
|
|
|
- <block type="logic_negate"></block>
|
|
|
<block type="logic_boolean"></block>
|
|
|
</category>
|
|
|
|
|
|
- <!-- 循环控制积木 -->
|
|
|
<category name="循环" colour="%{BKY_LOOPS_HUE}">
|
|
|
- <block type="controls_repeat_ext">
|
|
|
- <value name="TIMES">
|
|
|
- <shadow type="math_number">
|
|
|
- <field name="NUM"></field>
|
|
|
- </shadow>
|
|
|
- </value>
|
|
|
- </block>
|
|
|
- <block type="controls_whileUntil"></block>
|
|
|
+ <block type="controls_repeat_ext"></block>
|
|
|
+<!-- <block type="controls_whileUntil"></block>-->
|
|
|
</category>
|
|
|
|
|
|
- <!-- 数学运算积木 -->
|
|
|
<category name="数学" colour="%{BKY_MATH_HUE}">
|
|
|
<block type="math_number"></block>
|
|
|
<block type="math_arithmetic"></block>
|
|
|
@@ -148,6 +138,8 @@ const CONFIG = {
|
|
|
MESSAGE_DISPLAY: 2000, // 消息显示时间
|
|
|
COLLISION_RESET: 1000, // 碰撞状态重置时间
|
|
|
LOOP_PREVENTION: 10, // 循环防止UI阻塞的延迟
|
|
|
+ ITEMS_APPEAR: 300, // 物品出现延迟时间
|
|
|
+ ITEMS_FLIGHT_ANIMATION_DELAY: 800, // 飞行动画延迟时间
|
|
|
},
|
|
|
// 游戏配置
|
|
|
GAME: {
|
|
|
@@ -638,8 +630,83 @@ function registerJavaScriptGenerators() {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+const setupBlocklyChineseLocale = () => {
|
|
|
+ // 覆盖默认的英文文本为中文
|
|
|
+ if (!Blockly.Msg) Blockly.Msg = {};
|
|
|
+
|
|
|
+ // 逻辑积木中文配置
|
|
|
+ Blockly.Msg.CONTROLS_IF_MSG_IF = "如果";
|
|
|
+ Blockly.Msg.CONTROLS_IF_MSG_ELSEIF = "否则如果";
|
|
|
+ Blockly.Msg.CONTROLS_IF_MSG_ELSE = "否则";
|
|
|
+ Blockly.Msg.CONTROLS_IF_MSG_DO = "执行"; // 添加这行将'do'转换为中文
|
|
|
+ Blockly.Msg.CONTROLS_IF_TOOLTIP_1 = "如果条件为真,则执行相应的代码。";
|
|
|
+ Blockly.Msg.CONTROLS_IF_TOOLTIP_2 = "如果条件为真,则执行相应的代码;否则执行其他代码。";
|
|
|
+ Blockly.Msg.CONTROLS_IF_TOOLTIP_3 = "如果条件为真,则执行相应的代码;否则检查其他条件。";
|
|
|
+
|
|
|
+ // 添加设置按钮相关的中文配置
|
|
|
+ Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP = "否则如果条件为真,则执行相应的代码。";
|
|
|
+ Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP = "否则执行相应的代码。";
|
|
|
+
|
|
|
+ // 打开/关闭块的提示文本
|
|
|
+ Blockly.Msg.CONTROLS_IF_TOOLTIP_IF = "添加或删除条件。";
|
|
|
+ Blockly.Msg.CONTROLS_IF_TOOLTIP_ELSE = "添加或删除否则块。";
|
|
|
+
|
|
|
+
|
|
|
+ // 比较运算符中文配置 - 添加显示文本
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_EQ = "等于";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_NEQ = "不等于";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_LT = "小于";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_LTE = "小于等于";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_GT = "大于";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_GTE = "大于等于";
|
|
|
+
|
|
|
+ // 比较运算符提示文本(已存在)
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ = "比较两个值是否相等。";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ = "比较两个值是否不相等。";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT = "比较第一个值是否小于第二个值。";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE = "比较第一个值是否小于或等于第二个值。";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT = "比较第一个值是否大于第二个值。";
|
|
|
+ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE = "比较第一个值是否大于或等于第二个值。";
|
|
|
+
|
|
|
+ // 逻辑运算中文配置 - 添加显示文本
|
|
|
+ Blockly.Msg.LOGIC_OPERATION_AND = "且";
|
|
|
+ Blockly.Msg.LOGIC_OPERATION_OR = "或";
|
|
|
+
|
|
|
+ // 逻辑运算提示文本(已存在)
|
|
|
+ Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND = "如果两个条件都为真,则结果为真。";
|
|
|
+ Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR = "如果任一条件为真,则结果为真。";
|
|
|
+
|
|
|
+ // 布尔值配置
|
|
|
+ Blockly.Msg.LOGIC_BOOLEAN_TRUE = "真";
|
|
|
+ Blockly.Msg.LOGIC_BOOLEAN_FALSE = "假";
|
|
|
+ Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP = "返回一个布尔值:真或假。";
|
|
|
+
|
|
|
+ // 循环积木中文配置(保持不变)
|
|
|
+ Blockly.Msg.CONTROLS_REPEAT_TITLE = "重复%1次";
|
|
|
+ Blockly.Msg.CONTROLS_REPEAT_TOOLTIP = "重复执行内部代码指定次数。";
|
|
|
+ // Blockly.Msg.CONTROLS_WHILEUNTIL_TITLE_WHILE = "当%1时重复";
|
|
|
+ // Blockly.Msg.CONTROLS_WHILEUNTIL_TITLE_UNTIL = "重复直到%1";
|
|
|
+ // Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE = "只要条件为真,就重复执行内部代码。";
|
|
|
+ // Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL = "重复执行内部代码,直到条件变为真。";
|
|
|
+
|
|
|
+ // 数学积木中文配置(保持不变)
|
|
|
+ Blockly.Msg.MATH_NUMBER_TOOLTIP = "一个数字。在编辑器中双击以更改。";
|
|
|
+ Blockly.Msg.MATH_ADDITION_SYMBOL = "加";
|
|
|
+ Blockly.Msg.MATH_SUBTRACTION_SYMBOL = "减";
|
|
|
+ Blockly.Msg.MATH_MULTIPLICATION_SYMBOL = "乘";
|
|
|
+ Blockly.Msg.MATH_DIVISION_SYMBOL = "除";
|
|
|
+ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD = "返回两个数的和。";
|
|
|
+ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_SUBTRACT = "返回第一个数减去第二个数的差。";
|
|
|
+ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY = "返回两个数的积。";
|
|
|
+ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE = "返回第一个数除以第二个数的商。";
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
// 初始化Blockly工作区
|
|
|
function initBlockly() {
|
|
|
+ // 应用中文配置
|
|
|
+ setupBlocklyChineseLocale();
|
|
|
+
|
|
|
const toolbox = document.getElementById('toolbox');
|
|
|
workspace = Blockly.inject('blocklyDiv', {
|
|
|
toolbox: toolbox,
|
|
|
@@ -803,7 +870,7 @@ async function slidingLogic() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 处理陷阱逻辑
|
|
|
+// 处理任务逻辑
|
|
|
async function taskLogic(tileMap) {
|
|
|
if (shouldStopExecution || isColliding.value) {
|
|
|
return;
|
|
|
@@ -813,36 +880,38 @@ async function taskLogic(tileMap) {
|
|
|
// 判断当前位置是否有特殊需求
|
|
|
if (tileMap && tileMap.type === BLOCKLY_MAP_TYPE_DICT.TASK && tileMap.must === true && tileMap.status !== true) {
|
|
|
await handleWallCollision(tileMap.unfinishedTip);
|
|
|
+ return;
|
|
|
}
|
|
|
} catch (error) {
|
|
|
- console.error('处理陷阱逻辑发生错误:', error);
|
|
|
+ console.error('处理任务逻辑发生错误:', error);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 物品拾取动画函数 - 放大晃动两下然后移动到左上角物品容器
|
|
|
+// 物品拾取动画函数
|
|
|
async function animateItemPickup(item, itemX, itemY) {
|
|
|
// 创建临时动画元素
|
|
|
const tempItem = document.createElement('div');
|
|
|
const iconSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO;
|
|
|
const marginSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_MARGIN;
|
|
|
-
|
|
|
+
|
|
|
// 计算物品在地图上的实际位置
|
|
|
- const mapContainer = document.querySelector('.map-container');
|
|
|
- const mapRect = mapContainer.getBoundingClientRect();
|
|
|
const itemLeft = itemX * tileSize.value - tileSize.value + marginSize;
|
|
|
const itemTop = itemY * tileSize.value - tileSize.value + marginSize;
|
|
|
-
|
|
|
+
|
|
|
+ // 平行移动到容器位置,同时调整大小
|
|
|
+ const finalSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO * 0.3;
|
|
|
+
|
|
|
// 获取携带物品容器的位置(左上角)
|
|
|
- const carriedContainer = document.querySelector('.carried-items-container');
|
|
|
- let containerLeft = 30; // 默认值,如果容器不存在
|
|
|
- let containerTop = 30; // 默认值,如果容器不存在
|
|
|
-
|
|
|
- if (carriedContainer) {
|
|
|
- const containerRect = carriedContainer.getBoundingClientRect();
|
|
|
- containerLeft = containerRect.left - mapRect.left + 10; // 加上内边距
|
|
|
- containerTop = containerRect.top - mapRect.top + 10; // 加上内边距
|
|
|
+ // 注意:这里不需要考虑当前已携带物品数量,因为物品还没被添加
|
|
|
+ let containerLeft = 30;
|
|
|
+ let containerTop = 30;
|
|
|
+
|
|
|
+ // 如果已经有物品,计算新物品应该出现的位置
|
|
|
+ if (gameState.player.carriedItems.length > 0) {
|
|
|
+ let containerSize = finalSize + 10;
|
|
|
+ containerLeft = 30 + gameState.player.carriedItems.length * containerSize;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 设置临时元素样式
|
|
|
Object.assign(tempItem.style, {
|
|
|
position: 'absolute',
|
|
|
@@ -855,50 +924,162 @@ async function animateItemPickup(item, itemX, itemY) {
|
|
|
backgroundPosition: 'center',
|
|
|
backgroundRepeat: 'no-repeat',
|
|
|
zIndex: '100', // 确保在最上层
|
|
|
- transition: 'transform 0.3s ease-out',
|
|
|
+ opacity: '0', // 初始完全透明
|
|
|
transform: 'scale(1)',
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
// 将临时元素添加到地图容器
|
|
|
const mapBackground = document.querySelector('.map-background');
|
|
|
+ if (!mapBackground) {
|
|
|
+ console.error('地图容器未找到');
|
|
|
+ return;
|
|
|
+ }
|
|
|
mapBackground.appendChild(tempItem);
|
|
|
-
|
|
|
- // 强制重排,确保动画能正常触发
|
|
|
- await nextTick();
|
|
|
-
|
|
|
- // 第一下放大晃动
|
|
|
- tempItem.style.transform = 'scale(1.3) translateX(-5px)';
|
|
|
- await new Promise(resolve => setTimeout(resolve, 150));
|
|
|
-
|
|
|
- // 第二下放大晃动
|
|
|
- tempItem.style.transform = 'scale(1.3) translateX(5px)';
|
|
|
- await new Promise(resolve => setTimeout(resolve, 150));
|
|
|
-
|
|
|
- // 准备移动动画
|
|
|
- tempItem.style.transition = 'all 1.2s ease-out'; // 减慢动画速度
|
|
|
-
|
|
|
- // 平行移动到容器位置,同时调整大小
|
|
|
- const finalSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO * 0.3;
|
|
|
+
|
|
|
+ // 触发淡入动画
|
|
|
+ tempItem.offsetHeight;
|
|
|
+ tempItem.style.transition = 'opacity ' + CONFIG.DELAY.ITEMS_APPEAR + 'ms ease-out';
|
|
|
+ tempItem.style.opacity = '1'; // 完全显示
|
|
|
+ await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ITEMS_APPEAR));
|
|
|
+
|
|
|
+ // 移动动画
|
|
|
+ tempItem.style.transition = 'all ' + CONFIG.DELAY.ITEMS_FLIGHT_ANIMATION_DELAY + 'ms ease-out'; // 减慢动画速度
|
|
|
Object.assign(tempItem.style, {
|
|
|
left: containerLeft + 'px',
|
|
|
top: containerTop + 'px',
|
|
|
width: finalSize + 'px',
|
|
|
height: finalSize + 'px',
|
|
|
- opacity: '0.8', // 稍微淡化
|
|
|
+ opacity: '0.8',
|
|
|
transform: 'scale(1)',
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
// 等待动画完成
|
|
|
- await new Promise(resolve => setTimeout(resolve, 1200));
|
|
|
-
|
|
|
+ await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ITEMS_FLIGHT_ANIMATION_DELAY));
|
|
|
+
|
|
|
+ // 移除临时元素
|
|
|
+ if (mapBackground.contains(tempItem)) {
|
|
|
+ mapBackground.removeChild(tempItem);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 物品使用动画函数
|
|
|
+async function animateItemUse(item, itemIndex) {
|
|
|
+ // 创建临时动画元素
|
|
|
+ const tempItem = document.createElement('div');
|
|
|
+ const finalSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO * 0.3;
|
|
|
+ const iconSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO;
|
|
|
+ const marginSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_MARGIN;
|
|
|
+
|
|
|
+ // 计算物品在物品栏中的初始位置
|
|
|
+ let startLeft = 30;
|
|
|
+ let startTop = 30;
|
|
|
+ let containerSize = finalSize + 10;
|
|
|
+
|
|
|
+ // 根据物品索引计算在物品栏中的位置
|
|
|
+ if (itemIndex > 0) {
|
|
|
+ startLeft = 30 + itemIndex * containerSize;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算玩家当前位置(物品目标位置)
|
|
|
+ const playerLeft = playerPosition.value.x * tileSize.value - tileSize.value + marginSize;
|
|
|
+ const playerTop = playerPosition.value.y * tileSize.value - tileSize.value + marginSize;
|
|
|
+
|
|
|
+ // 获取玩家元素
|
|
|
+ const playerElement = document.querySelector('.player');
|
|
|
+ const originalPlayerZIndex = playerElement ? playerElement.style.zIndex : '';
|
|
|
+
|
|
|
+ // 获取当前位置的任务点元素
|
|
|
+ let taskPointElement = null;
|
|
|
+ const walkablePointsElements = document.querySelectorAll('.walkable-point');
|
|
|
+ walkablePointsElements.forEach(el => {
|
|
|
+ const rect = el.getBoundingClientRect();
|
|
|
+ const targetRect = {
|
|
|
+ left: playerLeft,
|
|
|
+ top: playerTop,
|
|
|
+ width: iconSize,
|
|
|
+ height: iconSize
|
|
|
+ };
|
|
|
+ // 简单判断元素是否在玩家位置附近
|
|
|
+ if (Math.abs(rect.left - targetRect.left) < iconSize &&
|
|
|
+ Math.abs(rect.top - targetRect.top) < iconSize) {
|
|
|
+ taskPointElement = el;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 先将任务图标置顶盖住人物
|
|
|
+ if (taskPointElement) {
|
|
|
+ taskPointElement.style.zIndex = '150';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置临时元素初始样式
|
|
|
+ Object.assign(tempItem.style, {
|
|
|
+ position: 'absolute',
|
|
|
+ left: startLeft + 'px',
|
|
|
+ top: startTop + 'px',
|
|
|
+ width: finalSize + 'px',
|
|
|
+ height: finalSize + 'px',
|
|
|
+ backgroundImage: `url(${item.img})`,
|
|
|
+ backgroundSize: 'contain',
|
|
|
+ backgroundPosition: 'center',
|
|
|
+ backgroundRepeat: 'no-repeat',
|
|
|
+ zIndex: '120',
|
|
|
+ transition: 'transform ' + CONFIG.DELAY.ITEMS_APPEAR + 'ms ease-out',
|
|
|
+ transform: 'scale(1)',
|
|
|
+ });
|
|
|
+
|
|
|
+ // 将临时元素添加到地图容器
|
|
|
+ const mapBackground = document.querySelector('.map-background');
|
|
|
+ if (!mapBackground) {
|
|
|
+ console.error('地图容器未找到');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ mapBackground.appendChild(tempItem);
|
|
|
+
|
|
|
+ // 准备漂移动画
|
|
|
+ await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ITEMS_APPEAR));
|
|
|
+
|
|
|
+ // 设置漂移动画样式
|
|
|
+ tempItem.style.transition = 'all 1s ease-out';
|
|
|
+ Object.assign(tempItem.style, {
|
|
|
+ left: playerLeft + 'px',
|
|
|
+ top: playerTop + 'px',
|
|
|
+ width: iconSize + 'px',
|
|
|
+ height: iconSize + 'px',
|
|
|
+ });
|
|
|
+
|
|
|
+ // 等待漂移到玩家位置
|
|
|
+ await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ITEMS_FLIGHT_ANIMATION_DELAY));
|
|
|
+
|
|
|
+ // 物品使用效果动画
|
|
|
+ tempItem.style.transition = 'transform 0.3s ease-in-out';
|
|
|
+ tempItem.style.transform = 'scale(1.2)';
|
|
|
+
|
|
|
+ await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ITEMS_APPEAR));
|
|
|
+
|
|
|
// 移除临时元素
|
|
|
if (mapBackground.contains(tempItem)) {
|
|
|
mapBackground.removeChild(tempItem);
|
|
|
}
|
|
|
+
|
|
|
+ // 延迟一段时间后将人物图标置顶,露出完整的人物图标
|
|
|
+ await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ITEMS_APPEAR));
|
|
|
+
|
|
|
+ // 恢复层级关系
|
|
|
+ if (taskPointElement) {
|
|
|
+ taskPointElement.style.zIndex = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ if (playerElement) {
|
|
|
+ playerElement.style.zIndex = originalPlayerZIndex || '';
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 拾取物品函数
|
|
|
window.pickupItem = async function() {
|
|
|
+ if (shouldStopExecution || isColliding.value || isSliding.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
//取人物当前位置
|
|
|
let x = playerPosition.value.x;
|
|
|
let y = playerPosition.value.y;
|
|
|
@@ -910,27 +1091,29 @@ window.pickupItem = async function() {
|
|
|
|
|
|
// 处理携带物品逻辑
|
|
|
if (tileMap && tileMap.img) {
|
|
|
- // 执行物品拾取动画:放大晃动两下然后移动到左上角物品容器
|
|
|
- await animateItemPickup(tileMap, x, y);
|
|
|
-
|
|
|
- // 将物品添加到玩家携带物品中
|
|
|
- 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);
|
|
|
+
|
|
|
+ // 执行物品拾取动画:放大晃动两下然后移动到左上角物品容器
|
|
|
+ await animateItemPickup(tileMap, x, y);
|
|
|
+
|
|
|
+ // 将物品添加到玩家携带物品中
|
|
|
+ gameState.player.carriedItems.push({
|
|
|
+ ...tileMap,
|
|
|
+ originalX: x,
|
|
|
+ originalY: y
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
@@ -942,6 +1125,10 @@ window.pickupItem = async function() {
|
|
|
|
|
|
// 使用物品函数
|
|
|
window.useItem = async function() {
|
|
|
+ if (shouldStopExecution || isColliding.value || isSliding.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
//取人物当前位置
|
|
|
let x = playerPosition.value.x;
|
|
|
let y = playerPosition.value.y;
|
|
|
@@ -955,31 +1142,29 @@ window.useItem = async function() {
|
|
|
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;
|
|
|
- // }
|
|
|
- // }
|
|
|
-
|
|
|
if (gameState.player.carriedItems.length > 0) {
|
|
|
- hasRequiredItem = true;
|
|
|
- itemIndex = 0;
|
|
|
+ hasRequiredItem = true;
|
|
|
+ itemIndex = 0;
|
|
|
}
|
|
|
|
|
|
if (hasRequiredItem) {
|
|
|
|
|
|
+ // 获取要使用的物品
|
|
|
+ const itemToUse = gameState.player.carriedItems[itemIndex];
|
|
|
+ // 执行物品使用动画
|
|
|
+ await animateItemUse(itemToUse, itemIndex);
|
|
|
+ // 从携带物品中移除已使用的物品
|
|
|
+ gameState.player.carriedItems.splice(itemIndex, 1);
|
|
|
+
|
|
|
// 从地图上移除图标(但保留点的可通行性)
|
|
|
const pointIndex = gameState.mapData.walkablePoints.findIndex(
|
|
|
p => p.x === x && p.y === y
|
|
|
);
|
|
|
if (pointIndex !== -1) {
|
|
|
- // 保留点但移除img属性
|
|
|
+
|
|
|
+ // 保留点但移除img属性并设置完成状态图标
|
|
|
const updatedPoint = { ...gameState.mapData.walkablePoints[pointIndex] };
|
|
|
- updatedPoint.img = updatedPoint.endImg;
|
|
|
+ updatedPoint.img = updatedPoint.endImg; // 设置完成状态图标
|
|
|
updatedPoint.status = true;
|
|
|
gameState.mapData.walkablePoints.splice(pointIndex, 1, updatedPoint);
|
|
|
|
|
|
@@ -990,9 +1175,6 @@ window.useItem = async function() {
|
|
|
// 使用物品成功
|
|
|
showGameMessage(tileMap.finishedTip || CONFIG.TIPS.USE_ITEM_SUCCESS, 'success');
|
|
|
|
|
|
- // 从携带物品中移除已使用的物品
|
|
|
- gameState.player.carriedItems.splice(itemIndex, 1);
|
|
|
-
|
|
|
} else {
|
|
|
// 提示缺少所需物品
|
|
|
showGameMessage(tileMap.unfinishedTip || CONFIG.TIPS.USE_SPECIAL_ITEM, 'warning');
|
|
|
@@ -1760,6 +1942,52 @@ onUnmounted(() => {
|
|
|
border-radius: 8px;
|
|
|
}
|
|
|
|
|
|
+/* 优化Blockly积木样式 */
|
|
|
+/* 增加积木高度 */
|
|
|
+.blocklyBlockCanvas .blocklyBlock {
|
|
|
+ height: 45px; /* 增加默认高度 */
|
|
|
+ min-height: 45px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 增加积木内部元素的行高和间距 */
|
|
|
+.blocklyText {
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 20px;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+/* 增加输入字段的高度 */
|
|
|
+.blocklyHtmlInput {
|
|
|
+ height: 30px;
|
|
|
+ font-size: 14px;
|
|
|
+ padding: 5px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 增加下拉菜单的高度 */
|
|
|
+.blocklyDropdownMenu {
|
|
|
+ line-height: 28px;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 优化积木圆角和阴影效果 */
|
|
|
+.blocklyBlock {
|
|
|
+ border-radius: 8px;
|
|
|
+ filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
|
|
|
+}
|
|
|
+
|
|
|
+/* 增加积木之间的连接点间距 */
|
|
|
+.blocklyConnection {
|
|
|
+ height: 20px;
|
|
|
+ width: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 增加工具箱中积木的高度 */
|
|
|
+.blocklyTreeRow {
|
|
|
+ height: 40px;
|
|
|
+ line-height: 40px;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
.controls {
|
|
|
display: flex;
|
|
|
gap: 10px;
|