Browse Source

join game table render

master
tangmingyou 4 years ago
parent
commit
e6a939b107
  1. 2167
      src/api/proto.js
  2. 10
      src/api/websocket.js
  3. 8
      src/api/wsapi.js
  4. 12
      src/components/card.jsx
  5. 38
      src/pages/lobby/lobby.jsx
  6. 5
      src/pages/new_table/new_table.jsx
  7. 271
      src/pages/table/table.jsx
  8. 4
      src/utils/application.js
  9. 12
      src/utils/validator.js

2167
src/api/proto.js

File diff suppressed because it is too large Load Diff

10
src/api/websocket.js

@ -50,14 +50,14 @@ const websocket = {
console.log('res msg:', res) console.log('res msg:', res)
if (wrap.seq !== 0) { if (wrap.seq !== 0) {
// 对应请求callback // 对应请求callback
const waitCall = this.waitCall[wrap.seq]; const caller = this.waitCall[wrap.seq];
delete this.waitCall[wrap.seq]; delete this.waitCall[wrap.seq];
// console.log(waitCall, this.waitCall); // console.log(waitCall, this.waitCall);
if (waitCall) { if (caller) {
if (wrap.op === opFail) { if (wrap.op === opFail) {
waitCall.onFail(res, wrap); caller.onFail(res, wrap);
} else { } else {
waitCall.onRes(res, wrap); caller.onRes(res, wrap);
} }
return; return;
} }
@ -98,7 +98,7 @@ const websocket = {
this.waitCall[wrap.seq] = { this.waitCall[wrap.seq] = {
seq: wrap.seq, seq: wrap.seq,
onRes: resCall, onRes: resCall,
onError: errCall, onFail: errCall,
} }
} }
// 定时检查是否超时... // 定时检查是否超时...

8
src/api/wsapi.js

@ -1,3 +1,11 @@
import { sendPromise } from './websocket' import { sendPromise } from './websocket'
import { api } from './proto'
export const aa = msg => sendPromise(msg) export const aa = msg => sendPromise(msg)
// 大厅桌面预览
export const reqLobbyView = () => sendPromise(api.ReqLobbyView.create());
export const reqGameFullStatus = () => sendPromise(api.ReqGameFullStatus.create({}));
export const reqJoinTable = tableNo => sendPromise(api.ReqJoinTable.create({tableNo}));

12
src/components/card.jsx

@ -12,7 +12,17 @@ import cardBack1 from '@/assets/card-back-1.svg'
import cardBack2 from '@/assets/card-back-2.svg' import cardBack2 from '@/assets/card-back-2.svg'
import cardBack3 from '@/assets/card-back-3.svg' import cardBack3 from '@/assets/card-back-3.svg'
const suits = [suit0Icon, suit1Icon, suit2Icon, suit3Icon]; const suits = {
0: suit0Icon,
1: suit1Icon,
2: suit2Icon,
3: suit3Icon,
D: suit0Icon,
C: suit1Icon,
H: suit2Icon,
S: suit3Icon,
};
const dots = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]; const dots = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"];
function Card(props) { function Card(props) {

38
src/pages/lobby/lobby.jsx

@ -5,10 +5,10 @@ import Taro from '@tarojs/taro'
import { useSelector, useDispatch } from 'react-redux' import { useSelector, useDispatch } from 'react-redux'
import './lobby.scss' import './lobby.scss'
import { navigateTo } from '@/utils/application' import { navigateTo, redirectTo, showToast } from '@/utils/application'
import { increment } from '@/store/index' import { increment } from '@/store/index'
import { fetchOpMap, fetchLobbyView } from '@/api/api' import { fetchOpMap, fetchLobbyView } from '@/api/api'
import { sendPromise } from '@/api/websocket' import { reqLobbyView, reqJoinTable } from '@/api/wsapi'
import proto from '@/api/proto' import proto from '@/api/proto'
import Title from '@/components/title' import Title from '@/components/title'
import coin1 from '@/assets/coin-1.png' import coin1 from '@/assets/coin-1.png'
@ -30,14 +30,16 @@ class Lobby extends Component {
} }
componentDidMount() { componentDidMount() {
sendPromise(ReqLobbyView.create()) setTimeout(() => {
.then(res => { reqLobbyView()
console.log('lobby res:', res) .then(res => {
this.setState({tables: res.tables}) console.log('lobby res:', res)
}) this.setState({tables: res.tables})
.catch(err => { })
console.log('lobby err:', err) .catch(err => {
}) console.log('lobby err:', err)
})
}, 1500)
// fetchLobbyView() // fetchLobbyView()
// .then(res => { // .then(res => {
@ -49,11 +51,21 @@ class Lobby extends Component {
// }) // })
} }
async handleJoinTable(table) {
try {
const res = await reqJoinTable(table.tableNo)
redirectTo({url: '/pages/table/table'})
// console.log('join res...', res)
}catch(err) {
showToast({title: err})
}
}
render() { render() {
// const count = useSelector((state) => state.counter.value) // const count = useSelector((state) => state.counter.value)
// const user = useSelector((state) => state.user) // const user = useSelector((state) => state.user)
console.log('state', this.state) // console.log('state', this.state)
return ( return (
<View> <View>
<Title title={"Lobby!!"} bgColor={true} /> <Title title={"Lobby!!"} bgColor={true} />
@ -61,7 +73,7 @@ class Lobby extends Component {
<View className="tab"> <View className="tab">
{ {
this.state.tables.map((table, i) => ( this.state.tables.map((table, i) => (
<View key={table.TableNo} className="tab-wrap" onClick={() => {console.log('join', table)}}> <View key={table.tableNo} className="tab-wrap" onClick={this.handleJoinTable.bind(this, table)}>
<View className="circle-wrap"> <View className="circle-wrap">
<View className="circle-inner"><Image className="inner-coin" src={coin1} /></View> <View className="circle-inner"><Image className="inner-coin" src={coin1} /></View>
{ {
@ -87,7 +99,7 @@ class Lobby extends Component {
)) ))
} }
<View className="tab-wrap"></View> <View key="tab-wrap" className="tab-wrap"></View>
</View> </View>
<View className="bottom-btn-wrap"> <View className="bottom-btn-wrap">
<Button className="bottom-btn" onClick={() => navigateTo({url: '/pages/new_table/new_table'})}>Create New Table</Button> <Button className="bottom-btn" onClick={() => navigateTo({url: '/pages/new_table/new_table'})}>Create New Table</Button>

5
src/pages/new_table/new_table.jsx

@ -3,6 +3,7 @@ import { View, Text, Image, Button } from '@tarojs/components'
import { Popup, Picker } from '@nutui/nutui-react-taro'; import { Popup, Picker } from '@nutui/nutui-react-taro';
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import { redirectTo } from '@/utils/application'
import './new_table.scss' import './new_table.scss'
import Title from '@/components/title' import Title from '@/components/title'
import { sendPromise } from '@/api/websocket' import { sendPromise } from '@/api/websocket'
@ -38,8 +39,8 @@ function NewTable() {
robots: players.filter(type => type === 2).length robots: players.filter(type => type === 2).length
}) })
try { try {
const res = await sendPromise(req) const _ = await sendPromise(req)
console.log('finish', res) redirectTo({url: '/pages/table/table'})
}catch(err) { }catch(err) {
showToast({title: err}) showToast({title: err})
} finally { } finally {

271
src/pages/table/table.jsx

@ -1,8 +1,11 @@
import React, { Component, useState } from 'react' import React, { Component, useState } from 'react'
import { View, Text, Image, Input, Button } from '@tarojs/components' import { View, Text, Image, Input, Button } from '@tarojs/components'
import { useSelector } from 'react-redux' import { connect } from 'react-redux'
import cnames from 'classnames' import cnames from 'classnames'
import { reqGameFullStatus } from '@/api/wsapi'
import { ifEmpty } from '@/utils/validator'
import './table.scss' import './table.scss'
import Title from '@/components/title' import Title from '@/components/title'
import Card from '@/components/card' import Card from '@/components/card'
@ -11,6 +14,7 @@ import coin2Icon from '@/assets/icon/coin-2.svg'
import plus1Icon from '@/assets/icon/plus-1.svg' import plus1Icon from '@/assets/icon/plus-1.svg'
import sub1Icon from '@/assets/icon/sub-1.svg' import sub1Icon from '@/assets/icon/sub-1.svg'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { showToast } from '@/utils/application'
function PlayerStatus() { function PlayerStatus() {
return ( return (
@ -20,129 +24,180 @@ function PlayerStatus() {
) )
} }
function Table() { function cardDot(card, cardBackCode) {
if (!card || !card.suit) {
return cardBackCode;
}
return card['dot'];
}
const { username, nickname, avatar } = useSelector(state => state.user); function cardSuit(card) {
return card.suit || 'D';
}
const players = [1, 2, 3, 4, 5, 6]; class Table extends Component {
const playerRows = players.reduce((arr, item, idx) => { constructor(props) {
const row = parseInt(idx / 2); super(props)
let rowArr = arr[row] || []; this.state = {
rowArr[idx % 2] = { index: idx, item }; inGame: false,
arr[row] = rowArr; tableNo: 0,
parseInt() stage: 0, // : 1;2;3;4;5,;6,,7
return arr; chip: 0,
}, []); RoundTimes: 0,
return ( players: [],
<View className="tab"> publicCard: [],
<Title title="GAME" /> }
{ }
playerRows.map((row, i) => ( componentDidMount() {
<View key={i} className="playerRow"> console.log('table mount')
{ setTimeout(() => {
row.map((player, j) => ( reqGameFullStatus()
<View key={j} className="player-wrap"> .then(res => {
{ this.setState({
j % 2 === 0 && inGame: !!res.inGame,
<View className={cnames('player-state-wrap', {'state-left': j % 2 === 0})}> tableNo: res.tableNo,
<PlayerStatus action={1} /> stage: res.gameStage,
</View> chip: res.chip || 0,
} RoundTimes: res.RoundTimes || 0,
<View className="player-bar">
<View className={cnames("player-no", { "player-no-running": player.index === 0 })}><Text>#{player.index}</Text></View> players: res.players,
<View className="card1"><Card w={38} h={48} dot={-1} suit={2} /></View> publicCard: res.publicCard,
<View className="card2"><Card w={38} h={48} dot={-1} suit={3} /></View> })
<View className={cnames("player", {'player-wait': player.index !== 0})}> console.log('res game', res, res.publicCard[0].dot, ifEmpty(res.publicCard[0].dot, -3))
<View className="avatar-wrap"><Image className="avatar" src={avatar} /></View> window.publicCard = res.publicCard
<View className="player-name"><Text>Player{player.item}</Text></View> })
</View> .catch(err => {
<View className="wallet-wrap"> showToast({title: err})
<View className={cnames("wallet", {'wallet-wait': player.index !== 0})}> })
<View className="wallet-icon"><Image className="wallet-icon-img" src={coinIcon} /></View> }, 2000)
<View className="wallet-amount"><Text>3,000,000</Text></View> }
render() {
const { username, nickname, avatar } = this.props.user; // useSelector(state => state.user);
// const players = [1, 2, 3, 4, 5, 6];
const playerRows = this.state.players.reduce((arr, player, idx) => {
const row = parseInt(idx / 2);
let rowArr = arr[row] || [];
rowArr[idx % 2] = { index: idx, player };
arr[row] = rowArr;
return arr;
}, []);
return (
<View className="tab">
<Title title="GAME" />
{
playerRows.map((row, i) => (
<View key={i} className="playerRow">
{
row.map((player, j) => (
<View key={j} className="player-wrap">
{
j % 2 === 0 &&
<View className={cnames('player-state-wrap', {'state-left': j % 2 === 0})}>
<PlayerStatus action={1} />
</View>
}
<View className="player-bar">
<View className={cnames("player-no", { "player-no-running": player.index === 0 })}><Text>#{player.index}</Text></View>
<View className="card1"><Card w={38} h={48} dot={-1} suit={2} /></View>
<View className="card2"><Card w={38} h={48} dot={-1} suit={3} /></View>
<View className={cnames("player", {'player-wait': player.index !== 0})}>
<View className="avatar-wrap"><Image className="avatar" src={avatar} /></View>
<View className="player-name"><Text>Player{player.item}</Text></View>
</View>
<View className="wallet-wrap">
<View className={cnames("wallet", {'wallet-wait': player.index !== 0})}>
<View className="wallet-icon"><Image className="wallet-icon-img" src={coinIcon} /></View>
<View className="wallet-amount"><Text>3,000,000</Text></View>
</View>
<View className="pct"><Text>25%</Text></View>
</View> </View>
<View className="pct"><Text>25%</Text></View>
</View> </View>
</View> </View>
</View> ))
)) }
} </View>
</View> ))
)) }
} <View className="desktop-box">
<View className="desktop-box"> <View className="desktop-wrap">
<View className="desktop-wrap"> <View className="desktop-cards">
<View className="desktop-cards"> {
{ this.state.publicCard.map((card, i) => (
[1, 2, 3, -3, -3].map((item, i) => ( <Card key={i} w={38} h={48} dot={cardDot(card, -3)} suit={cardSuit(card)} />
<Card key={i} w={38} h={48} dot={item} suit={2} /> ))
)) }
} </View>
</View> <View className="desktop-wallet">
<View className="desktop-wallet"> <View className="d-wallet-icon">
<View className="d-wallet-icon"> <Image className="d-wallet-icon-img" src={coinIcon} />
<Image className="d-wallet-icon-img" src={coinIcon} /> <Text className="d-wallet-icon-text">POT</Text>
<Text className="d-wallet-icon-text">POT</Text> </View>
<View className="d-wallet-amount">22,088,000</View>
</View> </View>
<View className="d-wallet-amount">22,088,000</View>
</View> </View>
{/* <View className="chatbox" style={{ display: 'none' }}>
<View className='chat-window'>
<View className="line">Kelly(#1)进入了游戏</View>
<View className="line">Apollo(#2)进入了游戏</View>
</View>
<View className='chat-panel'>
<View><Input name="chat" type="text" placeholder="" /></View>
<View><Button>OK</Button></View>
</View>
</View> */}
</View> </View>
{/* <View className="chatbox" style={{ display: 'none' }}>
<View className='chat-window'>
<View className="line">Kelly(#1)进入了游戏</View>
<View className="line">Apollo(#2)进入了游戏</View>
</View>
<View className='chat-panel'>
<View><Input name="chat" type="text" placeholder="" /></View>
<View><Button>OK</Button></View>
</View>
</View> */}
</View>
<View className="self-box"> <View className="self-box">
<View className="self-wrap"> <View className="self-wrap">
<View className={cnames("player-no", { "player-no-running": true })}><Text>#7</Text></View> <View className={cnames("player-no", { "player-no-running": true })}><Text>#7</Text></View>
<View className="hand-card1"><Card w={38} h={48} dot={12} suit={3} /></View> <View className="hand-card1"><Card w={38} h={48} dot={12} suit={3} /></View>
<View className="hand-card2"><Card w={38} h={48} dot={12} suit={3} /></View> <View className="hand-card2"><Card w={38} h={48} dot={12} suit={3} /></View>
<View className="hand-five"> <View className="hand-five">
{ {
[1, 2, 3, 4, 5].map((_, i) => ( [1, 2, 3, 4, 5].map((_, i) => (
<View key={i} className="hand-five-item"><Card w={28} h={36} dot={12} suit={2} /></View> <View key={i} className="hand-five-item"><Card w={28} h={36} dot={12} suit={2} /></View>
)) ))
} }
</View>
<View className='u-opt' style={{ display: 'flex' }}>
<View>
<View className="s-info-wrap">
<View className="s-avatar"><Image className="s-avatar-img" src={avatar} /></View>
<View className="s-username"><Text>Prometheus</Text></View>
</View>
<View className="s-wallet-wrap">
<View className="s-w-amount-wrap">
<View className="s-w-amount-icon"><Image className="s-w-amount-icon-img" src={coin2Icon} /></View>
<View className="s-w-amount"><Text>3,000,000</Text></View>
</View>
<View className="s-w-pct"><Text>0%</Text></View>
</View>
</View> </View>
<View className="control"> <View className='u-opt' style={{ display: 'flex' }}>
<View className="ctl-opt-wrap"> <View>
<View className="amount-input"><Input placeholder='your chip' defaultValue={0} /></View> <View className="s-info-wrap">
<View className="amount-sub"><Image className="amount-sub-icon" src={sub1Icon} /></View> <View className="s-avatar"><Image className="s-avatar-img" src={avatar} /></View>
<View className="amount-plus"><Image className="amount-plus-icon" src={plus1Icon} /></View> <View className="s-username"><Text>Prometheus</Text></View>
</View>
<View className="s-wallet-wrap">
<View className="s-w-amount-wrap">
<View className="s-w-amount-icon"><Image className="s-w-amount-icon-img" src={coin2Icon} /></View>
<View className="s-w-amount"><Text>3,000,000</Text></View>
</View>
<View className="s-w-pct"><Text>0%</Text></View>
</View>
</View> </View>
<View className="ctl-opt-wrap" style={{ marginTop: Taro.pxTransform(10) }}> <View className="control">
<View className="ctl-opt"><Button className="ctl-opt-btn-1">让牌</Button></View> <View className="ctl-opt-wrap">
<View className="ctl-opt"><Button className="ctl-opt-btn-2">弃牌</Button></View> <View className="amount-input"><Input placeholder='your chip' defaultValue={0} /></View>
<View className="ctl-opt"><Button className="ctl-opt-btn-3">跟注</Button></View> <View className="amount-sub"><Image className="amount-sub-icon" src={sub1Icon} /></View>
<View className="amount-plus"><Image className="amount-plus-icon" src={plus1Icon} /></View>
</View>
<View className="ctl-opt-wrap" style={{ marginTop: Taro.pxTransform(10) }}>
<View className="ctl-opt"><Button className="ctl-opt-btn-1">让牌</Button></View>
<View className="ctl-opt"><Button className="ctl-opt-btn-2">弃牌</Button></View>
<View className="ctl-opt"><Button className="ctl-opt-btn-3">跟注</Button></View>
</View>
</View> </View>
</View> </View>
</View> </View>
</View> </View>
</View> </View>
</View> )
) }
}
function mapStateToProps(state) {
return {user: state.user}
} }
export default Table export default connect(mapStateToProps)(Table)

4
src/utils/application.js

@ -54,7 +54,7 @@ export const navigateBack = function(option = {delta: 1}) {
return Taro.navigateBack(option); return Taro.navigateBack(option);
} }
export const showToast = function(option = {icon: 'success'}) { export const showToast = function(option = {title: '', icon: 'none'}) {
let {title} = option let {title} = option
if (!title) { return } if (!title) { return }
title = typeof(title) === 'string' ? title : title.msg || title.message; title = typeof(title) === 'string' ? title : title.msg || title.message;
@ -62,5 +62,7 @@ export const showToast = function(option = {icon: 'success'}) {
console.log('no title toast:', option.title) console.log('no title toast:', option.title)
return return
} }
option.title = title
option.icon = option.icon || 'none';
Taro.showToast(option) Taro.showToast(option)
} }

12
src/utils/validator.js

@ -0,0 +1,12 @@
// 判断数据是否为空
export const isEmpty = data => {
return data === undefined || data === null || data === '' ||
(Array.isArray(data) && data.length === 0) ||
(typeof data === 'object' && Object.keys(data).length === 0);
}
// 如果数据为空, 则使用默认值
export const ifEmpty = (data, defaultValue) => {
return isEmpty(data) ? defaultValue : data;
}
Loading…
Cancel
Save