在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示
这节,我们要实现棋谱列界面布局和棋谱的获取,先上一张久远的图片:
看清楚了,到本节为止,除了第三区棋谱区,其它的区域我们都已完成了,所以,我们抓紧时间,赶紧吧:
好了,先布局,和以往一样:
1:界面拖一个Border到Index.xaml,到第三区的位置,设置好宽和高[212*602]:
< UserControl ...省略... d:DesignHeight = " 620 " d:DesignWidth = " 1000 " > < Grid x:Name = " LayoutRoot " Background = " White " > // ...省略之前四个Border... < Border BorderBrush = " Silver " BorderThickness = " 1 " Height = " 602 " HorizontalAlignment = " Left " Margin = " 538,12,0,0 " Name = " chessManualBoard " VerticalAlignment = " Top " Width = " 212 " /> </ Grid > </ UserControl >
2:新建一个用户控件:就叫:ChessManual.xaml
3:后台动态加载控件了,后台代码就两行,看今天新加的那
public partial class Index : UserControl { // ..省略N行... ChessManual chessManualControl; public Index() { // ..省略N行... chessManualControl = new ChessManual(); // 今天新加的 chessManualBoard.Child = chessManualControl; // ..省略N行... } // ..省略N行... }
OK,控件加载完了。接下来的任务就是要实现ChessManual控件里的内容显示了:
4:接下来我们回到ChessManual.xaml里,改一下总体宽和高为212*602:
< UserControl ...省略一堆... d:DesignHeight = " 602 " d:DesignWidth = " 212 " > < Grid x:Name = " LayoutRoot " Background = " White " > </ Grid > </ UserControl >
我们往里添加界面布局:
< Grid x:Name ="LayoutRoot" Background ="White" > < ListBox Height ="520" HorizontalAlignment ="Left" Name ="lbChessManual" VerticalAlignment ="Top" Width ="190" Margin ="10,10,0,0" /> < Button Content ="回放" Height ="23" HorizontalAlignment ="Right" Margin ="0,541,12,0" Name ="btnPlay" VerticalAlignment ="Top" Width ="53" /> < Slider Height ="23" HorizontalAlignment ="Left" Margin ="12,541,0,0" Name ="slPlayerInternal" VerticalAlignment ="Top" Width ="56" SmallChange ="0.5" Maximum ="9" LargeChange ="1" /> < TextBox IsEnabled ="false" Height ="23" HorizontalAlignment ="Right" Margin ="0,541,110,0" Name ="txtValue" Text ="0" VerticalAlignment ="Top" Width ="15" /> < TextBlock Height ="23" HorizontalAlignment ="Center" Margin ="108,545,70,34" Name ="textBlock1" Text ="秒/步" VerticalAlignment ="Center" Width ="34" /> </ Grid >
代码看起来不整洁,是有点乱,布完局后的结果就是上面图的第三区了,不另外上图了:
至此,布局就完成了,接下来,我们要进入和棋谱相关的操作了服务端操作了:
在双方下棋的过程中,我们不断交互的传送棋步,同时,服务端也记录了每一步的棋步信息;
这节,我们将通过棋步生成棋谱,同时和棋步一起传递。
有一些基础知识要知道,就是棋谱是怎么写出来的?这个,大伙自己百度看看了,不做介绍了!
这里,我封装成一个方法,附加在Chess象棋类里面:
首先呢,棋谱里的数字,一方是数字,一方是中文数字,所以先来一个方法把数字转中文数字:
private string GetGBKNum(int num) { switch (num) { case 1: return "一"; case 2: return "二"; case 3: return "三"; case 4: return "四"; case 5: return "五"; case 6: return "六"; case 7: return "七"; case 8: return "八"; case 9: return "九"; default: return "XX"; } }
有了这个方法,接着我们实现写棋谱:
//写棋谱 public string WriteManual(Chessman chessman, Point moveTo) { string manual = (chessman.Color == Colors.Red ? "红方:" : "黑方:") + chessman.Name; int moveX = 9 - (int)chessman.MovePoint.X; int toX = 9 - (int)moveTo.X; int value = (int)chessman.MovePoint.Y - (int)moveTo.Y; manual += chessman.Color == Colors.Red ? GetGBKNum(moveX) : moveX.ToString(); manual += value == 0 ? "平" : ((value > 0) ? "进" : "退"); if (value != 0) { switch (Action.Rule.GetChessTypeByName(chessman.Name)) { case ChessType.Bing: case ChessType.Che: case ChessType.Jiang: case ChessType.Pao: toX = Math.Abs(value); break; } } manual += chessman.Color == Colors.Red ? GetGBKNum(toX) : toX.ToString(); return manual; }
上面这段函数可能没那么好理解,大伙需要先理解棋谱的基础知识,才能好好的理解这段代码,不理解就直接使用跳过也行了;
反正一步棋就产生一行中文说明的棋谱信息。
有了写棋谱函数,我们在哪里使用呢?当然是回到我们提交棋步到服务端那时了,回到Chess.xaml.cs里:
void Action_HelpMoveStepEvent(ChessNewInstance.Chessman chessman, Point moveTo) { MoveStep step = new MoveStep(); step.FromX = chessman.MovePoint.X; step.FromY = chessman.MovePoint.Y; step.ToX = moveTo.X; step.ToY = moveTo.Y; step.ColorValue = chessman.Color == Colors.Red ? 1 : 2 ; step.Name = chess.WriteManual(chessman, moveTo); // 这里只加一行代码 App.player.Step = step; // 附加棋步 App.client.MoveStepAsync(App.player); chess.IsCanMove = false ; }
在这里,我们只添加了一行代码,把棋谱放到棋步的Name里面,然后随便棋步一起过去了。
OK,接着我们回到接收棋步的地方,同样的,我们收到棋步后,把棋步的Name显示到棋谱区就行了。
我们接收棋步是在Chess.xaml.cs里,可是我们要显示的棋谱区却在我们新添加的ChessManual.xaml里;
所以,我们需要在控件间传递消息,所以,我们又要请出委托了:
在Chess.xaml.cs里添加委托,添加两行,然后在接收到棋步的最后,调用一下就OK了,参数就是传递棋步了:
public partial class Chess : UserControl { public delegate void HelpSetChessManual(MoveStep step); public event HelpSetChessManual HelpSetChessManualEvent; ChessNewInstance.Chess chess; // 这里我们同时把它提到全局对象 public Chess() { // ...省略N行... } // ...省略N行... void client_NotifyMoveStepReceived( object sender, NotifyMoveStepReceivedEventArgs e) { if (App.player.ID != e.player.ID) // 非自己 { // ...省略N行... } HelpSetChessManualEvent(e.player.Step); // 这里调用 } // ...省略N行... }
好了,我们的Index.xaml.cs又要干活了:
先和棋谱控件约好接口调用先,所以我们在棋谱区添加一个方法:
代码
是不是发现和Chat聊天区的极其相似,其实就是代码Copy一下,改改名称也就是了。
好了,接口也有了,我们回到Index.xaml.cs里做一下功夫:
public partial class Index : UserControl { // ...省略N行... public Index() { // ...省略N行... chessControl.HelpSetChessManualEvent += new Chess.HelpSetChessManual(chessControl_HelpSetChessManualEvent); } void chessControl_HelpSetChessManualEvent(GameService.MoveStep step) { chessManualControl.Add(step); } // ...省略N行... }
OK,至此,我们布局完了,写谱也有了,接谱也有了,该F5看下效果了:
一切正常,上图:
看到了吧,双方每走一步都有棋谱显示,只是棋谱,我们还没完?观众进来时,怎么还原棋谱?棋谱又该怎么回放?我们下节解说
本节就点到为止。
版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:
http://www.cnblogs.com/cyq1162/archive/2010/08/07/1794788.html
相关资源:敏捷开发V1.0.pptx