//"服务器, 我想加入XXX号桌子 / 服务器, 帮我快速找一个空位座下吧?"
message TJoinTableReq
{
optional int32 TableIndex = 1; // 需要加入的桌子编号, 不填就快速加入
optional string NickName = 2; // 昵称
optional int32 Cash = 3; // 带入金钱
}
///"好的, 已经安排你做在XXX号桌子. XXX号桌子里面的情况是这样的"
message TJoinTableRsp
{
optional string ErrorMsg = 1;
optional int32 ErrorCode = 2;
}
//"有一个新玩家进来"
// "又有一个新玩家进来"
message TPlayerComeInBc
{
optional int32 Status = 1;
optional TPlayerInfo PlayerInfo = 2;
optional TTableInfo TableInfo = 3;
}
客户端连接以后, 直接发送快速加入(其实就是加入第一个桌子)
顺带发送一下昵称, 不然不好做区分
这里可能需要小幅度修改一下协议, 协议可能和前面几章不同
快速加入的PB大概是这样的, 按照我们的初步规定. 请求快速加入协议是16 , 广播的加入和退出的协议是19
在客户端新增一个Edit输入框
self.Edit1 = vcl.NewEdit(self)
self.Edit1.SetParent(self)
self.Edit1.SetBounds(100, 50, 100, 28)
self.Edit1.SetText("昵称")
修改客户端的点击发送事件 用来模拟发送快速加入
// OnButton2Click 快速加入 按钮点击事件
func (self *TMainForm) OnButton2Click(sender vcl.IObject) {
pack := &ddzpb.TDDZ{}
pack.Command = proto.Int32(16) // 16 快速加入的请求
// 加入桌子的结构体
pack.JoinTableReq = &ddzpb.TJoinTableReq{}
// 在这里放用户昵称
pack.JoinTableReq.NickName = proto.String(self.Edit1.Text())
buff, _ := proto.Marshal(pack)
self.pClient.WritePack(buff)
}
在服务器端做接收处理, 并且进行广播
pServer.OnRead = func(pData *connection.TData) {
//
pack := &ddzpb.TDDZ{}
proto.Unmarshal(pData.GetBuffer(), pack)
log.Println("收到包", pack)
switch pack.GetCommand() {
case 16: // 16 快速加入的请求
req := &ddzpb.TJoinTableReq{}
// 快速加入.
pPlayer := NewPlayer()
pPlayer.strNickName = req.GetNickName()
pPlayer.Conn = pData.GetConnection()
pRoom.QuickJoin(pPlayer)
{
// 拿到玩家的桌子
pTable := pPlayer.pTable
// 拿到玩家的位置
nPos := pPlayer.nPosition
log.Println("位置是", nPos)
rsp := &ddzpb.TPlayerComeInBc{}
if pTable.isFull() {
// 人满
rsp.Status = proto.Int32(1)
} else {
// 未满
rsp.Status = proto.Int32(2)
}
rsp.PlayerInfo = &ddzpb.TPlayerInfo{}
// 昵称
rsp.PlayerInfo.NickName = proto.String(pPlayer.strNickName)
// 位置
rsp.PlayerInfo.Position = proto.Int(pPlayer.nPosition)
// 获取桌子的信息
rsp.TableInfo = pTable.getTableInfoProto()
pack.PlayerComeInBc = rsp
pack.JoinTableRsp = nil
pack.JoinTableReq = nil
pack.Command = proto.Int32(18)
buff, _ := proto.Marshal(pack)
// 广播桌子信息
for _, v := range pTable.pPlayerList {
if v == nil {
continue
}
v.Conn.WritePack(buff)
}
}
}
}
这样当我们开启3个客户端的时候, 大家就能知道房间里的情况了(这里没有做重复处理. 如果一个客户端发 3次..... 哈哈哈)
这样房间坐满了以后就直接开始
客户端收到这个包以后, 把房间内容显示出来
在客户端里面放上三个LABEL
// TMainForm 主窗体
type TMainForm struct {
*vcl.TForm
nTableIndex uint32 // 桌子编号
Btn1 *vcl.TButton
Btn2 *vcl.TButton
Edit1 *vcl.TEdit
Label1 *vcl.TLabel
Label2 *vcl.TLabel
Label3 *vcl.TLabel
pClient *tcpclient.TTCPClient
}
self.Label1 = vcl.NewLabel(self)
self.Label1.SetCaption("1号位置信息")
self.Label1.SetParent(self)
self.Label1.SetBounds(10, 90, 88, 28)
self.Label2 = vcl.NewLabel(self)
self.Label2.SetCaption("2号位置信息")
self.Label2.SetParent(self)
self.Label2.SetBounds(10, 130, 88, 28)
self.Label3 = vcl.NewLabel(self)
self.Label3.SetCaption("3号位置信息")
self.Label3.SetParent(self)
self.Label3.SetBounds(10, 170, 88, 28)
// 客户端收到消息事件
pClient.OnRead = func(pData *connection.TData) {
//
pack := &ddzpb.TDDZ{}
proto.Unmarshal(pData.GetBuffer(), pack)
log.Println("收到包", pack)
switch pack.GetCommand() {
case 19:
bc := pack.GetPlayerComeInBc()
tableinfo := bc.GetTableInfo()
for _, v := range tableinfo.GetPlayerInfo() {
switch v.GetPosition() {
case 1:
self.Label1.SetCaption(v.GetNickName())
case 2:
self.Label2.SetCaption(v.GetNickName())
case 3:
self.Label3.SetCaption(v.GetNickName())
default:
log.Panicln("error position", v)
}
}
self.nTableIndex = tableinfo.GetTableIndex() // 保存桌子号
}
}