经过两个多月的断断续续的尝试和摸索,BS版的人与人对战中国象棋终于可以进行基本功能的测试了。

这里要非常感谢在每天中午休息时候帮我进行游戏测试的同事们,他们给我提供的很多好的建议和意见,让我还愿意为这个小的创意不断的完善而进行新的内容的学习。十分欣慰!

如果曾经一直关注过我这个学习系列的朋友,可能能了解到,其实这个开发的真真的目的并不是只为这个象棋而实施的,整个构思就是想尝试下在Silverlight前台环境与后台WCF交互的双工能力上的一个尝试。

最终希望该项目能完成的功能就是对局双方能实时的获取对方棋子的移动,并将对方棋子的移动体现在自己UI棋盘上,当然这个实时性必须是通过服务端的推消息而获得而不是客户端的定时拉消息完成。

下面就把我这个项目的基本结构给大家共享下,希望能给对该类型应用开发的朋友能有些帮助。

整个项目因为开始只是个简单的构思,所以都是分块的进行尝试,以至于没有对项目的命名进行比较好的规范,所以里面每个Project的名称都不是很统一,所以这里我需要简单的说明下:

整个项目分为Client和Server工程两大块,Client部分包含了ChessComm(主要包含象棋里面通用的信息),ChessQiZiBase(主要包含了象棋的棋子和棋盘逻辑),SilverlightApp2(包含了UI的主要逻辑),SilverlightApp2.web(这个是Silverlight应用的宿主,自动生成不用多说)。

Server部分包含了WcfDataContract(包含了与服务交互的原数据类型),WcfDuplexContract(包含了服务的契约接口)WcfServiceApp(包含了服务的主要实现逻辑)

下面我想把整个的开发过程遇到的问题与解决方案给大家分享下:

问题1:棋盘的布局。这个问题和游戏的逻辑实现没有任何关系,但是该布局的实现其实也决定Silverlight对与棋盘这样逻辑的相对复杂的UI的控制能力。从考察Silverlight控件布局时,我希望该控件能够包含一定数量的子控件,并且其所包含的子控件能够在指定的父控件内的坐标中任意移动,当然这里说道的坐标系不应该是视窗内的绝对坐标系,而应该是棋盘布局上的相对坐标。我最终锁定的是Grid控件(其他控件是否能满足我没有太多仔细的考察),从控件的名称来看应该用网格是比较合理的。不过在整个棋盘的构思和使用中还是遇到了一些问题

问题1.1 空白网格的处理。对于象棋游戏来说,操作的过程是选择棋子后,将棋子移动到其他位置上,对应到Grid来说就是要将该棋子移动到对应的网格上,但是就目前我看到的Grid控件来说,当在网格内点击时,从点击的事件中,如果没有点击到明确的自控件,则在点击的事件参数中是没有办法将点击网格的坐标拿到的。也就是在空白Grid上的任何动作如果没有子控件接受该事件,是拿不到Grid的网格坐标的。对于该问题的处理,我只能将网格棋盘中所有坐标位置填充棋子,其中包含一种所谓的空白棋子,专门用于填充空白网格。

问题1.2 网格内移动效果故事板。对于Silverlight中很酷的一点就是在UI上,可以将所有的元素按照事先设定好的Storyboard来展示很酷的效果。但是在使用Grid时候发现,如果将Storyboard的TargetProperty设定为Grid.Row,或是Grid.Column,会发现无法使用,异常的提示是Storyboard无法制定这样的复杂属性。对于这点真的觉得十分遗憾,当然最后这个希望强加上的效果只能忽略了,如果那位有很好的建议可以在我的博客上留言,表示感谢!

问题2:WCF服务的回调处理。该问题主要是针对在服务端保留每个客户端的回调句柄,应该对这些内容进行如何的管理。

问题2.1 回调句柄的异常问题。对于该问题我在上一篇回调异常问题处理中做了我的理解和说明,并且给出了我理想的解决方案。

问题2.2 回调处理的效率问题。其实在该问题上,与问题一处理的结果是基本一致的,但是不同的是,这个问题的出发点不一样,对于问题2.1来说,后台的多线程的回调来说,可以防止回调句柄异常而造成的回调阻塞。并且可以加入对异常句柄的自定义处理。而对于问题2.2 来说,后台多线程的处理完全应该是构建鲁棒性较好的WCF推消息服务的必须处理机制。在我实施的象棋处理中对每个回调的接口都实现了一个线程。从效率上来看无论当前管理的回调句柄有多少个,回调的时限则是完全取决与网络延迟,而不会因为回调的代码的执行次序有所影响。当然如果需要管理回调的次序,则把多次回调在一个线程能顺序执行也是可以完成。

问题2.3 客户端退出的处理。对于该问题在上一篇回调异常问题处理中我也说道了,但是似乎没有提供一个好的解决方案,这里给大家一个非常简单的思路了,其实对于Silverlight应用来说,无论是浏览器的关闭和浏览器的刷新都会触发一个在App.xoml页面中的Application_Exist事件,该事件比较好理解,应该是应用退出的事件了,也就是浏览器的关闭和刷新都是在整个应用内可控的。所以在这里加入对调用对后台句柄处理的逻辑,再配合问题2.1中的处理,对于客户端的异常退出都可以在我们应用的控制范围内了。

整个项目里面和一般BS应用开发不太一样的地方大概就这些了,

下面就把工程中主要控制棋子,控制棋盘的地方简单说明下,方便感兴趣的朋友阅读。

整个象棋分为两个关键的实体对象,一个是棋子,一个是棋盘,所有的棋子都继承一个棋子的抽象类QiZiBase,所有棋子的管理都在棋盘内完成

棋子类图

 

 

棋盘类图

对于棋盘,棋子的逻辑在这里面基本都涵盖了,对于与WCF交互的部分主要在MainPage中完成。代码都比较好懂。有兴趣的朋友应该比较好看懂。

在项目中,我在后台也加入了一些游戏房间的元素,当然由于时间问题,UI部分没有展示房间的概念。整个工程还没有能够充分测试,可能还存在Bug,不过游戏尝试的初衷基本都达到了。

 

好了,整个工程介绍完了,因为本来尝试的初衷是双工的服务,所以在游戏的内容上没有做太多的研究,不过倒是对该种模式下的游戏开发觉得比较有前景,如果在目前的代码上扩充游戏品种,扩充玩家管理,积分管理,道具,等等。。。。。。

前景应该是非常广阔的!

如果大家对这个方面有开发的需求或是自己有创意的点子需要探讨,欢迎大家留言,探讨!

最后附上工程代码/Files/li_g_7711/SilverlightChess.zip  如果想尝试玩玩的朋友,打开两个连接登陆游戏,就可以享受BS版象棋的乐趣了,不过Bug还是存在的了,不太想调了,希望能做更广的开发,这个象棋就告一段落了,如果哪位朋友遇到Bug解决不了,可以给我留言,我来给解答就好了。

posted on 2009-12-15 14:20  牛仔不太忙  阅读(2975)  评论(10编辑  收藏  举报