Silverlight+WCF 新手实例 象棋 房间状态更新(二十)

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

 

这节开始,标题里就去掉"回归WCF通讯应用"几字了。

 

上节我们成功实现了进入房间,服务端也收到用户进入房间的请求了,这节,我们服务端收到进入房间请求后,通知在房间大门外的人更新房间状态。

我们要增加一个回调方法,ICallBack接口那,忘记的人回去看看WCF通讯那几篇(十四到十七节)。

方法如下,以前说过了,回调的方法是给客户端实现的,服务端只管调就行了:

using System.ServiceModel;

namespace GameService
{
    interface ICallBack
    {
        [OperationContract(IsOneWay = true)]
        void NotifyRoomUpdate(Room room);
    }
}

 

那我们回到服务端进入房间的代码,只管调用一下了:

我们看下这段进入房间代码:


 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);//改变玩家的房间标记,待会实现

            //这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
            foreach (KeyValuePair<Guid,Player> item in playerList[0])
            {
                item.Value.CallBack.NotifyRoomUpdate(room);
            }
            return true;
        }

 

foreach之前的代码是上节的了,这里我们只增加了一个foreach来循环0房间的用户,通知他们更新房间状态。

同样的,如果是退出房间,也要加一个foreach,代码如下:


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);//改变玩家的房间标记,待会实现

                //这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
                foreach (KeyValuePair<Guid, Player> item in playerList[0])
                {
                    item.Value.CallBack.NotifyRoomUpdate(room);
                }

            }
        }

 

当我们看到同样的代码循环重复的出现的时候,我们会感到皮痒,我们得把它封装起来,弄成一个小函数调用。

于是,我新建了一个Notify通知类。用于把所有的通知都集成到这里来。

皮痒了,GameService项目里新建一个类[示例源代码里会放到一个文件夹Notify下]:

namespace GameService
{
    /// <summary>
    /// 通知 by 路过秋天
    /// </summary>
    public class Notify
    {

    }
}

 

我们添加一个新方法,叫Room, 我们把那foreach的方法Copy过来,就是如下代码了:


namespace GameService
{
    /// <summary>
    /// 通知 by 路过秋天
    /// </summary>
    public class Notify
    {
        internal static void Room(Dictionary<int, Dictionary<Guid, Player>> playerList, Room room)
        {
            //这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
            foreach (KeyValuePair<Guid, Player> item in playerList[0])
            {
                item.Value.CallBack.NotifyRoomUpdate(room);
            }
        }
    }
}

 

有了这个,我们回去把房间进入的和退出的foreach都改成Notify.Room(playerList,room);就OK了。

大伙自己改了,这里不再贴代码出来了。

 

成了,服务端写完了,那客户端要实现回调的方法的,我们编绎一下GameService项目,不编绎是不行的,我们加了接口,

客户端得“更新服务引用”,

怎么更新?以前截过图的,回去看上一节:Silverlight+WCF 新手实例 象棋 回归WCF通讯应用-进入房间(十九)

好了,回客户端了,回哪?当然回到Room.xmal那了,我们要更新房间的状态的。


namespace NewChessProject
{
    public partial class Room : UserControl
    {
        public Room()
        {
            InitializeComponent();
            Game game = new Game();
            game.CreateGameRoom(30);
            game.DrawIn(LayoutRoot);

            //这里实现ICallBack的方法
            App.client.NotifyRoomUpdateReceived += new EventHandler<GameService.NotifyRoomUpdateReceivedEventArgs>(client_NotifyRoomUpdateReceived);
        }

        void client_NotifyRoomUpdateReceived(object sender, GameService.NotifyRoomUpdateReceivedEventArgs e)
        {
            //看这里看这里,这里实现啦
        }

    }
}

 

这里等待服务端调用时,执行的方法了,现在实现了。

嘿嘿,皮又痒了,三行的代码,又封装出一个UpdateRoomState方法来了。


 void client_NotifyRoomUpdateReceived(object sender, GameService.NotifyRoomUpdateReceivedEventArgs e)
        {
            //这里实现啦
            if (game.GameRoomList != null && e.room != null)
            {
                UpdateRoomState(e.room, game.GameRoomList[e.room.ID - 1]);
            }
        }
        void UpdateRoomState(GameService.Room gsRoom, GameRoom room)
        {
            room.RedPlayerInChair = gsRoom.RedInChair;
            room.BlackPlayerInChair = gsRoom.BlackInChair;
            room.ReDraw();
        }

 

最后还调用了room的ReDraw()方法。咦?room是没这个方法的,没有就加,咦什么咦。

回到GameRoom.cs里去,加个ReDraw方法,就两行代码了,大伙别急:


public void ReDraw()
{
redChair.Fill = new RadialGradientBrush(RedPlayerInChair ? Colors.Blue : Colors.Red, Colors.Transparent);
blackChair.Fill = new RadialGradientBrush(BlackPlayerInChair ? Colors.Blue : Colors.Black, Colors.Transparent);
}

 

OK,客户端写完了,我们F5运行看结果:

启动一个浏览器,登陆后我们不动,同时复制地址,新开一个浏览器,也登陆进去如下图:



好,我们点击第二个浏览器进去第一个红色房间:



看,第一个房间的状态变了。至此,我们顺利完成了房间状态的通知更新。

那退出房间哪去了?别急,Index页面还没东西呢。

 

版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:http://www.cnblogs.com/cyq1162/archive/2010/07/19/1780733.html

时间: 2024-12-31 12:50:31

Silverlight+WCF 新手实例 象棋 房间状态更新(二十)的相关文章

Silverlight+WCF 新手实例 象棋 主界面-事件区-游戏开始(二十七)

