zoukankan      html  css  js  c++  java
  • Silverlight+WCF 新手实例 象棋 回归WCF通讯应用进入房间(十九)

    上一节我们讲到登陆时通过WCF,把用户信息传递到远程服务器,并用一个全局泛型字典变量来保存用户列表。

    登陆后我们转向了房间页面。这节,我们要通过点击房间上的座位进入主页面(Index.xaml)。

    既然要点击房间座位才能进入,我们就得为那房间的座位添加鼠标点击事件了。

    我们回到GameRoom.cs找到创建房间的代码,找到Draw函数里,创建红蓝黑三个房间座位的代码,其实就是那三个矩形框Rectangle。

    我们在它们被添加到房间之前,添加几个事件:

     //添加三个房间点击事件
                redChair.MouseLeftButtonDown += new MouseButtonEventHandler(redChair_MouseLeftButtonDown);
                spectatorChair.MouseLeftButtonDown 
    += new MouseButtonEventHandler(spectatorChair_MouseLeftButtonDown);
                blackChair.MouseLeftButtonDown 
    += new MouseButtonEventHandler(blackChair_MouseLeftButtonDown);
                
    //下面就是添加房间了,之前就有的代码
                room.Children.Add(redChair);
                room.Children.Add(blackChair);
                room.Children.Add(spectatorChair);
                room.Children.Add(text);
                container.Children.Add(room);

    三个房间座位产生的事件函数:

    void blackChair_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                
    //待实现
            }
            
    void spectatorChair_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                
    //待实现
            }
            
    void redChair_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                
    //待实现
            }

    OK,在点击的时候,我们都要产生同一个动作,就是“进入”房间了。简单逻辑思维告诉我们要添加一个公共的"Enter"方法

    void Enter(int colorValue)
    {
     
    //待实现
    }

    有了Enter方法,我们可以写鼠标点击事件了:

    黑色位置点击:判断黑色房间是否有人,没人的话就设置一下有人,并改变一下房间背景色,然后调用Enter进入。

    重提一下颜色值是:[1红2黑3蓝]

    void blackChair_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                
    if (!BlackPlayerInChair)
                {
                    BlackPlayerInChair 
    = true;
                    blackChair.Fill 
    = new RadialGradientBrush(Colors.Blue , Colors.White);
                        
    //new SolidColorBrush(Colors.Blue);
                    Enter(2);
                }
                
    else
                {
                    MessageBox.Show(
    "黑色玩家已有人!");
                }
            }

    旁观者位置:一点进去了,当然了,如果以后要增加房间人数上限,还是要加判断的

    void spectatorChair_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                Enter(
    3);
            }

    红色位置:和黑色位置一样的判断方法

    void redChair_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                
    if (!RedPlayerInChair)
                {
                    RedPlayerInChair 
    = true;
                    redChair.Fill 
    = new RadialGradientBrush(Colors.Blue, Colors.White);
                        
    //new SolidColorBrush(Colors.Blue);
                    Enter(1);
                }
                
    else
                {
                    MessageBox.Show(
    "红色玩家已有人!");
                }
            }

    三个座位的点击事件都完成了,接下来要完成Enter方法了:

    于由进入房间时,需要用WCF通讯告知服务端,所以要先转入WCF,添加服务端EnterRoom事件

    回到GameService项目的IService.cs里,添加两个接口,进入房间和退出房间:

    接口的参数都是一样的,一个玩家,和一个玩家要进入/退出的房间号。

    [OperationContract]
    bool EnterRoom(Player player,int roomID);

    [OperationContract(IsOneWay 
    = true)]
    void OutRoom(Player player, int roomID);

    接下来就是到到IService.svc.cs里实现接口了:

    接着,我们要定义一个全局变量,有来保存所有发生变化的房间列表:

    什么叫发生变化?就是房间默认是没人坐上去,如果有人进入房间,房间状态就发生变化了,这时我们就要记录下来,同时,要更新到

    所有在线玩家的房间里去。

    /// <summary>
    /// 所有变化的房间列表
    /// </summary>
    private static Dictionary<int, Room> roomList = new Dictionary<int, Room>();

    看到一个Room没有,既然要保存房间列表,所以我们得创建一个和Player一样的[契约数据]实体用于传递Room

    我们对着文件夹DataContract右键->添加类->输入:Room.cs

    为房间实体类添加几个属性:

    ID:房间号

    Count:房间人数

    RedInChair:红色座位是否有人

    BlackInChair:黑色座位是否有人

    就四个属性,相当的简洁吧,接下来实现,这里一样去掉了文件夹的命名空间[.DataContract]:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Runtime.Serialization;

    namespace GameService
    {
        [DataContract]
        
    public class Room
        {
            
    /// <summary>
            
    /// 房间ID
            
    /// </summary>
            [DataMember]
            
    public int ID
            {
                
    get;
                
    set;
            }
            
    /// <summary>
            
    /// 房间人数
            
    /// </summary>
            [DataMember]
            
    public int Count
            {
                
    get;
                
    set;
            }
            
    /// <summary>
            
    /// 红色座位是否有人
            
    /// </summary>
            [DataMember]
            
    public bool RedInChair
            {
                
    get;
                
    set;
            }
            
    /// <summary>
            
    /// 黑色座位是否有人
            
    /// </summary>
            [DataMember]
            
    public bool BlackInChair
            {
                
    get;
                
    set;
            }
        }
    }

    同时呢,我们要为Player[契约数据]实体增加一个属性:颜色值,就是当前用户的进入房间后,自身的颜色就生变化了。

     /// <summary>
           
    /// 玩家颜色[0无色,1红,2黑色,3蓝色]
           
    /// </summary>
           [DataMember]
           
    public int ColorValue
           {
               
    get;
               
    set;
           }

    好了,玩家增加了一个颜色属性,房间实体也有了,全局的房间列表变量也加了。接下来要实现进入房间EnterRoom方法了。

    说明写的够仔细了,小看一会就明白了,其实就是改变房间状态了。还有一些事件通知,我们后面再实现。

     public bool EnterRoom(Player player, int roomID)
            {
                
    bool roomInDic = roomList.ContainsKey(roomID);//房间列表里有没有
                Room room = roomInDic ? roomList[roomID] : new Room();//有就直接拿了,没有就直接New一个新的
                if (!room.RedInChair)//房间的红色座位有没有人
                {
                    room.RedInChair 
    = player.ColorValue == 1;
                }
                
    if (!room.BlackInChair)//房间的黑色座位有没有人
                {
                    room.BlackInChair 
    = player.ColorValue == 2;
                }
                
    if (!roomInDic)//房间列表里没有,添加到房间列表中
                {
                    room.ID 
    = roomID;
                    roomList.Add(roomID, room);
                }
                
                
    //ChangeRoom(player, roomID);改变玩家的房间标记,待会实现

                
    //以下是我们以后要实现的。
                
    //Notify.Room(true, playerList, room, player);//提示房间内:有玩家进入
                
    //if (room.RedInChair && room.BlackInChair)//如果房间红和黑色都有人了。
                
    //{
                
    //    Notify.Game(playerList, player, GameType.Start);//提示对方可以开始游戏。
                
    //}
                return true;
            }

    接下来实现退出房间OutRoom方法,同样的也是改变房间的状态:

    public void OutRoom(Player player, int roomID)
            {
                
    if (roomID > 0)
                {
                    Room room 
    = roomList[roomID];
                    
    if (player.ColorValue == 1)//如果退出玩家是红色座位
                    {
                        room.RedInChair 
    = false;
                    }
                    
    if (player.ColorValue == 2)//如果退出玩家是红色黑色座位
                    {
                        room.BlackInChair 
    = false;
                    }
                   
    // ChangeRoom(player, 0);改变玩家的房间标记,待会实现
                    
    //Notify.Room(false, playerList, room, player);//提示房间内:有玩家退出

                }
            }

    OK,接下来我们来完成一个共同的方法叫:ChangeRoom

    意思就是当用户从不同的房间切换,就是进入或退出房间。

    以下四行代码、四行说明结束函数。

     public static void ChangeRoom(Player player, int roomID)
     {
        RemovePlayer(player);
    //在全局列表中移除原有的用户
        AddPlayer(player, roomID);//在新的房间增加新用户
        roomList[player.RoomID].Count = playerList[player.RoomID].Count;//原来房间人数变化
        roomList[roomID].Count = playerList[roomID].Count;//新加入的房间人数变化
    }

    方法有了,上面的EnterRoom和OutRoom的两行ChangeRoom的注释可以去掉了,成了:

    ChangeRoom(player, roomID);//改变玩家的房间标记,待会实现,这是进入房间的注释

    ChangeRoom(player, 0);//改变玩家的房间标记,待会实现,这里退出房间的注释

    OK,现在可以编绎一下代码,编绎后我们要在客户端更新一下服务引用。

    &

    由于在进入房间后,我们要进入Index页面,所以我们要新建一个Index.xaml了:

    Silverlight项目右键->添加新建项->Silverlight用户控件->输入:Index.xaml[新建的控件目前是一片空白的]。

    原来的MainPage.xaml我们把它删了吧,使命完成了,该回家吃饭了。

    接着我们回到GameRoom.cs代码里,去实现我们的Enter方法:

    代码相当的简单,就是调用WCF服务的EnterRoom,完成后转向Index页面了。

     /// <summary>
            
    /// 进入房间
            
    /// </summary>
            
    /// <param name="colorValue">颜色[0无色,1红,2黑色,3蓝]</param>
            void Enter(int colorValue)
            {
                App.player.ColorValue 
    = colorValue;
                App.client.EnterRoomCompleted 
    += new EventHandler<GameService.EnterRoomCompletedEventArgs>(client_EnterRoomCompleted);
                App.client.EnterRoomAsync(App.player, RoomID, RoomID);
            }

            
    void client_EnterRoomCompleted(object sender, GameService.EnterRoomCompletedEventArgs e)
            {
                
    if (e.Result)
                {
                    App.player.RoomID 
    =RoomID;
                    ((App)Application.Current).RedirectTo(
    new Index());
                }
                
    else
                {
                    App.player.ColorValue 
    = 0;
                    MessageBox.Show(
    "房间已有人!");
                }
            }

     我们运行F5一下,看看效果:

    起动正常,输入上面的昵称后登陆

    看到房间列表,我们随便点一下进去

    看到一片空白,说明我们已进入到房间里面去了。

    至此,本小结结束,下节,我们来实现房间的通知更新。

    版权声明:本文原创发表于 博客园,作者为 路过秋天 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
    个人微信公众号
    创业QQ群:617713515
    Donation(扫码支持作者):支付宝:
    Donation(扫码支持作者):微信:
  • 相关阅读:
    weblogic weak_password 复现
    redis 4-unacc 复现
    Django debug page XSS漏洞(CVE-2017-12794)复现
    (CVE-2016-4437)Apache Shiro <=1.2.4 反序列化漏洞复现
    Apache SSI 远程命令执行漏洞复现
    Apache HTTPD 未知后缀解析漏洞复现
    s2-005复现
    05 跨站请求伪造漏洞CSRF
    安全大面
    JAVA基础学习day03--流程控制语句
  • 原文地址:https://www.cnblogs.com/cyq1162/p/1778711.html
Copyright © 2011-2022 走看看