前面叫地主和抢地主结束了, 本篇基本上就是属于打牌的范畴了.
首先把超时的时间延长起来. 不要再超时了. 一定等着我们操作完再继续
select {
case <-ch:
log.Println("模拟打牌")
case <-time.After(time.Second * 10000): // 临时改成10000秒超时
log.Println("roundStart 超时")
}
其次, 客户端需要放两个按钮, 一个过,,, 一个打掉勾选的牌
// TMainForm 主窗体
type TMainForm struct {
*vcl.TForm
pClient *tcpclient.TTCPClient
nTableIndex uint32 // 桌子编号
Btn1 *vcl.TButton //开始连接
Btn2 *vcl.TButton //快速加入
Edit1 *vcl.TEdit
Label1 *vcl.TLabel
Label2 *vcl.TLabel
Label3 *vcl.TLabel
CheckBoxGroup [20]*vcl.TCheckBox
Btn3 *vcl.TButton //叫地主
Btn4 *vcl.TButton // 不叫
Btn5 *vcl.TButton // 打掉指定的牌
Btn6 *vcl.TButton // 过牌
}
self.Btn5 = vcl.NewButton(self)
self.Btn5.SetParent(self) //设置爸爸
self.Btn5.SetBounds(410, 50, 88, 28) //设置位置
self.Btn5.SetCaption("打牌") //
self.Btn5.SetOnClick(self.OnButton3Click) // 打牌按钮点击事件
self.Btn6 = vcl.NewButton(self)
self.Btn6.SetParent(self) //设置爸爸
self.Btn6.SetBounds(510, 50, 88, 28) //设置位置
self.Btn6.SetCaption("过牌") //
self.Btn6.SetOnClick(self.OnButton4Click) // 不叫按钮1点击事件
做出来的界面大概是这样一个丑陋的.....
客户端弄好了. 协议上面处理起来就比较复杂了. 协议有两个, 第一个是客户端要告诉服务器我是否要打牌, 打了什么牌.
第二个是服务器广播给3家, 当前打出了什么牌 , 和你手里目前是什么牌, 当然可能还有包含一些额外的信息, 比如3家他们都剩余多少牌了? 当前炸弹翻倍了多少倍之类
先看第一个协议 , 可能要添加内容, 会和前面讲的不一样
// 我过, 我要出对三
message TOutCardReq
{
optional int32 Status = 1; // 状态, 其实可以不要( 目前暂时定, 1过牌, 2打牌)
optional int32 OutCount = 2; // 出牌的牌的数量
repeated int32 OutCards = 3; // 出牌的牌的具体内容
}
在看第二个协议, 可能也要添加内容, 会和前面讲的不一样
//"游戏正式开始, 请出牌"
message TOutCardBc
{
optional int32 Position = 1; // 轮到当前某个位置的玩家进行出牌
optional int32 StartPosition = 2; // 本轮开始的玩家的位置
optional int32 LargePosition = 3; // 本轮目前最大牌的玩家位置(也就是上一个出过牌的人)
optional int32 Round = 4; // 轮次是
optional int32 Hand = 5; // 手次是
optional int32 CardType = 6; // 已经出的牌的类型是
optional int32 CardPoint = 7; // 已经出的牌的点数是
optional TCards OutCards = 8; // 上一次出牌的牌的具体内容
optional TCards YourCards = 9; // 你的牌
}
接下来在客户端做一个打牌的逻辑
// OnButton5Click 打牌
func (self *TMainForm) OnButton5Click(sender vcl.IObject) {
// 选中所有被check的按钮, 把他弄成要打的牌
pack := &ddzpb.TDDZ{}
pack.Command = proto.Int32(26)
pack.OutCardReq = &ddzpb.TOutCardReq{}
pack.OutCardReq.Status = proto.Int32(1) // 1打掉, 2不打
pack.OutCardReq.TableIndex = proto.Uint32(self.nTableIndex) // 桌子号
// 在这里要准备插入牌
nOutCount := 0
pack.OutCardReq.OutCards = &ddzpb.TCards{}
for i := 0; i < 20; i++ {
// 如果被选上了.
if self.CheckBoxGroup[i].Checked() {
v := self.CheckBoxGroup[i].Tag()
pCard := c.NewCard(v)
log.Println(self.CheckBoxGroup[i].Tag(), pCard.ToStr())
nOutCount++
pack.OutCardReq.OutCards.CardValue = append(pack.OutCardReq.OutCards.CardValue, int32(v)) // 插入
}
}
pack.OutCardReq.OutCards.CardCount = proto.Int(nOutCount) // 补上数量
buff, _ := proto.Marshal(pack)
self.pClient.WritePack(buff)
}
// OnButton6Click 不打, 直接放弃, 要不起
func (self *TMainForm) OnButton6Click(sender vcl.IObject) {
pack := &ddzpb.TDDZ{}
pack.Command = proto.Int32(26)
pack.OutCardReq = &ddzpb.TOutCardReq{}
pack.OutCardReq.Status = proto.Int32(1) // 1打掉, 2不打
pack.OutCardReq.TableIndex = proto.Uint32(self.nTableIndex) // 桌子号
buff, _ := proto.Marshal(pack)
self.pClient.WritePack(buff)
}