本专题出产简单原由: 一开始的初衷,只是想写个简单的单机BS人机对战版的,开始还下了点AI算法看看的: 但是写到最后,都写成了通讯版本的对战了,只因中间不小心看到了WCF的相关内容,顺便加了进来; 最后就定局了,反正新手实例,能加多点内容就加多点了. 关于原始初衷,后期再补上了.       好了,先上几个附加索引: 1:Silverlight+WCF 新手实例 象棋 在线演示 2:Silverlight+WCF 简单部署问题集 3:Silverlight4 ListBox bug 4:Silv

Silverlight+WCF 新手实例 象棋 获取房间状态列表更新(二十一)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   上节是当有用户进入某个房间时,我的某个房间状态被通知,并被通知更新. 这节说说首次进入房间大厅时,我们自己创建了N个房间,默认都是初始状态的,这时我们需要获取服务端的所有已更新的房间状态, 下到本地之后,进行批量更新状态.   于是开始了,首先从服务端开始,我们要获取所有已更新的房间,于是到WCF服务端添加一个方法: 到IService.cs添加方法接口 [OperationContract] Dictionary<in

赶紧接着上一节:Silverlight+WCF 新手实例 象棋 主界面-实时聊天区(二十五) 这节我们实现上节没实现的纠结的进出房间的消息提示 我们清楚的知道,我们每个区都是一个用户控件,我们的在线用户进出时,得到聊天区域显示信息,这就涉及到用户控件之间的消息传递了。 在线用户区说:反正我是

赶紧接着上一节:Silverlight+WCF 新手实例 象棋 主界面-实时聊天区(二十五)  这节我们实现上节没实现的纠结的进出房间的消息提示 我们清楚的知道,我们每个区都是一个用户控件,我们的在线用户进出时,得到聊天区域显示信息,这就涉及到用户控件之间的消息传递了. 在线用户区说:反正我是没权直接去实时聊天区写东西,没办法,找中介委托设置一下了. 那谁是中介呢?委托谁呢?当然是衣食父母Index.xaml了,是它撑着整个家庭的. 好了,知道中介了,那我就签个委托书了: 回到OnlineUse

Silverlight+WCF 新手实例 象棋 主界面-状态重置(三十四)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   正如我们在:Silverlight+WCF 新手实例 象棋 主界面-事件区-求和认输(三十二)里面提到的一样: "游戏结束了,要干点什么呢?当然就是棋盘复位了,按钮重置了,如果还有棋谱之类的,全都得重置.这些,我们留下到另一节优化处理吧."   所以,本节就做这些手尾工作了. 由于游戏结束,我们复位的工作很多,至少有N个控件需要复位,因此,Silverlight+WCF 新手实例 象棋 主界面-控件消息传递(二

Silverlight+WCF 新手实例 象棋 主界面-棋谱-获取列表(三十八)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   在Silverlight+WCF 新手实例 象棋 主界面-棋谱-布局写谱(三十六)中,我们完成下棋双方的棋谱显示,这节,我们为观众增加棋子列表: 观众进入房间后,第一时间当然也要获取棋步列表了,不然进来干麻呢?你当这是聊天室啊,光聊天不看棋.   首先,当然是要在服务端添加一个获取棋步列表的接口方法了: WCF服务端,IService.cs:  /// <summary>     /// 服务端方法接口 by 路过秋天

Silverlight+WCF 新手实例 象棋 介绍III(二十三)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   虽然有在线演示,不过还是要写一个介绍,因为并没有实时更新到在线演示 说是介绍,其实就是阶段进度报告,现在看一下最近的更新吧: 先来总体截一下图看看变化吧: 1.登陆: 增加了初始作者文字显示[没用户时默认文字],和在当前线用户数显示. 我开了三个浏览器窗口才截到这图. 2:房间: 这里从QQ象棋里弄了两张背景图过来,换了一下之前的房间背景,如果是游戏对战中,桌面背景就变成了: 3:增加倒计时子窗口实现,替换掉了Messa

Silverlight+WCF 新手实例 象棋 主界面-在线用户区(二十四)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 演示已更新到此节介绍:Silverlight+WCF 新手实例 象棋 介绍III(二十三)   这节我们来实现在线用户区的显示,把上两节介绍那张图再弄来,看在线用户区是哪块:   一眼扫过看到了,是第四区,现在开始了,还是上次下棋区域一样的逻辑,往Index.xaml里拉一个Board控件,然后后台写两行代码代码一下. 当然了,得新建一个用户控件:就叫:OnlineUser.xaml,好,空白的在线用户建完了,下面还是两步实

Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放-结局(四十)

查看本系列其他相关文章请点击:Silverlight+WCF 新手实例象棋专题索引 在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 在Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)中,我们实现了用户的棋谱回放,在文章的下面,我们曾留下了两个问题: 下棋者在下棋过程,要不要开放"回放"功能,如果开放,需要注意什么? 观众在回放过程中,突然又传来一个棋步,需要注意什么? 在解答这两个问题之前,我们先来解答上一篇的截图中发现的问题: 不知

Silverlight+WCF 新手实例 象棋 该谁下棋-B下A停(三十)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   上上一节,就是二十八节:Silverlight+WCF 新手实例 象棋 该谁下棋-A下B停(二十八)   我们实现了"开始"游戏后,对棋子的限制,A下B停 这节,我们要实现:B下A停,[同时,传递棋步,对方收到棋步,要反转棋步坐标,自动移动棋子] 所以呢,这节我们要实现的东西是比上上一节相对多一点.   少废话,开始了: 按流程来了,A移动棋子之后,要干点什么事呢? //-------这是一个AB同样的循环流程