update
This commit is contained in:
@@ -27,8 +27,12 @@ const {
|
||||
leaveRoomPending,
|
||||
canStartGame,
|
||||
seatViews,
|
||||
selectedTile,
|
||||
actionButtons,
|
||||
connectWs,
|
||||
sendStartGame,
|
||||
selectTile,
|
||||
sendGameAction,
|
||||
backHall,
|
||||
} = useChengduGameRoom(route, router)
|
||||
|
||||
@@ -129,7 +133,7 @@ const seatDecor = computed<Record<SeatKey, SeatPlayerCardModel>>(() => {
|
||||
const score = scoreMap[playerId]
|
||||
result[seat.key] = {
|
||||
avatar: seat.isSelf ? '我' : String(index + 1),
|
||||
name: seat.isSelf ? '你自己' : playerId,
|
||||
name: seat.isSelf ? '你自己' : seat.player.displayName || `玩家${seat.player.index + 1}`,
|
||||
money: typeof score === 'number' ? String(score) : '--',
|
||||
dealer: seat.player.index === dealerIndex,
|
||||
isTurn: seat.isTurn,
|
||||
@@ -170,6 +174,23 @@ const centerTimer = computed(() => {
|
||||
: '等待中'
|
||||
})
|
||||
|
||||
const pendingClaimText = computed(() => {
|
||||
const claim = roomState.value.game?.state?.pendingClaim
|
||||
if (!claim) {
|
||||
return '无'
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.stringify(claim)
|
||||
} catch {
|
||||
return '存在响应窗口'
|
||||
}
|
||||
})
|
||||
|
||||
const selectedTileText = computed(() => {
|
||||
return selectedTile.value ?? '未选择'
|
||||
})
|
||||
|
||||
function missingSuitLabel(value: string | null | undefined): string {
|
||||
if (!value) {
|
||||
return '未定'
|
||||
@@ -270,6 +291,51 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="table-panel game-table-panel action-panel">
|
||||
<div class="action-grid">
|
||||
<div class="action-card">
|
||||
<h3>我的手牌</h3>
|
||||
<p class="action-hint">当前仅渲染 `my_hand` 事件下发的真实手牌。</p>
|
||||
<div class="hand-wall" v-if="roomState.myHand.length > 0">
|
||||
<button
|
||||
v-for="(tile, index) in roomState.myHand"
|
||||
:key="`${tile}-${index}`"
|
||||
class="tile-chip"
|
||||
type="button"
|
||||
:class="{ selected: selectedTile === tile }"
|
||||
@click="selectTile(tile)"
|
||||
>
|
||||
{{ tile }}
|
||||
</button>
|
||||
</div>
|
||||
<p v-else class="action-empty">尚未收到 `my_hand`。</p>
|
||||
<p class="action-meta">已选牌:{{ selectedTileText }}</p>
|
||||
</div>
|
||||
|
||||
<div class="action-card">
|
||||
<h3>对局动作</h3>
|
||||
<p class="action-hint">已接入 `draw / discard / peng / gang / hu / pass` WS 发包。</p>
|
||||
<div class="action-buttons">
|
||||
<button
|
||||
v-for="action in actionButtons"
|
||||
:key="action.type"
|
||||
class="primary-btn action-btn"
|
||||
type="button"
|
||||
:disabled="action.disabled"
|
||||
@click="sendGameAction(action.type)"
|
||||
>
|
||||
{{ action.label }}
|
||||
</button>
|
||||
</div>
|
||||
<p class="action-meta">当前响应窗口:{{ pendingClaimText }}</p>
|
||||
<p class="action-meta">
|
||||
最近弃牌:{{ roomState.game?.state?.lastDiscardTile || '无' }}
|
||||
/ {{ roomState.game?.state?.lastDiscardBy || '无' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="table-shell">
|
||||
<img class="table-desk" :src="deskImage" alt="" />
|
||||
<div class="table-felt">
|
||||
@@ -345,3 +411,69 @@ onBeforeUnmount(() => {
|
||||
</section>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.action-panel {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.action-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.action-card {
|
||||
background: rgba(10, 27, 22, 0.72);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.action-card h3 {
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
.action-hint,
|
||||
.action-meta,
|
||||
.action-empty {
|
||||
margin: 8px 0 0;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.hand-wall,
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.tile-chip {
|
||||
min-width: 56px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
background: rgba(247, 239, 220, 0.9);
|
||||
color: #1c1b18;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tile-chip.selected {
|
||||
transform: translateY(-4px);
|
||||
border-color: #f4c76a;
|
||||
box-shadow: 0 10px 24px rgba(244, 199, 106, 0.25);
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
min-width: 88px;
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
.action-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user