feat(chat): 完善五子棋功能,包含AI对战、PvP邀请、断线重连及界面美化
This commit is contained in:
@@ -735,6 +735,112 @@
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', setupChangelogPublishedListener);
|
||||
|
||||
// ── 五子棋 PvP 邀请通知(聊天室内显示「接受挑战」按钮)───────
|
||||
/**
|
||||
* 监听 .gomoku.invite 事件,在聊天窗口追加邀请消息行。
|
||||
* 发起者收到的邀请(自己发出的)不显示接受按钮。
|
||||
*/
|
||||
function setupGomokuInviteListener() {
|
||||
if (!window.Echo || !window.chatContext) {
|
||||
setTimeout(setupGomokuInviteListener, 500);
|
||||
return;
|
||||
}
|
||||
window.Echo.join(`room.${window.chatContext.roomId}`)
|
||||
.listen('.gomoku.invite', (e) => {
|
||||
const now = new Date();
|
||||
const timeStr = now.getHours().toString().padStart(2, '0') + ':' +
|
||||
now.getMinutes().toString().padStart(2, '0') + ':' +
|
||||
now.getSeconds().toString().padStart(2, '0');
|
||||
|
||||
const isSelf = (e.inviter_name === window.chatContext.username);
|
||||
const div = document.createElement('div');
|
||||
div.className = 'msg-line';
|
||||
div.style.cssText =
|
||||
'background:linear-gradient(135deg,#e8eef8,#f0f4fc); ' +
|
||||
'border-left:3px solid #336699; border-radius:4px; padding:6px 10px; margin:3px 0;';
|
||||
|
||||
const acceptBtn = isSelf ?
|
||||
// 自己的邀请:只显示打开面板按钮,方便被关掉后重新进入
|
||||
`<button onclick="document.querySelector('[x-data=\"gomokuPanel()\"]').__x.$data.open()"
|
||||
style="margin-left:10px; padding:3px 12px; border:1.5px solid #2d6096;
|
||||
border-radius:12px; background:#f0f6ff; color:#2d6096; font-size:12px;
|
||||
cursor:pointer; font-family:inherit; transition:all .15s;"
|
||||
onmouseover="this.style.background='#ddeeff'" onmouseout="this.style.background='#f0f6ff'">
|
||||
⤴️ 打开面板
|
||||
</button>` :
|
||||
// 别人的邀请:显示接受挑战按钮
|
||||
`<button onclick="acceptGomokuInvite(${e.game_id})" id="gomoku-accept-${e.game_id}"
|
||||
style="margin-left:10px; padding:3px 12px; border:1.5px solid #336699;
|
||||
border-radius:12px; background:#336699; color:#fff; font-size:12px;
|
||||
cursor:pointer; font-family:inherit; transition:all .15s;"
|
||||
onmouseover="this.style.opacity='.8'" onmouseout="this.style.opacity='1'">
|
||||
⚔️ 接受挑战
|
||||
</button>`;
|
||||
|
||||
div.innerHTML = `<span style="color:#1e3a5f; font-weight:bold;">
|
||||
♟️ 【五子棋】<b>${e.inviter_name}</b> 发起了随机对战!${isSelf ? '(等待中)' : ''}
|
||||
</span>${acceptBtn}
|
||||
<span class="msg-time">(${timeStr})</span>`;
|
||||
|
||||
// 追加到公聊窗口
|
||||
const say1 = document.getElementById('chat-messages-container');
|
||||
if (say1) {
|
||||
say1.appendChild(div);
|
||||
say1.scrollTop = say1.scrollHeight;
|
||||
}
|
||||
|
||||
// 60 秒后移除接受按钮(邀请超时)
|
||||
if (!isSelf) {
|
||||
setTimeout(() => {
|
||||
const btn = document.getElementById(`gomoku-accept-${e.game_id}`);
|
||||
if (btn) {
|
||||
btn.textContent = '已超时';
|
||||
btn.disabled = true;
|
||||
btn.style.opacity = '.5';
|
||||
btn.style.cursor = 'not-allowed';
|
||||
}
|
||||
}, 60000);
|
||||
}
|
||||
})
|
||||
.listen('.gomoku.finished', (e) => {
|
||||
// 对局结束:在公聊展示战报(仅 PvP 有战报意义)
|
||||
if (e.mode !== 'pvp') return;
|
||||
const now = new Date();
|
||||
const timeStr = now.getHours().toString().padStart(2, '0') + ':' +
|
||||
now.getMinutes().toString().padStart(2, '0') + ':' +
|
||||
now.getSeconds().toString().padStart(2, '0');
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.className = 'msg-line';
|
||||
div.style.cssText =
|
||||
'background:#fffae8; border-left:3px solid #d97706; border-radius:4px; padding:5px 10px; margin:2px 0;';
|
||||
|
||||
const reason = {
|
||||
win: '获胜',
|
||||
draw: '平局',
|
||||
resign: '认输',
|
||||
timeout: '超时'
|
||||
} [e.reason] || '结束';
|
||||
let text = '';
|
||||
if (e.winner === 0) {
|
||||
text = `♟️ 五子棋对局以<b>平局</b>结束!`;
|
||||
} else {
|
||||
text =
|
||||
`♟️ <b>${e.winner_name}</b> 击败 <b>${e.loser_name}</b>(${reason})获得 <b style="color:#b45309;">${e.reward_gold}</b> 金币!`;
|
||||
}
|
||||
|
||||
div.innerHTML =
|
||||
`<span style="color:#92400e;">${text}</span><span class="msg-time">(${timeStr})</span>`;
|
||||
const say1 = document.getElementById('chat-messages-container');
|
||||
if (say1) {
|
||||
say1.appendChild(div);
|
||||
say1.scrollTop = say1.scrollHeight;
|
||||
}
|
||||
});
|
||||
console.log('[五子棋] 邀请监听器已注册');
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', setupGomokuInviteListener);
|
||||
|
||||
// ── 全屏特效事件监听(烟花/下雨/雷电/下雪)─────────
|
||||
window.addEventListener('chat:effect', (e) => {
|
||||
const type = e.detail?.type;
|
||||
|
||||
Reference in New Issue
Block a user