zoukankan      html  css  js  c++  java
  • 一起谈.NET技术,Silverlight+WCF 新手实例 象棋 主界面棋谱回放结局(四十) 狼人:

    查看本系列其他相关文章请点击:Silverlight+WCF 新手实例象棋专题索引

    在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示

    Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)中,我们实现了用户的棋谱回放,在文章的下面,我们曾留下了两个问题:

    • 下棋者在下棋过程,要不要开放“回放”功能,如果开放,需要注意什么?
    • 观众在回放过程中,突然又传来一个棋步,需要注意什么?

    在解答这两个问题之前,我们先来解答上一篇的截图中发现的问题:

    不知有没有人发现?图中有三个“炮”或三个”马“,出现这个事故的原因,

    是由于在每次重置chess.Reset的时候,我们没有清除棋子列表,造成了有重复的棋子。找到了原因,解决的方法就相当的简单了,

    只要在chess象棋类里的确Reset方法里,添加一行棋子列表.clear方法清除下就行了,增加的只有第一行:

    public void Reset()
    {
       ChessmanList.Clear();
    //增加棋子列表清除
       container.Children.Clear();//棋盘和棋子一并清掉了
       InitBoard();//只好重新初始棋盘了
       InitChessman();//只好重新初始棋子了
       IsCanMove = false;//设置状态不能移动了
       IsGaming = false;//这个差点忘了
    }

    好了,一行代码解决了我们上一节隐藏在图片中的bug。

    接下来,我们要对上节留下的两个问题做一下解答了:

    我们把问题顺序倒一下,先解答第二个问题吧:观众在回放过程中,突然又传来一个棋步,需要注意什么?

    我们在上一节,曾定义过一个全局变量:

    public static bool chessManualPlaying = false;//棋谱正回放中

    而上节中,我只说了后面会用到[很后哦],所以,这节我们要用到了,因为这个变量可以解答问题:

    我们假设:当观众在回放棋步的过程中,棋手双方在不停的下棋,不断的传递新的棋步过来;

    这时,我们仅需要处理的,只是不执行自动播放而已,至于写棋谱区文字和添加到棋谱列表的照常就行了。

    所以,我们要做的事情就是:开始播放时,设置App.chessManualPlaying为true;播放结束后,设置为false;

    于是我们回到播放时的代码增加:

     private void PlayStep()
            {
                
    if (App.stepList.Count > 0)
                {
                    
    //播放前复位棋子
                      App.chess.Reset();
                    App.chessManualPlaying 
    = true;//增加的一行
                    timer.Interval = TimeSpan.FromSeconds(slPlayerInternal.Value);
                    timer.Start();
                }
            }

    于是我们再回到播放结束时的代码增加:

    void timer_Tick(object sender, EventArgs e)
            {
                
    //...省略N行...
               if (moveStepIndex == App.stepList.Count)//棋步结束
                {
                    moveStepIndex 
    = 0;//重置索引
                      timer.Stop();//停止timer
                    App.chessManualPlaying = false;//增加的一行
                }
            }

    标识位加完了,我们回到设置自动移动棋步的地方,加判断,如果播放中,切断棋步自动移动:

    接收棋步的通知在Chess.xaml.cs里,我们只需要添加半行代码[下面的!App.chessManualPlaying]:

    void client_NotifyMoveStepReceived(object sender, NotifyMoveStepReceivedEventArgs e)
            {
                App.stepList.Add(e.player.Step);
    //添加棋步
                if (!App.chessManualPlaying && App.player.ID != e.player.ID)//非棋步播放中,非自己
                {
                  
    //...省略棋步移动相关代码...
                 }
                HelpSetChessManualEvent(e.player.Step);
    //写棋谱区
            }

    第二个问题,至此就解决了,总共添加了2.5行代码。

    现在转回第一个问题了:下棋者在下棋过程,要不要开放“回放”功能,如果开放,需要注意什么?

    不开放:只需要把“回放”按钮启用状态设置为false就行了;

    开放:其实也不难:我们只要限制在播放过程中,不让棋手下棋就行了,

    同时棋手播放过程也会产生第一个问题:不过,我们刚才已经解决,加的代码对棋手也是同样有效。

    如何限制棋手不让下棋,其实很简单了,chess.IsCanMove属性就能限制了,只要播放时,设置为false,播放完,设置回原值就行了;

    是不是感觉和第一个问题太相似了?动手吧,还是播放开始和结束,只不过,也要增加一个变量,来存棋手的下棋状态:

    增加一行全局变量:

     public partial class ChessManual : UserControl
        {
           
    //...省略2行代码...
            bool tempIsCanMove;//保存棋手之前的状态
            public ChessManual()
            {
                
    //...省略N行代码...

            }
           
    //...省略N行代码...
       }

    播放时,先取状态,再设置IsCanMove=false[这句在Reset重置里已经有了,可以省了];

     private void PlayStep()
            {
                
    if (App.stepList.Count > 0)
                {
                    
    //播放前复位棋子
                    tempIsCanMove = App.chess.IsCanMove;//先存之前状态
                    App.chess.Reset();//重置状态时会设置IsCanMove=false,所以不用写多一行
                    App.chessManualPlaying = true;
                    timer.Interval 
    = TimeSpan.FromSeconds(slPlayerInternal.Value);
                    timer.Start();
                }
            }

    接着播放结束时,状态设置回来[最后一行代码]:

    void timer_Tick(object sender, EventArgs e)
            {
                
    //...省略N行代码...
                if (moveStepIndex == App.stepList.Count)//判断棋步结束没有
                {
                    moveStepIndex 
    = 0;//重置索引
                    timer.Stop();//停止timer
                    App.chessManualPlaying = false;
                    App.chess.IsCanMove 
    = tempIsCanMove;//增加的一行
                }
            }

    OK,至此,我们用了同样的方法,解决了上节的两个问题,接下来又到F5的showtime时间:

    正常,上图,这下棋步回放是正常的了:

    1:棋手正下棋不久:

    2:观众进来了,播放了棋步,定位到实时状态:

    3:观众想看下棋过程,开始“回放”棋步:

    4:“回放”到第三步棋中:

    5:回放到第五步棋中:

    OK,截图到就到此了,本系列文章,一不小心就写了40节了,在这系列的40节里,所有功能已完全的开放源码并讲解完了!

    有兴趣的读者欢迎关注本系列文章,明天公司又要搬家了,本系列有没有后续文章,目前情况不明......

    顺路更新下索引:Silverlight+WCF 新手实例 象棋 专题索引

  • 相关阅读:
    URAL——DFS找规律——Nudnik Photographer
    URAL1353——DP——Milliard Vasya's Function
    URAL1203——DPor贪心——Scientific Conference
    递推DP HDOJ 5389 Zero Escape
    区间DP UVA 1351 String Compression
    树形DP UVA 1292 Strategic game
    Manacher HDOJ 5371 Hotaru's problem
    同余模定理 HDOJ 5373 The shortest problem
    递推DP HDOJ 5375 Gray code
    最大子序列和 HDOJ 1003 Max Sum
  • 原文地址:https://www.cnblogs.com/waw/p/2158629.html
Copyright © 2011-2022 走看看