246 lines
6.4 KiB
Vue
246 lines
6.4 KiB
Vue
<template>
|
|
<div class="game-container container">
|
|
<div class="game-player-info">
|
|
<div class="users">
|
|
<span v-for="user in users"> {{user.nick_name}}: {{user.counter}}</span>
|
|
</div>
|
|
<div class="join">
|
|
{{joinMsg}}
|
|
</div>
|
|
</div>
|
|
<div class="game-body">
|
|
<div class="pot">pot: {{pot}}</div>
|
|
<div class="common-card">commonCard:{{commonCardString}}</div>
|
|
<div class="hand-card">handCard:{{handCardString}}</div>
|
|
<div class="action">
|
|
<div class="action-type btn" v-show="isAction">
|
|
<span @click="action('check')">check</span>
|
|
<span @click="action('fold')">fold</span>
|
|
<span @click="action('call')">call</span>
|
|
<span @click="action('raise')">raise</span>
|
|
</div>
|
|
<div class="raise-size" v-show="isRaise">
|
|
<i @click="raise(pot / 3)">1/3 pot</i>
|
|
<i @click="raise(pot / 2)">1/2 pot</i>
|
|
<i @click="raise(pot / 4)">3/4 pot</i>
|
|
<i @click="raise(pot)">1 pot</i>
|
|
<i @click="raise(pot * 2)">2 pot</i>
|
|
<i @click="raise(pot * 3)">3 pot</i>
|
|
<i @click="raise(-1)">allin</i>
|
|
</div>
|
|
</div>
|
|
<div class="btn play"><span @click="play">play game</span></div>
|
|
</div>
|
|
<div class="buy-in">
|
|
<div class="input-bd">
|
|
<div class="input-name">buy in:</div>
|
|
<div class="input-text">
|
|
<input type="text"
|
|
v-model="buyInSize"/>
|
|
</div>
|
|
</div>
|
|
<div class="btn"><span @click="buyIn">buy in</span></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import {Vue} from 'vue-property-decorator';
|
|
import Component from 'vue-class-component';
|
|
import io from 'socket.io-client';
|
|
import cookie from 'js-cookie';
|
|
import service from '../service';
|
|
|
|
interface IUser {
|
|
counter: number;
|
|
nick_name: string;
|
|
actionSize: number;
|
|
type: string;
|
|
userId?: number;
|
|
}
|
|
|
|
export enum ECommand {
|
|
CALL = 'call',
|
|
ALL_IN = 'allin',
|
|
RAISE = 'raise',
|
|
CHECK = 'check',
|
|
FOLD = 'fold',
|
|
}
|
|
|
|
interface IMsg {
|
|
action: string;
|
|
clients: string[];
|
|
target: string;
|
|
data: any;
|
|
}
|
|
|
|
@Component
|
|
export default class Game extends Vue {
|
|
public socket: any = null;
|
|
private users: IUser[] = [];
|
|
private userInfo: any = {};
|
|
private joinMsg = '';
|
|
private handCard = [];
|
|
private commonCard = [];
|
|
private buyInSize = 0;
|
|
private pot = 0;
|
|
private prevSize = 0;
|
|
private isAction = false;
|
|
private isRaise = false;
|
|
|
|
get roomId() {
|
|
return this.$route.params.roomNumber;
|
|
}
|
|
|
|
get commonCardString() {
|
|
const cardNumber = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A'];
|
|
const color = ['♦', '♣', '♥', '♠'];
|
|
return this.commonCard.map((c: string) => {
|
|
const cNumber = c.charCodeAt(0) - 97;
|
|
const cColor = Number(c[1]) - 1;
|
|
return `${cardNumber[cNumber]}${color[cColor]}`;
|
|
});
|
|
}
|
|
|
|
get handCardString() {
|
|
const cardNumber = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A'];
|
|
const color = ['♦', '♣', '♥', '♠'];
|
|
return this.handCard.map((c: string) => {
|
|
const cNumber = c.charCodeAt(0) - 97;
|
|
const cColor = Number(c[1]) - 1;
|
|
return `${cardNumber[cNumber]}${color[cColor]}`;
|
|
});
|
|
}
|
|
|
|
private raise(size: number) {
|
|
if (size === -1) {
|
|
size = this.userInfo.counter;
|
|
}
|
|
this.emit('action', { command: `raise:${size}` });
|
|
}
|
|
|
|
private action(type: string) {
|
|
this.isAction = false;
|
|
if (type === ECommand.RAISE) {
|
|
this.isRaise = true;
|
|
}
|
|
}
|
|
|
|
private socketInit() {
|
|
const token = cookie.get('token');
|
|
const log = console.log;
|
|
// const origin = 'http://172.22.72.70:7001';
|
|
const origin = 'http://192.168.0.105:7001';
|
|
this.socket = io(`${origin}/socket`, {
|
|
// 实际使用中可以在这里传递参数
|
|
query: {
|
|
room: this.roomId,
|
|
token,
|
|
},
|
|
transports: ['websocket'],
|
|
});
|
|
this.socket.on('connect', () => {
|
|
const id: string = this.socket.id;
|
|
|
|
log('#connect,', id, this.socket);
|
|
|
|
// 监听自身 id 以实现 p2p 通讯
|
|
this.socket.on(id, (msg: any) => {
|
|
log('#receive,', msg);
|
|
const data = msg.data;
|
|
if (data.action === 'handCard') {
|
|
this.handCard = data.payload.handCard;
|
|
}
|
|
if (data.action === 'userInfo') {
|
|
this.userInfo = data.payload;
|
|
}
|
|
});
|
|
});
|
|
|
|
// 接收在线用户信息
|
|
this.socket.on('online', (msg: IMsg) => {
|
|
log('#online,', msg);
|
|
if (msg.action === 'join') {
|
|
this.joinMsg = msg.data;
|
|
}
|
|
if (msg.action === 'players') {
|
|
this.users = msg.data.players;
|
|
}
|
|
if (msg.action === 'commonCard') {
|
|
this.commonCard = msg.data.commonCard;
|
|
console.log('users', msg.data);
|
|
}
|
|
if (msg.action === 'gameInfo') {
|
|
this.users = msg.data.players;
|
|
this.pot = msg.data.pot;
|
|
this.prevSize = msg.data.prevSize;
|
|
this.isAction = !!(this.userInfo && this.userInfo.userId === msg.data.currPlayer.userId);
|
|
console.log('gameInfo', msg.data);
|
|
}
|
|
});
|
|
|
|
// 系统事件
|
|
this.socket.on('disconnect', (msg: IMsg) => {
|
|
log('#disconnect', msg);
|
|
});
|
|
|
|
this.socket.on('disconnecting', () => {
|
|
log('#disconnecting');
|
|
});
|
|
|
|
this.socket.on('error', () => {
|
|
log('#error');
|
|
});
|
|
}
|
|
|
|
private async buyIn() {
|
|
try {
|
|
this.emit('buyIn', {
|
|
buyInSize: this.buyInSize,
|
|
});
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
}
|
|
|
|
private play() {
|
|
console.log('play');
|
|
this.emit('playGame');
|
|
}
|
|
|
|
private emit(eventType: string, data: any = {}) {
|
|
this.socket.emit(eventType, {
|
|
target: '',
|
|
payload: {
|
|
...data,
|
|
},
|
|
});
|
|
}
|
|
|
|
private mounted() {
|
|
this.socketInit();
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="less"
|
|
scoped>
|
|
.game-container {
|
|
.raise-size{
|
|
i{
|
|
padding: 5px;
|
|
width: 30px;
|
|
height: 30px;
|
|
display: inline-block;
|
|
font-style: normal;
|
|
font-size: 12px;
|
|
line-height: 30px;
|
|
border-radius: 50%;
|
|
border: 1px solid #bababa;
|
|
margin: 10px;
|
|
vertical-align: middle;
|
|
}
|
|
}
|
|
}
|
|
</style>
|