Silverlight+WCF 新手实例 象棋 主界面-棋谱-布局写谱(三十六)

    xiaoxiao2022-07-08  210

    在线演示地址: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
    最新回复(0)