• Silverlight+WCF 新手实例 象棋 主界面事件区求和认输(三十二)


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

    事隔几篇,我们又回到事件区,继续其它两个按钮事件,来张图吧:

    Silverlight+WCF 新手实例 象棋 主界面-事件区-游戏开始(二十七) 和之后的几篇,我们实现了游戏开始,

    在这篇之前,基本上双方已可以对战了,看似主体功能已完成。只是,大伙都知道,细节的东西,才是花时间的,漫长的路还在后面.......

    如标题所示,这节实现“求和+认输”两个事件。

    每次开始,我们都习惯的先写WCF服务端代码,再回到客户端写代码:

    对应着“开始的”StartGame,这节我们也要开始我们的EndGame了。

    回到IService.cs,添加接口:

    /// <summary>
            
    ///游戏结束
            
    /// </summary>
            [OperationContract(IsOneWay = true)]
            
    void EndGame(Player player);

    接着是ICallBack.cs,回调接口:

    [OperationContract(IsOneWay = true)]
    void NotifyEndGame(Player player);

    紧跟着是实现EndGame接口,和StartGame一样,只需一行代码:

    public void EndGame(Player player)
    {
        Notify.Game(player, GameType.End);
    }

    接着我们实现Notify.Game里预留的Switch语句:

    Notify.Game
    internal static void Game(Player player, GameType type)
            {
                
    switch (type)
                {
                    
    case GameType.Start://通知对方玩家开始游戏
                      
    //省略已实现的代码
                       break;
                    
    case GameType.Move://通知移动了,房间内人手一份
                       
    //省略已实现的代码
                        break;
                    
    case GameType.End://通知游戏结束了,房间内人手一份
                        foreach (KeyValuePair<Guid, Player> item in Service.playerList[player.RoomID])
                        {
                          //请求平手,只发给对手
                          if (player.AttachInfo == "22"|| player.AttachInfo == "21" || player.AttachInfo == "20")
                            {
                                if (item.Value.ColorValue + player.ColorValue == 3)
                                {
                                    item.Value.CallBack.NotifyEndGame(player);
                                    break;
                                }
                            }
                            else
                            {
                                item.Value.CallBack.NotifyEndGame(player);
                            }
                        }
                        break;
                }
            }

    就一个循环,正常是人手一份通知,不过请求平手,对手一份就够了[多了一个21,20,是对方回应标识,下面有说到]。

    到此服务端轻松已完成了!!

    OK,接着我们回到客户端,对应相应的按钮事件:

    喂喂,编绎,更新服务引用哦[我又忘了-_-...]。

    一:求和[我查了下E文(平手)叫:Deuce]

    我们双击求和按钮,这是我们最本能的反应了,前后台产生了Click事件代码:

    我们往后台轻松敲两行代码,为什么App.player后面还有一个"22"的参数???有什么用呢?等会就知!:

    //平手事件,我们定义22
    private void btnGameDeuce_Click(object sender, RoutedEventArgs e)
    {
        App.player.AttachInfo 
    = "22";
        App.client.EndGameAsync(App.player, 
    "22");
    }

    OK,发送完命令就等对方回应了:

    这里有一点,我们点击完发送后,要不要提示用户“你的请求已发送,请等待回应”这样的提示语呢?

    如果不用,就不用加那个完成事件了,如果要,我们就加一下了,如下

    为了不产生多个事件,我们都把事件移到构造函数里:

    代码
    public EventButton()
            {
                
    //省略N行
                App.client.EndGameCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_EndGameCompleted);
            }

            
    void client_EndGameCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
            {
                
    if (Convert.ToString(e.UserState) == "22")
                {
                    MessageBox.Show(
    "你的请求已发送,请等待回应""游戏通知", MessageBoxButton.OK);
                }
            }

    看到事件结束后我们的判断了,那个上面传的参数"22"这里我们就用到了。由于可以多次调用同一个请求,每个请求都会产生一个回调,这样,通过多传一个参数标识是哪个请求的,这样接收的时候,就可以分支处理了。

    好了,消息是发送了,可是,对方在哪接收呢?既然是在这里开始,就在这里结束好了!

    还是构造函数里添加事件:

    public EventButton()
            {
              
    //省略N行
              App.client.NotifyEndGameReceived += new EventHandler<GameService.NotifyEndGameReceivedEventArgs>(client_NotifyEndGameReceived);
            }

            
    void client_NotifyEndGameReceived(object sender, GameService.NotifyEndGameReceivedEventArgs e)
            {
                
    //接收游戏结束消息
            }

    接下来就是分支处理游戏结束消息了:

     void client_NotifyEndGameReceived(object sender, GameService.NotifyEndGameReceivedEventArgs e)
            {
                
    //接收游戏结束消息
                switch (e.player.AttachInfo)
                {
                    
    case "22"://平手请求
                        MessageBoxResult result = MessageBox.Show("对方请求平手,是否同意!""游戏请求", MessageBoxButton.OKCancel);
                        
    if (result == MessageBoxResult.OK)//同意
                        {
                            App.player.AttachInfo 
    = "21";//同意请求标识位设为21
                        }
                        
    else//拒绝
                        {
                            App.player.AttachInfo 
    = "20";//拒绝请求标识位设为20
                            
                        }
                        App.client.EndGameAsync(App.player);
                        
    break;
                }
            }

    看代码,简单的很,如果同意,回复21,拒绝,回复20,

    接着,我们要对21,20的回复进行处理了。

    void client_NotifyEndGameReceived(object sender, GameService.NotifyEndGameReceivedEventArgs e)
            {
                
    //接收游戏结束消息
                switch (e.player.AttachInfo)
                {
                    
    case "22"://平手请求
                        
    //...省略...
                        break;
                    
    case "21":
                        
    //显示同意平手,结束游戏,向大伙广播游戏结束了
                        MessageBox.Show("对方同意平局""游戏通知", MessageBoxButton.OK);
                        App.player.AttachInfo 
    = "2";//发出游戏平局广播。
                        App.client.StartGameAsync(App.player);

                        
    break;
                    
    case "20":
                        
    //显示拒绝,然后当什么事也没发生
                        MessageBox.Show("对方拒绝平局""游戏通知", MessageBoxButton.OK);
                        
    break;
                }
            }

    唉,又多了一个游戏平局广播标识"2"又要处理,好吧,处理吧,等会不会又出来其它数字吧,唉,这个还真有,认命吧。

                    case "2":
                        MessageBox.Show(
    "双方平局""游戏结果通知", MessageBoxButton.OK);
                        
    break;

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

    吃饭时间快到了,要写快一点,接下来处理认输事件了:

    二:认输

    同样的,双击认输按钮,产生事件,这里代码也同样很简单,起个标志位,发送过去,认输就直接广播说输了就行了:

    private void btnGameLose_Click(object sender, RoutedEventArgs e)
            {
                App.player.AttachInfo 
    = "0";
                App.client.EndGameAsync(App.player);
            }

    大伙在游戏结束通知消息里处理一下:

    void client_NotifyEndGameReceived(object sender, GameService.NotifyEndGameReceivedEventArgs e)
            {
                
    //接收游戏结束消息
                switch (e.player.AttachInfo)
                {
                    
    case "22"://平手请求
                       
    //...能省则省...
                        break;
                    
    case "21":
                       
    //...能省则省...
                        break;
                    
    case "20":
                      
    //...能省则省...
                        break;
                    
    case "2":
                       
    //...能省则省...
                        break;
                    
    case "0":
                        MessageBox.Show(e.player.NickName
    +"认输了!""游戏结果通知", MessageBoxButton.OK);
                        
    break;
                }
            }

    OK,到此,两个事件就处理完成了,只是游戏结束后的复位功能没用实现,我们留到下节处理了,时间不等人,赶紧F5看下效果:

    没啥效果,默认那个两个按钮是不可用的,在游戏开始后,要开启那两个按钮,赶紧赶紧,加两行代码:

    void client_NotifyStartGameReceived(object sender, GameService.NotifyStartGameReceivedEventArgs e)
            {
                
    //收到消息了应该咋办
                switch (e.player.AttachInfo)
                {
                    
    case "0"://通知可以开始游戏
                       
    //...能省则省...
                        break;
                    
    case "1"://请求开始游戏
                     
    //...能省则省...
                      if (result == MessageBoxResult.OK)//同意开始游戏
                      {
                          btnGameDeuce.IsEnabled = true;
                          btnGameLose.IsEnabled = true;
                      }
                        break;
                    
    case "10":
                     
    //...能省则省...
                        break;
                    
    case "11":
                      
    //...能省则省...

                        btnGameDeuce.IsEnabled 
    = true;
                        btnGameLose.IsEnabled 
    = true;
                        
    break;
                }
            }

    好了,抓紧F5看效果[上面那段1的if语句(绿色的),是截图后补上去的,不然就只有一方的求各认输按钮显示了]:

    上图看效果,“马还走一步”,博客园上图片出错了,吃完饭回来再看看补上了。

    文章先发了,图后补。

    现在补图了:

    1:游戏开始了,“求和-认输”启用了:

    2:求和发送,对方收到消息:

    3:对方拒绝的后果:

    4:对方同意的结果:

    5:对方认输了:

    版权声明:本文原创发表于 博客园,作者为 路过秋天 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
    个人微信公众号
    创业QQ群:617713515
    Donation(扫码支持作者):支付宝:
    Donation(扫码支持作者):微信:
  • 相关阅读:
    Java创建对象的几种方式
    Sqlserver建立Oracle的鏈接服務器
    千万级的大表!MySQL这样优化更好
    ConurrentHashMap和Hashtable的区别
    BTree和B+Tree详解
    为什么MySQL数据库索引选择使用B+树?
    网易跟贴这么火,背后的某个力量不可忽视
    知物由学 | 如何利用人工智能来对抗DDoS攻击?
    揭秘医疗安全防卫战:“我们仍在购买不安全的医疗设备”
    6月第5周业务风控关注 | 《网络安全等级保护条例(征求意见稿)》本周正式发布
  • 原文地址:https://www.cnblogs.com/cyq1162/p/1791063.html
Copyright © 2020-2023  润新知