feat(game): 实现出牌选择与计时功能
- 添加 PlayerTurnPayload 接口定义和 PLAYER_TURN 动作类型 - 实现选牌、出牌确认逻辑和相关状态管理 - 添加客户端出牌限制检查和错误提示 - 集成 PLAYER_TURN WebSocket 消息处理 - 添加房间状态面板显示游戏信息 - 优化桌面背景图片和样式布局 - 添加马蹄形动画样式文件 - 配置 Vite 别名和端口设置
This commit is contained in:
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
BIN
src/assets/images/desk/desk_01_1920_945.png
Normal file
BIN
src/assets/images/desk/desk_01_1920_945.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1006 KiB |
@@ -1,8 +1,7 @@
|
||||
.picture-scene {
|
||||
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
padding: 18px;
|
||||
padding: 0;
|
||||
background:
|
||||
radial-gradient(circle at top, rgba(116, 58, 41, 0.28), transparent 20%),
|
||||
linear-gradient(180deg, #3f2119 0%, #27140f 100%);
|
||||
@@ -10,44 +9,51 @@
|
||||
|
||||
.picture-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 320px;
|
||||
gap: 18px;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 0;
|
||||
align-items: stretch;
|
||||
min-height: calc(100vh - 36px);
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
}
|
||||
|
||||
.table-stage {
|
||||
.picture-scene .table-stage {
|
||||
position: relative;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
align-content: start;
|
||||
align-content: stretch;
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 36px);
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-desk,
|
||||
.table-felt {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
max-height: calc(100dvh - 72px);
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
|
||||
.table-desk {
|
||||
grid-area: 1 / 1;
|
||||
.picture-scene .table-desk {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: block;
|
||||
margin-top: 18px;
|
||||
border-radius: 26px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 24px 44px rgba(0, 0, 0, 0.34);
|
||||
}
|
||||
|
||||
.table-felt {
|
||||
grid-area: 1 / 1;
|
||||
position: relative;
|
||||
margin-top: 18px;
|
||||
border-radius: 26px;
|
||||
.picture-scene .table-felt {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
aspect-ratio: auto;
|
||||
margin-top: 0;
|
||||
border-radius: 0;
|
||||
overflow: hidden;
|
||||
justify-self: stretch;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.table-surface {
|
||||
@@ -312,10 +318,57 @@
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.action-countdown {
|
||||
.room-status-panel {
|
||||
position: absolute;
|
||||
top: 92px;
|
||||
right: 40px;
|
||||
width: min(320px, calc(100% - 80px));
|
||||
padding: 12px;
|
||||
border: 1px solid rgba(255, 226, 175, 0.12);
|
||||
border-radius: 14px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(45, 24, 18, 0.82), rgba(26, 14, 11, 0.88)),
|
||||
radial-gradient(circle at top, rgba(255, 219, 154, 0.05), transparent 44%);
|
||||
box-shadow: 0 14px 26px rgba(0, 0, 0, 0.22);
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.room-status-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.room-status-item {
|
||||
padding: 10px 12px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.room-status-item span {
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
color: rgba(244, 233, 208, 0.62);
|
||||
}
|
||||
|
||||
.room-status-item strong {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
color: #fff0c2;
|
||||
font-size: 15px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.room-status-error {
|
||||
margin-top: 10px;
|
||||
color: #ffc1c1;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.action-countdown {
|
||||
position: absolute;
|
||||
top: 210px;
|
||||
right: 40px;
|
||||
min-width: 188px;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid rgba(255, 219, 131, 0.22);
|
||||
@@ -713,6 +766,8 @@
|
||||
background: transparent;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
transform: translateY(0);
|
||||
transition: transform 150ms cubic-bezier(0.22, 0.82, 0.32, 1), filter 150ms ease-out;
|
||||
}
|
||||
|
||||
.wall-live-tile-lack-tag {
|
||||
@@ -738,6 +793,21 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wall-live-tile-button:not(:disabled):hover {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.wall-live-tile-button.is-selected {
|
||||
transform: translateY(-18px);
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.wall-live-tile-button.is-selected .wall-live-tile {
|
||||
filter:
|
||||
drop-shadow(0 14px 18px rgba(0, 0, 0, 0.24))
|
||||
drop-shadow(0 0 10px rgba(255, 214, 111, 0.42));
|
||||
}
|
||||
|
||||
.wall-live-tile-button:disabled .wall-live-tile {
|
||||
opacity: 1;
|
||||
filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.18));
|
||||
@@ -1142,6 +1212,18 @@
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.discard-confirm-button {
|
||||
min-width: 168px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(110, 32, 20, 0.94), rgba(72, 16, 9, 0.98)),
|
||||
radial-gradient(circle at 20% 24%, rgba(255, 214, 153, 0.14), transparent 34%);
|
||||
border-color: rgba(255, 184, 112, 0.34);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 232, 205, 0.14),
|
||||
inset 0 -1px 0 rgba(0, 0, 0, 0.28),
|
||||
0 12px 22px rgba(0, 0, 0, 0.26);
|
||||
}
|
||||
|
||||
.hand-action-bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -1357,126 +1439,9 @@
|
||||
background: radial-gradient(circle at 35% 28%, #fff6c2 0%, #ffe16c 42%, #e3aa23 100%);
|
||||
}
|
||||
|
||||
.ws-sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 36px);
|
||||
min-height: calc(100vh - 36px);
|
||||
padding: 16px;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(255, 226, 175, 0.12);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(45, 24, 18, 0.94), rgba(26, 14, 11, 0.96)),
|
||||
radial-gradient(circle at top, rgba(255, 219, 154, 0.06), transparent 40%);
|
||||
box-shadow: 0 16px 28px rgba(0, 0, 0, 0.22);
|
||||
}
|
||||
|
||||
.sidebar-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
color: #ffe2a0;
|
||||
}
|
||||
|
||||
.sidebar-head small {
|
||||
color: rgba(248, 233, 199, 0.68);
|
||||
}
|
||||
|
||||
.sidebar-btn {
|
||||
min-width: 76px;
|
||||
height: 38px;
|
||||
border: 1px solid rgba(255, 223, 164, 0.16);
|
||||
border-radius: 999px;
|
||||
color: #ffe9b7;
|
||||
background: rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
.sidebar-stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.sidebar-stat {
|
||||
padding: 12px;
|
||||
border-radius: 14px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.sidebar-stat span {
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
color: rgba(244, 233, 208, 0.62);
|
||||
}
|
||||
|
||||
.sidebar-stat strong {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
color: #fff0c2;
|
||||
font-size: 15px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.sidebar-error {
|
||||
margin-top: 14px;
|
||||
color: #ffc1c1;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.sidebar-log {
|
||||
flex: 1 1 auto;
|
||||
margin-top: 14px;
|
||||
padding: 12px;
|
||||
border-radius: 14px;
|
||||
background: rgba(9, 12, 19, 0.34);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.sidebar-empty,
|
||||
.sidebar-line {
|
||||
font-size: 12px;
|
||||
color: #e6eef8;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.sidebar-line + .sidebar-line {
|
||||
margin-top: 8px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.picture-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.table-desk,
|
||||
.table-felt {
|
||||
width: min(100%, calc((100dvh - 290px) * 16 / 9));
|
||||
}
|
||||
|
||||
.ws-sidebar {
|
||||
height: auto;
|
||||
min-height: 240px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 980px) {
|
||||
.picture-scene {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.table-desk,
|
||||
.table-felt {
|
||||
width: 100%;
|
||||
margin-top: 8px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wall-right {
|
||||
@@ -1529,14 +1494,15 @@
|
||||
right: 20px;
|
||||
min-width: 164px;
|
||||
}
|
||||
|
||||
.room-status-panel {
|
||||
top: 92px;
|
||||
right: 20px;
|
||||
width: min(300px, calc(100% - 40px));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.table-desk,
|
||||
.table-felt {
|
||||
aspect-ratio: 9 / 16;
|
||||
}
|
||||
|
||||
.inner-outline.mid {
|
||||
inset: 92px 34px 190px;
|
||||
}
|
||||
@@ -1596,8 +1562,23 @@
|
||||
padding: 7px 10px;
|
||||
}
|
||||
|
||||
.room-status-panel {
|
||||
top: 58px;
|
||||
right: 16px;
|
||||
width: calc(100% - 32px);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.room-status-grid {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.room-status-item {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.action-countdown {
|
||||
top: 62px;
|
||||
top: 176px;
|
||||
right: 16px;
|
||||
min-width: 0;
|
||||
width: calc(100% - 32px);
|
||||
|
||||
151
src/assets/styles/windowSquare.css
Normal file
151
src/assets/styles/windowSquare.css
Normal file
@@ -0,0 +1,151 @@
|
||||
.wind-square {
|
||||
position: relative;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
border-radius: 22px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10px 18px rgba(0, 0, 0, 0.28),
|
||||
inset 0 0 0 1px rgba(255, 240, 196, 0.2);
|
||||
}
|
||||
|
||||
.square-base {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
filter: sepia(1) hue-rotate(92deg) saturate(3.3) brightness(0.22);
|
||||
}
|
||||
|
||||
.wind-square::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(circle at 28% 22%, rgba(255, 238, 191, 0.08), transparent 42%),
|
||||
linear-gradient(145deg, rgba(5, 33, 24, 0.34), rgba(0, 0, 0, 0.16));
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* ===== 四个三角形区域 ===== */
|
||||
.quadrant {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
/* 上三角 */
|
||||
.quadrant-top {
|
||||
clip-path: polygon(50% 50%, 0 0, 100% 0);
|
||||
background: radial-gradient(circle at 50% 38%, rgba(255, 225, 180, 0.30), transparent 68%),
|
||||
linear-gradient(to bottom, rgba(180, 95, 55, 0.28), rgba(80, 35, 20, 0.12));
|
||||
}
|
||||
|
||||
/* 右三角 */
|
||||
.quadrant-right {
|
||||
clip-path: polygon(50% 50%, 100% 0, 100% 100%);
|
||||
background: radial-gradient(circle at 62% 50%, rgba(255, 225, 180, 0.30), transparent 68%),
|
||||
linear-gradient(to left, rgba(180, 95, 55, 0.28), rgba(80, 35, 20, 0.12));
|
||||
}
|
||||
|
||||
/* 下三角 */
|
||||
.quadrant-bottom {
|
||||
clip-path: polygon(50% 50%, 0 100%, 100% 100%);
|
||||
background: radial-gradient(circle at 50% 62%, rgba(255, 225, 180, 0.30), transparent 68%),
|
||||
linear-gradient(to top, rgba(180, 95, 55, 0.28), rgba(80, 35, 20, 0.12));
|
||||
}
|
||||
|
||||
/* 左三角 */
|
||||
.quadrant-left {
|
||||
clip-path: polygon(50% 50%, 0 0, 0 100%);
|
||||
background: radial-gradient(circle at 38% 50%, rgba(255, 225, 180, 0.30), transparent 68%),
|
||||
linear-gradient(to right, rgba(180, 95, 55, 0.28), rgba(80, 35, 20, 0.12));
|
||||
}
|
||||
|
||||
/* 激活时闪烁 */
|
||||
.quadrant.active {
|
||||
opacity: 1;
|
||||
animation: quadrant-pulse 1.2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes quadrant-pulse {
|
||||
0% {
|
||||
opacity: 0.22;
|
||||
filter: brightness(0.95);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.72;
|
||||
filter: brightness(1.18);
|
||||
}
|
||||
100% {
|
||||
opacity: 0.22;
|
||||
filter: brightness(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
.diagonal {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 160%;
|
||||
height: 2px;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 0, 0, 0) 0%,
|
||||
rgba(80, 35, 20, 0.6) 25%,
|
||||
rgba(160, 85, 50, 0.9) 50%,
|
||||
rgba(80, 35, 20, 0.6) 75%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
transform-origin: center;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.diagonal-a {
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
}
|
||||
|
||||
.diagonal-b {
|
||||
transform: translate(-50%, -50%) rotate(-45deg);
|
||||
}
|
||||
|
||||
.wind-slot {
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.wind-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
filter: brightness(0) invert(1) drop-shadow(0 0 2px rgba(255, 220, 180, 0.8)) drop-shadow(0 0 4px rgba(120, 60, 30, 0.6));
|
||||
}
|
||||
|
||||
.wind-top {
|
||||
top: 5px;
|
||||
left: 34px;
|
||||
}
|
||||
|
||||
.wind-right {
|
||||
top: 34px;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
.wind-bottom {
|
||||
bottom: 5px;
|
||||
left: 34px;
|
||||
}
|
||||
|
||||
.wind-left {
|
||||
top: 34px;
|
||||
left: 5px;
|
||||
}
|
||||
Reference in New Issue
Block a user