拼吾爱程序人生

首页 » .Net编程 » C# » 基于TCP的网络游戏黑白棋系列(四):游戏棋盘
cobra - 2008-10-15 0:11:00
上一节我们讨论的游戏大厅的实现,这一节我们来看一下客户端游戏棋盘的处理

关于棋盘的呈现采用了GDI的DrawImage方法,先准备一张400*400的棋盘图片和两个40*40的棋子图片(分别为黑棋和白棋),我们的思路是通过和客户端服务器的数据交互得到游戏大厅某桌的棋子信息,然后客户端直观的呈现该信息。

棋盘同样可以看作一个对象,只不过这个对象我们需要从Form来继承,因为我们需要用到PictureBox控件来呈现棋盘和棋子

Code


这里和服务器端的GameTable一样也定义了grid(8,8),目的是在客户端保存棋子的状态,每次通讯时只由服务器端通知更改的棋子的位置和颜色,客户端也作相应的修改。当然也可以不声明grid(8,8),不过那样每次通讯都需要传递所有的棋子位置状态,效率不高

上一节提到当玩家选中Checkbox表明坐下时,触发CheckedChange事件,这一节对该事件进行修改,初始化棋盘FormPlaying并打开

Code


调用GDI画棋盘及棋子信息(初始化及任一方落子都调用该事件)

Code


当玩家落子的时候实际上是触发了PictureBox的MouseDown事件,程序判断是否可在该处下子,如果可以则调用GDI的Graphics.DrawImage将棋子“画”到棋盘上。

Code


此处的实现效率上有些问题,把判断能否落子的任务交给服务器端,实际上我们已经在客户端利用grid数组保存了棋子的状态,完全可以放到客户端去判断,放到服务器端会造成很多无用的通讯数据(写文章的时候代码已经完成,不打算改了)

列一下服务器端处理SetDot命令的逻辑

1 如果没有轮到该方落子,则丢弃此次命令

2 将落子的位置向八个方向进行比较(上、下、左、右、左上、左下、右上、右下)

  考虑落子的同一列的上下两个方向的比较情况
  (1)单列中小于目标行的情况,目标行最小为第1行(下标为0)
      假设目标行为第5行(下标为4)则比较行k1依次为3,2,1,0
      如果目标行为第1行(下标为0)则不需要比较小于目标行的情况
  (2)单列中大于目标行的情况,目标行最大为第8行(下标为7)
      假设目标行为第5行(下标为4)则比较行k2依次为5,6,7
      如果目标行为第8行(下标为7)则不需要比较大于目标行的情况

3 准备八个List<string>,将八个方向需要反转的棋子分别存入代表各自方向的List<string>中,以向上方向为例

  (1)从最靠近目标行的行数开始,逐个检验同列中棋子颜色,遇到相同颜色或者无子即退出,连续不同存入;如果检测位置无子,则晴空该方向List<string>,即无法改变该方向棋子颜色
  (2)如果有同颜色的子,则退出,List<string>中的值即为该方向需要更改的值
  (3)如果有不同颜色的子且不为第1行,则记录,否则清空列表。假设在第1列第1-4行为黑子,白方在第1列第5行打算落下白子,从向上的方向比较,当检测到第1行时,该方向列表中已有3个子,但第一行为黑子,无法反转1-4行黑子,所以清空已有列表。

4 如果八个方向List<string>均为空,则表明此处无法下子,丢弃此命令

5 通知客户端修改 落子的信息及需要反转的棋子的所有信息

此处代码较多,不列了,请看源码

本节完成了棋盘的呈现及简单的落子算法,但未考虑游戏中一方无法落子而由另一方继续落子的情况,下一节将对代码进行简单的重构以添加该功能,最终完成一个完整的网络黑白棋对弈。

源代码下载:
 附件: 您所在的用户组无法下载或查看附件





(文/basilwang  出处/博客园)

 您可能对 [C#] 的这些文章也感兴趣:

基于C#的接口基础教程之七(1)
c#中用Win32API实现的媒体播放类,支持mp3\wma\wmv
C#低级Windows API钩子拦截键盘输入
C#InnerClassvs.java的innerclass比较
用于统计函数执行时间的类
用VisualC#发送电子邮件
C# 实现A*算法
C# 网络资源
C#程序控制开始菜单的弹出
用VisualC#来获得计算机的分辨率
1
查看完整版本: 基于TCP的网络游戏黑白棋系列(四):游戏棋盘
Modify by pin5i DZNT_ExpandPackage 2.1.3258 2007-2008 pin5i.com
  Total Unique Visitors: