zoukankan      html  css  js  c++  java
  • Silverlight+WCF 新手实例 象棋 主界面状态重置(三十四)

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

    正如我们在:Silverlight+WCF 新手实例 象棋 主界面-事件区-求和认输(三十二)里面提到的一样:

    “游戏结束了,要干点什么呢?当然就是棋盘复位了,按钮重置了,如果还有棋谱之类的,全都得重置。这些,我们留下到另一节优化处理吧。”

    所以,本节就做这些手尾工作了。

    由于游戏结束,我们复位的工作很多,至少有N个控件需要复位,因此,Silverlight+WCF 新手实例 象棋 主界面-控件消息传递(二十六)

    我们本节又要用到了:我们需要统筹全局的Index来做这件事:

    我们在EventButton.xaml.cs里,那里有游戏结束通知:

    我们添加一个代理,两行代码,这里我们多了个参数,传递Player:

     public partial class EventButton : UserControl
        {
            
    public delegate void HelpSetGameEnd(Player player);
            
    public event HelpSetGameEnd HelpSetGameEndEvent;
            
    public EventButton()
            {
                
    //...省略N行...
            }
            
    //...省略N行...

         }

    有了代理了,游戏结束时,只管调就是了:

     void client_NotifyEndGameReceived(object sender, GameService.NotifyEndGameReceivedEventArgs e)
            {
                
    //接收游戏结束消息
                switch (e.player.AttachInfo)
                {
                 
    //...省略N行...
                                     
                }
                
    switch (e.player.AttachInfo)
                {
                    
    case "0"://用户主动认输,游戏结束
                    case "1"://将军被吃,游戏结束
                    case "2"://双方同意平手,游戏结束
                        HelpSetGameEndEvent(e.player);
                        
    break;
                }
            }

    咦!怎么两个switch,是不是写错了还是写多了?不是了,这里多加的switch,只是把游戏结束的标志都抽出来,单独的执行一下游戏结束重置而已。

    好了,这里的事情况就做完了,然后该Index出手了。

    public partial class Index : UserControl
        {
           
    //...省略N行...
            EventButton eventButtonControl;
            
    public Index()
            {
                
    //...省略N行...
                eventButtonControl = new EventButton();
                eventButtonBoard.Child 
    = eventButtonControl;

                
    //下面为委托事件 ...省略1行...
              eventButtonControl.HelpSetGameEndEvent += new EventButton.HelpSetGameEnd(eventButtonControl_HelpSetGameEndEvent);
            }

            
    void eventButtonControl_HelpSetGameEndEvent(GameService.Player player)
            {
                
    //这里实现游戏结束后所有的复位
                
            }
            
    //...省略N行...
       }

    好了,接下来,我们要为一些控件做一些“重置”工作:

    我们先为Chess象棋类增加一个Reset方法,用于把所有象棋相关参数重置为初始状态:

       /// <summary>
        
    /// 象棋 by 路过秋天
        
    /// http://cyq1162.cnblogs.com
        
    /// </summary>
        public class Chess
        {
            
    //...省略N多行...

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

    OK,有了这个方法,我们的Index就首先可以添加一行了:

    void eventButtonControl_HelpSetGameEndEvent(GameService.Player player)
            {
                
    //这里实现游戏结束后所有的复位
                App.chess.Reset();
            }

    接着要复位事件区的按钮,先为事件区控件添加一个Reset方法[以后的控件基本上都添加一个]:

    public partial class EventButton : UserControl
        {
            
    //...省略2行...
            public EventButton()
            {
               
    //...省略N行...
            }
            
    public void Reset()
            {
                btnGameDeuce.IsEnabled 
    = false;
                btnGameLose.IsEnabled 
    = false;
                btnGameStart.IsEnabled 
    = false;
            }
             
    //...省略N行...

        }

    OK,我们可以实现总复位方法了:

    void eventButtonControl_HelpSetGameEndEvent(GameService.Player player)
            {
                
    //这里实现游戏结束后所有的复位
                App.chess.Reset();
                eventButtonControl.Reset();
                
    if (App.player.ColorValue == player.ColorValue)
                {
                    eventButtonControl.btnGameStart.IsEnabled 
    = true;
                }
            }

    最后一个,总得有一个人的“开始按钮”得激活的吧,不然怎么重新开始游戏呢?

    OK,现在如果回头看看上面的结束标志,那个:

    case "1"://将军被吃,游戏结束

    这个怎么产生的?哪产生的呢?其实很容易了,回到棋子“GoToDead"的地方,我们添加N行语句判断一下:

    if (Name == "" || Name == "")
    {
        
    //发送游戏结束到服务器
    }

    可是,棋子并不能自己发送消息,所以,正常思维就是添加代理了。可是呢,如果一个棋子一个代理,36颗子不就要产生36个代理了?

    所以,代理的位置要移动一下了,一开始呢,我是在Chess类里添加一个代理,然后在棋子GoToDead里调用一个Chess的代理方法。

    不过呢!刚想到了,直接在ChessAction的吃子动作里加代理和判断就行了,说动就动。

     /// <summary>
        
    /// 棋子动作类 by 路过秋天
        
    /// </summary>
        public class ChessAction
        {
          
            
    public delegate void GameEndDelegate(int colorValue);
            
    public event GameEndDelegate HelpSetGameEndEvent;
            
    //...省略N多行
            public void SetIsGameEnd(Chessman man)
            {
                
    if (man.Name == "" || man.Name == "")
                {
                    GameEndEvent(man.Color 
    == Colors.Red ? 1 : 2);
                }
            }

            
    public void EatChessman(Chessman moveChessman, Chessman eatChessman)
            {
                
    if (MoveTo(moveChessman, eatChessman.MovePoint))
                {
                    SetIsGameEnd(eatChessman);
                    eatChessman.GoToDead();
                }
            }
            
    /// <summary>
            
    /// 系统自动移动棋子
            
    /// </summary>
            public void AutoMoveTo(Point from, Point to)
            {
                Chessman chessman 
    = Parent.FindChessman(from);
                Chessman eatChessman 
    = Parent.FindChessman(to);
                
    if (chessman != null)
                {
                    PlayMove(chessman, to);
                    chessman.MovePoint 
    = to;
                    
    if (eatChessman != null)
                    {
                        SetIsGameEnd(eatChessman);
                        eatChessman.GoToDead();
                    }
                }
            }
            
    //...省略N多行
     }

    我们添加了一个代理,由于,除了我们人为移动,还有系统自己移动,所以我们添加了一个公共方法,在吃子前都SetIsGameEnd来看看是不是游戏结束了,由于棋子谁输谁赢,所以要传递一个Color用于说明谁的将/帅被吃了。

    OK,接着我们回到Chess.xaml.cs里,实现一下这个代理方法:

    public partial class Chess : UserControl
        {
            ChessNewInstance.Chess chess;
    //这里我们同时把它提到全局对象
            public Chess()
            {
               
    //...省略N行...
                chess.Action.HelpSetGameEndEvent += new ChessNewInstance.ChessAction.GameEndDelegate(Action_HelpSetGameEndEvent);
               
    //...省略N行...        
            }

            
    void Action_HelpSetGameEndEvent(int colorValue)
            {
                
    //将帅被吃,游戏结束
                if (App.player.ColorValue + colorValue == 3)
                {
                    App.player.AttachInfo 
    = "1";
                    App.client.EndGameAsync(App.player);
                }
            }
             
    //...省略N行...
       }

    颜色值相加=3就是对手了。由于将帅被吃,无论是棋手还是看棋者,都会产生这个事件,所以要过滤判断。

    OK,至此,我们F5看下效果了:

    再走一步,吃将军:

    状态重置成功了,可是一点提示都没有,于是,我们回到游戏结束EventButton.xaml.cs那里,添加一下结束通知弹出消息了:

     void client_NotifyEndGameReceived(object sender, GameService.NotifyEndGameReceivedEventArgs e)
            {
                
    //接收游戏结束消息
                switch (e.player.AttachInfo)
                {
                    
    //...省略N行...
                      case "1":
                         MessageBox.Show(e.player.NickName
    +" 赢了!""游戏结果通知", MessageBoxButton.OK);
                        
    break;
                }
                 
    //...省略N行...
            }

    继续F5运行看下效果:

    吃掉对方将军时,终于有提示了:

    确认后,游戏重置所有状态:看按钮,也重置了:

    OK,本节点到为止了。

    版权声明:本文原创发表于 博客园,作者为 路过秋天 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
    个人微信公众号
    创业QQ群:617713515
    Donation(扫码支持作者):支付宝:
    Donation(扫码支持作者):微信:
  • 相关阅读:
    217. 存在重复元素
    189. 旋转数组
    122. 买卖股票的最佳时机 II
    26. 删除排序数组中的重复项
    [剑指Offer]二进制中1的个数
    [Unity]Unity更改黑色主题(个人版)
    [Unity]限制两个物体之间的距离
    [Untiy]贪吃蛇大作战(五)——游戏主界面
    sql server 函数详解(3)数据类型转换函数和文本图像函数
    sql server 函数详解(2)数学函数
  • 原文地址:https://www.cnblogs.com/cyq1162/p/1794242.html
Copyright © 2011-2022 走看看