|
|
@@ -286,9 +286,14 @@ const CONFIG = {
|
|
|
STYLES: {
|
|
|
DEFAULT_TILE_SIZE: 143, // 默认瓦片大小
|
|
|
PLAYER_SIZE_RATIO: 0.8, // 玩家大小占瓦片的比例
|
|
|
- PLAYER_SIZE_MARGIN: 0.1, // 玩家大小占瓦片的比例
|
|
|
- ITEM_CONTAINER_POSITION: { x: 30, y: 30 },
|
|
|
- ITEM_CONTAINER_SPACING: 10
|
|
|
+ PLAYER_SIZE_MARGIN: 0.1, // 玩家大小占瓦片边距
|
|
|
+
|
|
|
+ IMG_SIZE_RATIO: 0.8, // 地图素材大小占瓦片的比例
|
|
|
+ IMG_SIZE_MARGIN: 0.1, // 地图素材大小占瓦片边距
|
|
|
+
|
|
|
+ ITEM_CONTAINER_POSITION: { x: 30, y: 30 }, // 物品容器位置
|
|
|
+ ITEM_CONTAINER_RATIO: 0.4, // 物品大小占容器的比例
|
|
|
+ ITEM_CONTAINER_SPACING: 10 // 物品大小占容器的间距
|
|
|
},
|
|
|
//提示语
|
|
|
TIPS: {
|
|
|
@@ -661,8 +666,8 @@ function getPointStyle(point) {
|
|
|
|
|
|
// 如果point有img属性,则添加图标
|
|
|
if (point.img) {
|
|
|
- const iconSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO;
|
|
|
- const marginSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_MARGIN;
|
|
|
+ const iconSize = tileSize.value * CONFIG.STYLES.IMG_SIZE_RATIO;
|
|
|
+ const marginSize = tileSize.value * CONFIG.STYLES.IMG_SIZE_MARGIN;
|
|
|
|
|
|
// 重置可能影响背景图显示的样式
|
|
|
style.backgroundColor = 'transparent';
|
|
|
@@ -682,7 +687,7 @@ function getPointStyle(point) {
|
|
|
|
|
|
// 计算携带物品样式
|
|
|
function getCarriedItemStyle(index, item) {
|
|
|
- const baseSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO * 0.5;
|
|
|
+ const baseSize = tileSize.value * CONFIG.STYLES.ITEM_CONTAINER_RATIO;
|
|
|
|
|
|
return {
|
|
|
position: 'relative',
|
|
|
@@ -797,12 +802,21 @@ const resetPlayer = async () => {
|
|
|
// 清除所有视频组件
|
|
|
const mapBackground = document.querySelector('.map-background');
|
|
|
if (mapBackground) {
|
|
|
+ // 清除视频元素
|
|
|
const videoElements = mapBackground.querySelectorAll('video');
|
|
|
videoElements.forEach(video => {
|
|
|
if (mapBackground.contains(video)) {
|
|
|
mapBackground.removeChild(video);
|
|
|
}
|
|
|
});
|
|
|
+
|
|
|
+ // 清除临时动画元素
|
|
|
+ const tempElements = mapBackground.querySelectorAll('div[style*="backgroundImage"]');
|
|
|
+ tempElements.forEach(temp => {
|
|
|
+ if (mapBackground.contains(temp)) {
|
|
|
+ mapBackground.removeChild(temp);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
// 确保小智显形(不隐形)
|
|
|
@@ -1098,7 +1112,7 @@ window.pickupItem = async function() {
|
|
|
|
|
|
// 判断是否是要拾取的方块类型
|
|
|
if (tileMap && tileMap.type === BLOCKLY_MAP_TYPE_DICT.ITEM) {
|
|
|
- showGameMessage(tileMap.tip || CONFIG.TIPS.PICKUP_ITEM, 'warning')
|
|
|
+ showGameMessage(tileMap.tip || CONFIG.TIPS.PICKUP_ITEM, 'warning');
|
|
|
|
|
|
// 处理携带物品逻辑
|
|
|
if (tileMap && tileMap.img) {
|
|
|
@@ -1129,7 +1143,7 @@ window.pickupItem = async function() {
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- showGameMessage(CONFIG.TIPS.NULL_PICKUP_ITEM, 'info')
|
|
|
+ showGameMessage(CONFIG.TIPS.NULL_PICKUP_ITEM, 'info');
|
|
|
}
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ACTION_DELAY));
|
|
|
@@ -1197,7 +1211,7 @@ window.pause = async function(seconds) {
|
|
|
const totalIterations = seconds * 10; // 总迭代次数
|
|
|
|
|
|
//处理特殊任务消失
|
|
|
- processingSpecialTasksDisappearing()
|
|
|
+ processingSpecialTasksDisappearing();
|
|
|
|
|
|
for (let i = 1; i <= totalIterations; i++) {
|
|
|
// 检查是否应该停止执行
|
|
|
@@ -1299,18 +1313,21 @@ window.isFinish = async function() {
|
|
|
|
|
|
//移动逻辑处理(前后通用)
|
|
|
async function moveStep(newX, newY, moveDirection = 0){
|
|
|
+ // 检查是否应该停止执行
|
|
|
+ if (shouldStopExecution) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
// 检查是否可以移动
|
|
|
if (walkablePointsMap.has(`${newX},${newY}`)) {
|
|
|
+ // 移动前处理方块类型逻辑
|
|
|
+ await switchMapType(0);
|
|
|
|
|
|
- // 处理方块类型逻辑
|
|
|
- await switchMapType(0);
|
|
|
+ // 使用平滑移动动画
|
|
|
+ await smoothMoveTo(newX, newY);
|
|
|
|
|
|
- // 使用平滑移动动画
|
|
|
- await smoothMoveTo(newX, newY);
|
|
|
-
|
|
|
- // 处理方块类型逻辑
|
|
|
- await switchMapType(1, moveDirection);
|
|
|
+ // 移动后处理方块类型逻辑
|
|
|
+ await switchMapType(1, moveDirection);
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, CONFIG.DELAY.ACTION_DELAY));
|
|
|
} else {
|
|
|
@@ -1498,15 +1515,15 @@ async function taskLogic(tileMap) {
|
|
|
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 iconSize = tileSize.value * CONFIG.STYLES.IMG_SIZE_RATIO;
|
|
|
+ const marginSize = tileSize.value * CONFIG.STYLES.IMG_SIZE_MARGIN;
|
|
|
|
|
|
// 计算物品在地图上的实际位置
|
|
|
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.5;
|
|
|
+ const finalSize = tileSize.value * CONFIG.STYLES.ITEM_CONTAINER_RATIO;
|
|
|
|
|
|
// 获取携带物品容器的位置(左上角)
|
|
|
// 注意:这里不需要考虑当前已携带物品数量,因为物品还没被添加
|
|
|
@@ -1573,9 +1590,9 @@ async function animateItemPickup(item, itemX, itemY) {
|
|
|
async function animateItemUse(item, itemIndex, finishAnimation) {
|
|
|
// 创建临时动画元素
|
|
|
const tempItem = document.createElement('div');
|
|
|
- const finalSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO * 0.5;
|
|
|
- const iconSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_RATIO;
|
|
|
- const marginSize = tileSize.value * CONFIG.STYLES.PLAYER_SIZE_MARGIN;
|
|
|
+ const finalSize = tileSize.value * CONFIG.STYLES.ITEM_CONTAINER_RATIO;
|
|
|
+ const iconSize = tileSize.value * CONFIG.STYLES.IMG_SIZE_RATIO;
|
|
|
+ const marginSize = tileSize.value * CONFIG.STYLES.IMG_SIZE_MARGIN;
|
|
|
|
|
|
// 计算物品在物品栏中的初始位置
|
|
|
let startLeft = CONFIG.STYLES.ITEM_CONTAINER_POSITION.x;
|
|
|
@@ -1735,11 +1752,11 @@ async function animateItemUse(item, itemIndex, finishAnimation) {
|
|
|
videoElement.style.opacity = '0';
|
|
|
|
|
|
// 等待淡出动画完成后再移除元素
|
|
|
- setTimeout(() => {
|
|
|
- if (mapBackground.contains(videoElement)) {
|
|
|
- mapBackground.removeChild(videoElement);
|
|
|
- }
|
|
|
- }, CONFIG.DELAY.VIDEO_FADE_DURATION); // 与动画时长一致
|
|
|
+ setTimeout(() => {
|
|
|
+ if (mapBackground.contains(videoElement)) {
|
|
|
+ mapBackground.removeChild(videoElement);
|
|
|
+ }
|
|
|
+ }, CONFIG.DELAY.VIDEO_FADE_DURATION); // 与动画时长一致
|
|
|
}
|
|
|
} else {
|
|
|
// 10.无视频
|
|
|
@@ -1796,10 +1813,54 @@ async function showPass(passStar){
|
|
|
//================卸载区=====================
|
|
|
// 组件卸载时清理
|
|
|
onUnmounted(() => {
|
|
|
+ // 清理Blockly工作区
|
|
|
if (workspace) {
|
|
|
workspace.dispose();
|
|
|
+ workspace = null;
|
|
|
}
|
|
|
+
|
|
|
+ // 移除事件监听器
|
|
|
window.removeEventListener('resize', updateMapContainerDimensions);
|
|
|
+
|
|
|
+ // 停止当前正在执行的代码
|
|
|
+ shouldStopExecution = true;
|
|
|
+
|
|
|
+ // 取消任何正在进行的执行
|
|
|
+ if (executionAbortController) {
|
|
|
+ executionAbortController.abort();
|
|
|
+ executionAbortController = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清除当前执行的Promise引用
|
|
|
+ currentExecutionPromise = null;
|
|
|
+
|
|
|
+ // 清理所有临时DOM元素
|
|
|
+ const mapBackground = document.querySelector('.map-background');
|
|
|
+ if (mapBackground) {
|
|
|
+ // 清除视频元素
|
|
|
+ const videoElements = mapBackground.querySelectorAll('video');
|
|
|
+ videoElements.forEach(video => {
|
|
|
+ if (mapBackground.contains(video)) {
|
|
|
+ mapBackground.removeChild(video);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 清除临时动画元素
|
|
|
+ const tempElements = mapBackground.querySelectorAll('div[style*="backgroundImage"]');
|
|
|
+ tempElements.forEach(temp => {
|
|
|
+ if (mapBackground.contains(temp)) {
|
|
|
+ mapBackground.removeChild(temp);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清理全局函数引用
|
|
|
+ window.pickupItem = null;
|
|
|
+ window.useItem = null;
|
|
|
+
|
|
|
+ // 重置游戏状态
|
|
|
+ gameState.player.carriedItems = [];
|
|
|
+ gameState.player.position = { ...startPoint.value };
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
@@ -2026,14 +2087,14 @@ onUnmounted(() => {
|
|
|
}
|
|
|
.message-item p {
|
|
|
margin: rpx(4) 0;
|
|
|
- line-height: 0;
|
|
|
- font-size: rpx(10);
|
|
|
+ line-height: 1.6;
|
|
|
+ font-size: rpx(7);
|
|
|
text-align: left;
|
|
|
color: black;
|
|
|
background-color: #e6faff;
|
|
|
opacity: 0.8;
|
|
|
border-radius: rpx(4);
|
|
|
- padding: rpx(2) rpx(5);
|
|
|
+ padding: rpx(6);
|
|
|
max-width: 100%;
|
|
|
}
|
|
|
.message-item p:first-child {
|
|
|
@@ -2454,7 +2515,7 @@ onUnmounted(() => {
|
|
|
gap: 20px;
|
|
|
}
|
|
|
|
|
|
-// 合并重复的区块样式
|
|
|
+// 统一区块样式
|
|
|
.map-section, .workspace-section {
|
|
|
background: rgba(248, 249, 250, 0.82);
|
|
|
padding: 15px;
|
|
|
@@ -2469,14 +2530,6 @@ onUnmounted(() => {
|
|
|
padding-bottom: 8px;
|
|
|
}
|
|
|
|
|
|
-// 合并重复的区块背景样式
|
|
|
-.map-section,
|
|
|
-.workspace-section {
|
|
|
- background: rgba(248, 249, 250, 0.82);
|
|
|
- padding: 15px;
|
|
|
- border-radius: 15px;
|
|
|
-}
|
|
|
-
|
|
|
#blocklyDiv {
|
|
|
height: 87%;
|
|
|
min-height: rpx(250);
|