From 5a12e92765560f7cfa926177c8c98ff6061de7a7 Mon Sep 17 00:00:00 2001 From: tangmingyou <234767776@qq.com> Date: Mon, 6 Feb 2023 18:02:25 +0800 Subject: [PATCH] big small blind render --- src/api/api.js | 2 + src/api/proto.js | 83 ++++++++++++++++++++++++--- src/api/websocket.js | 10 ++-- src/assets/icon/big_blind.svg | 1 + src/assets/icon/crown.svg | 1 + src/assets/icon/crown_dark.svg | 1 + src/assets/icon/small_blind.svg | 1 + src/assets/icon/time-fill.svg | 1 + src/pages/lobby/lobby.jsx | 1 - src/pages/login/login.jsx | 8 +-- src/pages/table/table.jsx | 99 ++++++++++++++++++++++++++++++--- src/pages/table/table.scss | 96 +++++++++++++++++++++++++++++--- 12 files changed, 269 insertions(+), 35 deletions(-) create mode 100644 src/assets/icon/big_blind.svg create mode 100644 src/assets/icon/crown.svg create mode 100644 src/assets/icon/crown_dark.svg create mode 100644 src/assets/icon/small_blind.svg create mode 100644 src/assets/icon/time-fill.svg diff --git a/src/api/api.js b/src/api/api.js index d8182c1..d4f385a 100644 --- a/src/api/api.js +++ b/src/api/api.js @@ -5,3 +5,5 @@ export const doLogin = params => post('/api/auth/authorize', params) export const fetchOpMap = () => get('/api/conn/opMap') export const fetchLobbyView = () => get('/api/game/lobby') + +export const fetchRouteWs = () => get('/api/conn/route_ws') diff --git a/src/api/proto.js b/src/api/proto.js index 36731a7..2388094 100644 --- a/src/api/proto.js +++ b/src/api/proto.js @@ -4772,6 +4772,8 @@ export const api = $root.api = (() => { * @property {number|null} [chip] ResGameFullStatus chip * @property {number|null} [roundTimes] ResGameFullStatus roundTimes * @property {number|Long|null} [playerId] ResGameFullStatus playerId + * @property {number|null} [bigBlindPos] ResGameFullStatus bigBlindPos + * @property {number|null} [smallBlindPos] ResGameFullStatus smallBlindPos * @property {Array.|null} [publicCard] ResGameFullStatus publicCard * @property {Array.|null} [players] ResGameFullStatus players */ @@ -4841,6 +4843,22 @@ export const api = $root.api = (() => { */ ResGameFullStatus.prototype.playerId = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + /** + * ResGameFullStatus bigBlindPos. + * @member {number} bigBlindPos + * @memberof api.ResGameFullStatus + * @instance + */ + ResGameFullStatus.prototype.bigBlindPos = 0; + + /** + * ResGameFullStatus smallBlindPos. + * @member {number} smallBlindPos + * @memberof api.ResGameFullStatus + * @instance + */ + ResGameFullStatus.prototype.smallBlindPos = 0; + /** * ResGameFullStatus publicCard. * @member {Array.} publicCard @@ -4893,12 +4911,16 @@ export const api = $root.api = (() => { writer.uint32(/* id 5, wireType 0 =*/40).int32(message.roundTimes); if (message.playerId != null && Object.hasOwnProperty.call(message, "playerId")) writer.uint32(/* id 6, wireType 0 =*/48).int64(message.playerId); + if (message.bigBlindPos != null && Object.hasOwnProperty.call(message, "bigBlindPos")) + writer.uint32(/* id 7, wireType 0 =*/56).int32(message.bigBlindPos); + if (message.smallBlindPos != null && Object.hasOwnProperty.call(message, "smallBlindPos")) + writer.uint32(/* id 8, wireType 0 =*/64).int32(message.smallBlindPos); if (message.publicCard != null && message.publicCard.length) for (let i = 0; i < message.publicCard.length; ++i) - $root.api.Card.encode(message.publicCard[i], writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim(); + $root.api.Card.encode(message.publicCard[i], writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim(); if (message.players != null && message.players.length) for (let i = 0; i < message.players.length; ++i) - $root.api.TablePlayer.encode(message.players[i], writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim(); + $root.api.TablePlayer.encode(message.players[i], writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); return writer; }; @@ -4957,13 +4979,21 @@ export const api = $root.api = (() => { message.playerId = reader.int64(); break; } - case 9: { + case 7: { + message.bigBlindPos = reader.int32(); + break; + } + case 8: { + message.smallBlindPos = reader.int32(); + break; + } + case 14: { if (!(message.publicCard && message.publicCard.length)) message.publicCard = []; message.publicCard.push($root.api.Card.decode(reader, reader.uint32())); break; } - case 10: { + case 15: { if (!(message.players && message.players.length)) message.players = []; message.players.push($root.api.TablePlayer.decode(reader, reader.uint32())); @@ -5022,6 +5052,12 @@ export const api = $root.api = (() => { if (message.playerId != null && message.hasOwnProperty("playerId")) if (!$util.isInteger(message.playerId) && !(message.playerId && $util.isInteger(message.playerId.low) && $util.isInteger(message.playerId.high))) return "playerId: integer|Long expected"; + if (message.bigBlindPos != null && message.hasOwnProperty("bigBlindPos")) + if (!$util.isInteger(message.bigBlindPos)) + return "bigBlindPos: integer expected"; + if (message.smallBlindPos != null && message.hasOwnProperty("smallBlindPos")) + if (!$util.isInteger(message.smallBlindPos)) + return "smallBlindPos: integer expected"; if (message.publicCard != null && message.hasOwnProperty("publicCard")) { if (!Array.isArray(message.publicCard)) return "publicCard: array expected"; @@ -5074,6 +5110,10 @@ export const api = $root.api = (() => { message.playerId = object.playerId; else if (typeof object.playerId === "object") message.playerId = new $util.LongBits(object.playerId.low >>> 0, object.playerId.high >>> 0).toNumber(); + if (object.bigBlindPos != null) + message.bigBlindPos = object.bigBlindPos | 0; + if (object.smallBlindPos != null) + message.smallBlindPos = object.smallBlindPos | 0; if (object.publicCard) { if (!Array.isArray(object.publicCard)) throw TypeError(".api.ResGameFullStatus.publicCard: array expected"); @@ -5125,6 +5165,8 @@ export const api = $root.api = (() => { object.playerId = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; } else object.playerId = options.longs === String ? "0" : 0; + object.bigBlindPos = 0; + object.smallBlindPos = 0; } if (message.inGame != null && message.hasOwnProperty("inGame")) object.inGame = message.inGame; @@ -5141,6 +5183,10 @@ export const api = $root.api = (() => { object.playerId = options.longs === String ? String(message.playerId) : message.playerId; else object.playerId = options.longs === String ? $util.Long.prototype.toString.call(message.playerId) : options.longs === Number ? new $util.LongBits(message.playerId.low >>> 0, message.playerId.high >>> 0).toNumber() : message.playerId; + if (message.bigBlindPos != null && message.hasOwnProperty("bigBlindPos")) + object.bigBlindPos = message.bigBlindPos; + if (message.smallBlindPos != null && message.hasOwnProperty("smallBlindPos")) + object.smallBlindPos = message.smallBlindPos; if (message.publicCard && message.publicCard.length) { object.publicCard = []; for (let j = 0; j < message.publicCard.length; ++j) @@ -5195,6 +5241,7 @@ export const api = $root.api = (() => { * @property {string|null} [avatar] TablePlayer avatar * @property {number|null} [chip] TablePlayer chip * @property {number|null} [status] TablePlayer status + * @property {number|null} [lastStatus] TablePlayer lastStatus * @property {boolean|null} [master] TablePlayer master * @property {Array.|null} [handCard] TablePlayer handCard */ @@ -5263,6 +5310,14 @@ export const api = $root.api = (() => { */ TablePlayer.prototype.status = 0; + /** + * TablePlayer lastStatus. + * @member {number} lastStatus + * @memberof api.TablePlayer + * @instance + */ + TablePlayer.prototype.lastStatus = 0; + /** * TablePlayer master. * @member {boolean} master @@ -5315,11 +5370,13 @@ export const api = $root.api = (() => { writer.uint32(/* id 5, wireType 0 =*/40).int32(message.chip); if (message.status != null && Object.hasOwnProperty.call(message, "status")) writer.uint32(/* id 6, wireType 0 =*/48).int32(message.status); + if (message.lastStatus != null && Object.hasOwnProperty.call(message, "lastStatus")) + writer.uint32(/* id 7, wireType 0 =*/56).int32(message.lastStatus); if (message.master != null && Object.hasOwnProperty.call(message, "master")) - writer.uint32(/* id 7, wireType 0 =*/56).bool(message.master); + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.master); if (message.handCard != null && message.handCard.length) for (let i = 0; i < message.handCard.length; ++i) - $root.api.Card.encode(message.handCard[i], writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim(); + $root.api.Card.encode(message.handCard[i], writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim(); return writer; }; @@ -5379,10 +5436,14 @@ export const api = $root.api = (() => { break; } case 7: { - message.master = reader.bool(); + message.lastStatus = reader.int32(); break; } case 8: { + message.master = reader.bool(); + break; + } + case 15: { if (!(message.handCard && message.handCard.length)) message.handCard = []; message.handCard.push($root.api.Card.decode(reader, reader.uint32())); @@ -5441,6 +5502,9 @@ export const api = $root.api = (() => { if (message.status != null && message.hasOwnProperty("status")) if (!$util.isInteger(message.status)) return "status: integer expected"; + if (message.lastStatus != null && message.hasOwnProperty("lastStatus")) + if (!$util.isInteger(message.lastStatus)) + return "lastStatus: integer expected"; if (message.master != null && message.hasOwnProperty("master")) if (typeof message.master !== "boolean") return "master: boolean expected"; @@ -5487,6 +5551,8 @@ export const api = $root.api = (() => { message.chip = object.chip | 0; if (object.status != null) message.status = object.status | 0; + if (object.lastStatus != null) + message.lastStatus = object.lastStatus | 0; if (object.master != null) message.master = Boolean(object.master); if (object.handCard) { @@ -5528,6 +5594,7 @@ export const api = $root.api = (() => { object.avatar = ""; object.chip = 0; object.status = 0; + object.lastStatus = 0; object.master = false; } if (message.robot != null && message.hasOwnProperty("robot")) @@ -5545,6 +5612,8 @@ export const api = $root.api = (() => { object.chip = message.chip; if (message.status != null && message.hasOwnProperty("status")) object.status = message.status; + if (message.lastStatus != null && message.hasOwnProperty("lastStatus")) + object.lastStatus = message.lastStatus; if (message.master != null && message.hasOwnProperty("master")) object.master = message.master; if (message.handCard && message.handCard.length) { diff --git a/src/api/websocket.js b/src/api/websocket.js index 6f1307d..fe16a83 100644 --- a/src/api/websocket.js +++ b/src/api/websocket.js @@ -1,7 +1,7 @@ import store from '@/store/index' import proto from '@/api/proto'; -import { fetchOpMap } from '@/api/api' +import { fetchOpMap, fetchRouteWs } from '@/api/api' import { getStorage, removeStorage } from '@/utils/storage'; import { showToast } from '@/utils/application'; import { setUserInfo } from '@/store/user' @@ -20,7 +20,7 @@ const websocket = { // 消息监听列表 msgListener: {}, // {op: func} waitInitCalls: [], - init(token, { offset, opFail, opSuccess, opPathMap, nameOpMap }) { + init(token, { offset, opFail, opSuccess, opPathMap, nameOpMap }, { wsAddr }) { // TODO 连接状态判定 this.offset = offset || 0; @@ -30,7 +30,7 @@ const websocket = { this.nameOpMap = nameOpMap || {}; // window.proto = proto; - const ws = new WebSocket("ws://localhost:9999/api/conn/ws") + const ws = new WebSocket(`ws://${wsAddr}/api/conn/ws`) this.conn = ws console.log(this) ws.binaryType = 'arraybuffer' @@ -184,8 +184,8 @@ export const sendPromise = function(msg) { return; } // console.log('token', token) - const opMap = await fetchOpMap() - websocket.init(token, opMap.data) + const [opMap, wsRes] = await Promise.all([fetchOpMap(), fetchRouteWs()]); + websocket.init(token, opMap.data, wsRes.data); window.websocket = websocket; })() diff --git a/src/assets/icon/big_blind.svg b/src/assets/icon/big_blind.svg new file mode 100644 index 0000000..d55d689 --- /dev/null +++ b/src/assets/icon/big_blind.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icon/crown.svg b/src/assets/icon/crown.svg new file mode 100644 index 0000000..99276e6 --- /dev/null +++ b/src/assets/icon/crown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icon/crown_dark.svg b/src/assets/icon/crown_dark.svg new file mode 100644 index 0000000..c27de30 --- /dev/null +++ b/src/assets/icon/crown_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icon/small_blind.svg b/src/assets/icon/small_blind.svg new file mode 100644 index 0000000..ff6d005 --- /dev/null +++ b/src/assets/icon/small_blind.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icon/time-fill.svg b/src/assets/icon/time-fill.svg new file mode 100644 index 0000000..a744f9d --- /dev/null +++ b/src/assets/icon/time-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/pages/lobby/lobby.jsx b/src/pages/lobby/lobby.jsx index 2604f61..3f73b43 100644 --- a/src/pages/lobby/lobby.jsx +++ b/src/pages/lobby/lobby.jsx @@ -7,7 +7,6 @@ import { useSelector, useDispatch } from 'react-redux' import './lobby.scss' import { navigateTo, redirectTo, showToast } from '@/utils/application' import { increment } from '@/store/index' -import { fetchOpMap, fetchLobbyView } from '@/api/api' import { reqLobbyView, reqJoinTable } from '@/api/wsapi' import proto from '@/api/proto' import Title from '@/components/title' diff --git a/src/pages/login/login.jsx b/src/pages/login/login.jsx index 3e36e34..b954641 100644 --- a/src/pages/login/login.jsx +++ b/src/pages/login/login.jsx @@ -5,7 +5,7 @@ import Taro from '@tarojs/taro'; //import { Form, Input, TextArea, Cell, Button, Row, Col, Image } from '@nutui/nutui-react-taro'; import ws from '@/api/websocket' import './login.scss' -import { doLogin, fetchOpMap } from '@/api/api' +import { doLogin, fetchOpMap, fetchRouteWs } from '@/api/api' import { redirectTo, showToast } from '@/utils/application' import iconUser from '@/assets/icon/user-3-fill.svg' import iconLock from '@/assets/icon/lock-2-fill.svg' @@ -33,10 +33,10 @@ function Login() { //const token = "AgOjcdf3goeYDX3lwWWwkXtVpcrL-l2rX8csrRKgs3_-BC3JOx0l6nZU0MV25eIn" try { - const [tokenRes, opMapRes] = await Promise.all([doLogin(state), fetchOpMap()]); - setStorage('_t', tokenRes.data.token) + const [tokenRes, opMapRes, wsRes] = await Promise.all([doLogin(state), fetchOpMap(), fetchRouteWs()]); + setStorage('_t', tokenRes.data.token); // 初始化 websocket 连接 - ws.init(tokenRes.data.token, opMapRes.data); + ws.init(tokenRes.data.token, opMapRes.data, wsRes.data); showToast({title: '登录成功', duration: 800}); // 重定向到大厅 setTimeout(() => redirectTo({url: '/pages/lobby/lobby'}), 800); diff --git a/src/pages/table/table.jsx b/src/pages/table/table.jsx index 03d271e..d3e1d85 100644 --- a/src/pages/table/table.jsx +++ b/src/pages/table/table.jsx @@ -20,6 +20,12 @@ import plus1Icon from '@/assets/icon/plus-1.svg' import sub1Icon from '@/assets/icon/sub-1.svg' import closeIcon from '@/assets/icon/close-1.svg' +import timeIcon from '@/assets/icon/time-fill.svg' +import crownIcon from '@/assets/icon/crown.svg' +import crownDarkIcon from '@/assets/icon/crown_dark.svg' +import bigBlindIcon from '@/assets/icon/big_blind.svg' +import smallBlindIcon from '@/assets/icon/small_blind.svg' + import Taro from '@tarojs/taro' import { showToast, redirectTo } from '@/utils/application' import { isIn } from '@/utils/collect' @@ -59,6 +65,9 @@ class Table extends Component { chip: 0, roundTimes: 0, playerId: 0, + masterId: 0, + bigBlindPos: -1, + smallBlindPos: -1, players: [], publicCard: [], @@ -84,7 +93,15 @@ class Table extends Component { addMsgListen('api.ResDismissGameTable', res => { showToast({title: '牌桌已解散'}); setTimeout(() => redirectTo({url: '/pages/lobby/lobby'}), 800); - }) + }); + // 扣除大盲注(显示3秒) + addMsgListen('api.ResBigBlindChip', res => { + showToast({title: '大盲注:' + res.chip}); + }); + // 扣除小盲注(显示3秒) + addMsgListen('api.ResSmallBlindChip', res => { + showToast({title: '小盲注:' + res.chip}); + }); // 查询当前牌桌状态 reqGameFullStatus() @@ -108,6 +125,9 @@ class Table extends Component { stage: res.gameStage, chip: res.chip || 0, roundTimes: res.roundTimes || 0, + masterId: res.masterId, + bigBlindPos: res.bigBlindPos, + smallBlindPos: res.smallBlindPos, players: res.players, publicCard: res.publicCard, @@ -195,7 +215,7 @@ class Table extends Component { const { username, nickname, avatar, defaultAvatar } = this.props.user; // useSelector(state => state.user); // const players = [1, 2, 3, 4, 5, 6]; const players = this.state.players.map((player, index) => ({player, index})); - const {playerId, tableNo, stage, chip, roundTimes} = this.state; + const {inGame, playerId, tableNo, stage, bigBlindPos, smallBlindPos, chip, roundTimes} = this.state; // 从玩家中找到自己 TODO 弄到 state, 避免每次render计算 // console.log('props', this.props); @@ -225,20 +245,52 @@ class Table extends Component { player.status === 2 && Ready! } - 1})}>#{index} { + // 座位编号 + !player.id ? null : + player.master + ? + + #{index+1} + + : #{index+1} + } + { + // 大小盲注图标 + !player.id ? null : !(inGame && isIn(index, bigBlindPos, smallBlindPos)) ? null + : + } + { + // 等待读秒,下注金额 + !inGame ? null : !isIn(player.status,4,6) ? null : + + { + // TODO All In ... + j%2 === 0 + ? + + 29 + + : 99})}>+{player.chip} + } + + } + { + // 踢出牌桌close图标 stage === 1 && selfPlayer.master && player.id ? : null } - {existsCard(player.handCard[0]) && } - {existsCard(player.handCard[1]) && } - + {/* 玩家手牌 */} + {existsCard(selfPlayer.handCard[0]) && } + {existsCard(selfPlayer.handCard[0]) && } + {/* 头像名称 */} {!player.id ? null : } {player.username} { + // 玩家筹码 !player.id ? null : @@ -286,9 +338,38 @@ class Table extends Component { - #{selfIndex} + { + // + selfPlayer.master + ? + + #{selfIndex+1} + + : #{selfIndex+1} + } + + { + // 大小盲注图标 + !(inGame && isIn(selfIndex, bigBlindPos, smallBlindPos)) ? null + : + } + { + // 等待读秒,下注金额 + + { + // TODO All In ... + true + ? + + 29 + + : +{selfPlayer.chip} + // , {'filling-chip-l': selfPlayer.chip > 99} + } + + } {existsCard(selfPlayer.handCard[0]) && } - {existsCard(selfPlayer.handCard[1]) && } + {existsCard(selfPlayer.handCard[1]) && } { existsCard(selfPlayer.handCard[0]) && [1, 2, 3, 4, 5].map((_, i) => ( @@ -296,7 +377,7 @@ class Table extends Component { )) } - + diff --git a/src/pages/table/table.scss b/src/pages/table/table.scss index c23b634..d8ce6c2 100644 --- a/src/pages/table/table.scss +++ b/src/pages/table/table.scss @@ -22,25 +22,103 @@ font-weight: bold; font-size: 12px; } - .player-no { + .player-no,.player-no-crown { position: absolute; - top: -25px; - color: #fff; + top: -26px; + color: #EE914E; font-size: 14px; - height: 23px; - width: 23px; - line-height: 23px; - background-color: #807878; + height: 24px; + width: 24px; + line-height: 24px; border-radius: 50%; text-align: center; + font-weight: bold; + } + .player-no { + background-color: #D8D8D8; } - .player-no-running { font-weight: bold; color: #fff; background-color: #EE914E; } + .player-no-crown { + line-height: 28px; + color: #EE914E; + } + .pnc-bg-icon { + position: absolute; + z-index: -1; + top: 0; + left: 0; + height: 24px; + width: auto; + } + .pnc-text-running { + color: #fff; + } + + .blind-icon { + position: absolute; + left: 110px; + top: 25px; + width: 48px; + height: 48px; + } + .blind-icon-self { + left: -2px; + top: -2px; + z-index: 1; + } + + .round-wrap-l,.round-wrap-r { + position: absolute; + top: 8px; + left: 154px; + width: 36px; + height: 60px; + display: flex; + flex-direction: column; + justify-content: space-evenly; + align-items: center; + } + .round-wrap-r { + left: -40px; + } + .round-wrap-self { + top: -66px; + // left: 21px; + left: 0px; + z-index: 2; + } + .time-wrap { + color: #1BCE7D; + font-weight: bold; + text-align: center; + line-height: 10px; + } + .time-icon { + width: 36px; + height: 36px; + } + .time-wrap-self { + margin-top: -46px; + margin-left: -15px; + line-height: 14px; + } + .filling-chip { + font-size: 18px; + font-weight: bold; + color: #EE914E; + } + .filling-chip-l { + margin-left: -10px; + } + .filling-chip-self { + color: #FF4400; + margin-top: -10px; + } .kickout { position: absolute; z-index: 99; @@ -76,7 +154,7 @@ // line-height: 114px; display: flex; // padding: 10px 4px; - border: 1px solid #000; + // border: 1px solid #000; border-radius: 5px; }