feat 小程序模式下禁止缩放棋盘
This commit is contained in:
parent
5691d0601d
commit
96555e690c
@ -990,16 +990,11 @@
|
|||||||
border: 1px solid $border-dark;
|
border: 1px solid $border-dark;
|
||||||
// 确保格子始终保持正方形
|
// 确保格子始终保持正方形
|
||||||
aspect-ratio: 1 / 1;
|
aspect-ratio: 1 / 1;
|
||||||
// 阻止长按缩放
|
// 防止双击缩放
|
||||||
touch-action: none;
|
touch-action: manipulation;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
// 额外的防护
|
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
outline: none;
|
|
||||||
// 禁用任何手势
|
|
||||||
overscroll-behavior: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-cell {
|
.grid-cell {
|
||||||
@ -1014,16 +1009,11 @@
|
|||||||
aspect-ratio: 1 / 1;
|
aspect-ratio: 1 / 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
// 阻止长按弹出菜单和缩放
|
// 防止双击缩放和长按菜单
|
||||||
touch-action: none;
|
touch-action: manipulation;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
// 额外的防护
|
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
outline: none;
|
|
||||||
// 禁用任何手势
|
|
||||||
overscroll-behavior: none;
|
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
|
|||||||
@ -82,7 +82,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 游戏主界面 -->
|
<!-- 游戏主界面 -->
|
||||||
<view v-else class="game-screen">
|
<view v-else class="game-screen" :class="{ 'spectator-mode': isSpectator }">
|
||||||
<!-- 顶部状态栏 -->
|
<!-- 顶部状态栏 -->
|
||||||
<view class="game-header">
|
<view class="game-header">
|
||||||
<view class="round-badge">Round {{ gameState.globalTurnCount || gameState.round || 0 }}</view>
|
<view class="round-badge">Round {{ gameState.globalTurnCount || gameState.round || 0 }}</view>
|
||||||
@ -170,9 +170,7 @@
|
|||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
@tap="handleCellClick(i)"
|
@tap="handleCellClick(i)"
|
||||||
@touchstart="handleCellTouchStart(i, $event)"
|
catchtap="handleCellCatchTap(i)"
|
||||||
@touchend="handleCellTouchEnd($event)"
|
|
||||||
@touchmove="handleCellTouchMove($event)"
|
|
||||||
>
|
>
|
||||||
<view v-if="cell.revealed">
|
<view v-if="cell.revealed">
|
||||||
<text v-if="cell.type === 'bomb'" class="cell-icon">💣</text>
|
<text v-if="cell.type === 'bomb'" class="cell-icon">💣</text>
|
||||||
@ -345,7 +343,8 @@ export default {
|
|||||||
onlineCount: 0,
|
onlineCount: 0,
|
||||||
onlineCountInterval: null,
|
onlineCountInterval: null,
|
||||||
spectatorFlags: {}, // 观察者模式的旗帜标记 { cellIndex: true }
|
spectatorFlags: {}, // 观察者模式的旗帜标记 { cellIndex: true }
|
||||||
longPressTimer: null, // 长按定时器
|
lastTapTime: 0, // 上次点击时间,用于检测双击
|
||||||
|
lastTapIndex: -1, // 上次点击的格子索引
|
||||||
// Timers
|
// Timers
|
||||||
matchInterval: null,
|
matchInterval: null,
|
||||||
turnInterval: null,
|
turnInterval: null,
|
||||||
@ -884,11 +883,27 @@ export default {
|
|||||||
this.addLog('system', '已切断匹配信号');
|
this.addLog('system', '已切断匹配信号');
|
||||||
},
|
},
|
||||||
handleCellClick(idx) {
|
handleCellClick(idx) {
|
||||||
// 前置条件检查
|
// 观察者模式:双击插旗
|
||||||
if (this.isSpectator) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 普通玩家模式
|
||||||
if (!this.gameState?.gameStarted) {
|
if (!this.gameState?.gameStarted) {
|
||||||
uni.showToast({ title: '游戏尚未开始', icon: 'none' });
|
uni.showToast({ title: '游戏尚未开始', icon: 'none' });
|
||||||
return;
|
return;
|
||||||
@ -903,9 +918,15 @@ export default {
|
|||||||
// 发送移动指令
|
// 发送移动指令
|
||||||
nakamaManager.sendMatchState(this.matchId, 3, JSON.stringify({ index: idx }));
|
nakamaManager.sendMatchState(this.matchId, 3, JSON.stringify({ index: idx }));
|
||||||
},
|
},
|
||||||
// 观察者模式:长按插旗
|
// 微信小程序专用:捕获点击事件并阻止默认行为
|
||||||
|
handleCellCatchTap(idx) {
|
||||||
|
// 在微信小程序中,catchtap 会阻止事件冒泡和默认行为
|
||||||
|
// 这里不需要做任何处理,事件会继续传递给 @tap
|
||||||
|
// 关键是 catchtap 会阻止双击缩放等默认行为
|
||||||
|
},
|
||||||
|
// 观察者模式:双击插旗
|
||||||
handleCellLongPress(idx) {
|
handleCellLongPress(idx) {
|
||||||
// 只有观察者才能长按插旗
|
// 只有观察者才能插旗
|
||||||
if (!this.isSpectator) return;
|
if (!this.isSpectator) return;
|
||||||
if (!this.gameState?.grid) return;
|
if (!this.gameState?.grid) return;
|
||||||
if (this.gameState.grid[idx].revealed) return;
|
if (this.gameState.grid[idx].revealed) return;
|
||||||
@ -917,53 +938,11 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.$set(this.spectatorFlags, idx, true);
|
this.$set(this.spectatorFlags, idx, true);
|
||||||
this.addLog('system', `🚩 在位置 ${idx} 插上了旗帜`);
|
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
|
// #ifndef MP-ALIPAY
|
||||||
uni.vibrateShort();
|
uni.vibrateShort();
|
||||||
// #endif
|
// #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() {
|
refreshAndPlayAgain() {
|
||||||
@ -986,12 +965,6 @@ export default {
|
|||||||
clearInterval(this.turnInterval);
|
clearInterval(this.turnInterval);
|
||||||
clearInterval(this.onlineCountInterval);
|
clearInterval(this.onlineCountInterval);
|
||||||
|
|
||||||
// 清理长按定时器
|
|
||||||
if (this.longPressTimer) {
|
|
||||||
clearTimeout(this.longPressTimer);
|
|
||||||
this.longPressTimer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
nakamaManager.disconnect();
|
nakamaManager.disconnect();
|
||||||
},
|
},
|
||||||
async fetchOnlineCount() {
|
async fetchOnlineCount() {
|
||||||
|
|||||||
@ -185,7 +185,11 @@
|
|||||||
"navigationBarTitleText": "扫雷对战",
|
"navigationBarTitleText": "扫雷对战",
|
||||||
"disableScroll": true,
|
"disableScroll": true,
|
||||||
"mp-weixin": {
|
"mp-weixin": {
|
||||||
"disableSwipeBack": true
|
"disableSwipeBack": true,
|
||||||
|
"enablePullDownRefresh": false,
|
||||||
|
"disableShareMenu": true,
|
||||||
|
"disableScroll": true,
|
||||||
|
"disableScale": true
|
||||||
},
|
},
|
||||||
"h5": {
|
"h5": {
|
||||||
"titleNView": false
|
"titleNView": false
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user