diff --git a/pages-game/game/minesweeper/play.scss b/pages-game/game/minesweeper/play.scss index 4c3f453..4880fbe 100644 --- a/pages-game/game/minesweeper/play.scss +++ b/pages-game/game/minesweeper/play.scss @@ -990,16 +990,11 @@ border: 1px solid $border-dark; // 确保格子始终保持正方形 aspect-ratio: 1 / 1; - // 阻止长按缩放 - touch-action: none; + // 防止双击缩放 + touch-action: manipulation; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; - // 额外的防护 - -webkit-tap-highlight-color: transparent; - outline: none; - // 禁用任何手势 - overscroll-behavior: none; } .grid-cell { @@ -1014,16 +1009,11 @@ aspect-ratio: 1 / 1; width: 100%; height: auto; - // 阻止长按弹出菜单和缩放 - touch-action: none; + // 防止双击缩放和长按菜单 + touch-action: manipulation; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; - // 额外的防护 - -webkit-tap-highlight-color: transparent; - outline: none; - // 禁用任何手势 - overscroll-behavior: none; &:active { transform: scale(0.95); diff --git a/pages-game/game/minesweeper/play.vue b/pages-game/game/minesweeper/play.vue index e41d245..b7caf3f 100644 --- a/pages-game/game/minesweeper/play.vue +++ b/pages-game/game/minesweeper/play.vue @@ -82,7 +82,7 @@ - + Round {{ gameState.globalTurnCount || gameState.round || 0 }} @@ -170,9 +170,7 @@ } ]" @tap="handleCellClick(i)" - @touchstart="handleCellTouchStart(i, $event)" - @touchend="handleCellTouchEnd($event)" - @touchmove="handleCellTouchMove($event)" + catchtap="handleCellCatchTap(i)" > 💣 @@ -345,7 +343,8 @@ export default { onlineCount: 0, onlineCountInterval: null, spectatorFlags: {}, // 观察者模式的旗帜标记 { cellIndex: true } - longPressTimer: null, // 长按定时器 + lastTapTime: 0, // 上次点击时间,用于检测双击 + lastTapIndex: -1, // 上次点击的格子索引 // Timers matchInterval: null, turnInterval: null, @@ -884,11 +883,27 @@ export default { this.addLog('system', '已切断匹配信号'); }, handleCellClick(idx) { - // 前置条件检查 + // 观察者模式:双击插旗 if (this.isSpectator) { - // 观察者模式:不处理普通点击,只处理长按 + const now = Date.now(); + const timeDiff = now - this.lastTapTime; + const isSameCell = this.lastTapIndex === idx; + + // 检测双击:时间间隔小于 300ms 且是同一个格子 + if (isSameCell && timeDiff < 300) { + // 这是双击,切换旗帜 + this.handleCellLongPress(idx); + this.lastTapTime = 0; + this.lastTapIndex = -1; + } else { + // 这是单击,记录状态 + this.lastTapTime = now; + this.lastTapIndex = idx; + } return; } + + // 普通玩家模式 if (!this.gameState?.gameStarted) { uni.showToast({ title: '游戏尚未开始', icon: 'none' }); return; @@ -903,9 +918,15 @@ export default { // 发送移动指令 nakamaManager.sendMatchState(this.matchId, 3, JSON.stringify({ index: idx })); }, - // 观察者模式:长按插旗 + // 微信小程序专用:捕获点击事件并阻止默认行为 + handleCellCatchTap(idx) { + // 在微信小程序中,catchtap 会阻止事件冒泡和默认行为 + // 这里不需要做任何处理,事件会继续传递给 @tap + // 关键是 catchtap 会阻止双击缩放等默认行为 + }, + // 观察者模式:双击插旗 handleCellLongPress(idx) { - // 只有观察者才能长按插旗 + // 只有观察者才能插旗 if (!this.isSpectator) return; if (!this.gameState?.grid) return; if (this.gameState.grid[idx].revealed) return; @@ -917,53 +938,11 @@ export default { } else { this.$set(this.spectatorFlags, idx, true); this.addLog('system', `🚩 在位置 ${idx} 插上了旗帜`); - } - }, - // 触摸开始 - 用于检测长按 - handleCellTouchStart(idx, event) { - // 只有观察者才处理长按插旗 - if (!this.isSpectator) return; - // 阻止默认行为,防止长按弹出菜单(仅观察者) - if (event) { - event.preventDefault(); - event.stopPropagation(); - } - - // 清除之前的定时器 - if (this.longPressTimer) { - clearTimeout(this.longPressTimer); - } - - // 设置长按定时器(800ms) - this.longPressTimer = setTimeout(() => { // 添加震动反馈 // #ifndef MP-ALIPAY uni.vibrateShort(); // #endif - this.handleCellLongPress(idx); - this.longPressTimer = null; - }, 800); - }, - // 触摸结束 - 取消长按 - handleCellTouchEnd(event) { - // 只有观察者需要处理 - if (!this.isSpectator) return; - - if (this.longPressTimer) { - clearTimeout(this.longPressTimer); - this.longPressTimer = null; - } - }, - // 触摸移动 - 取消长按 - handleCellTouchMove(event) { - // 只有观察者需要处理 - if (!this.isSpectator) return; - - // 如果手指移动了,取消长按 - if (this.longPressTimer) { - clearTimeout(this.longPressTimer); - this.longPressTimer = null; } }, refreshAndPlayAgain() { @@ -986,12 +965,6 @@ export default { clearInterval(this.turnInterval); clearInterval(this.onlineCountInterval); - // 清理长按定时器 - if (this.longPressTimer) { - clearTimeout(this.longPressTimer); - this.longPressTimer = null; - } - nakamaManager.disconnect(); }, async fetchOnlineCount() { diff --git a/pages.json b/pages.json index 364925c..5e99261 100644 --- a/pages.json +++ b/pages.json @@ -185,7 +185,11 @@ "navigationBarTitleText": "扫雷对战", "disableScroll": true, "mp-weixin": { - "disableSwipeBack": true + "disableSwipeBack": true, + "enablePullDownRefresh": false, + "disableShareMenu": true, + "disableScroll": true, + "disableScale": true }, "h5": { "titleNView": false