Silverlight+WCF 新手实例 象棋 该何人下棋-A下B停(二十八)

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

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

 

 

上一节,大家兑现了“初步”游戏,并相互打招呼可以开端游戏了;但是大家并没有对棋子举行限定,双方都得以随时的下;

Silverlight+WCF 新手实例 象棋
主界面-棋谱-回放(三十九)
中,大家贯彻了用户的棋谱回看,在小说的上边,我们曾留下了七个难点:

于是,接下去大家要贯彻对棋子的限定,A下B停,B下A停,同时,要传递棋步,对方接到棋步,要反转棋步坐标,还得自动移动棋子。

 

 

1:下棋者在博弈进程,要不要开放“回看”功用,倘使开放,须求小心如何?

说了那样多,大家从哪个地方起始出手吧?其实作者也想了很久……

2:观众在回看进程中,突然又传来三个棋步,须要留意哪些?

让大家回到Chess象棋类,于是添加三本性质IsCanMove

 

图片 1图片 2

 

//象棋类 by 路过冬天
public class Chess
{
        /// <summary>
        /// 是还是不是足以活动棋子
        /// </summary>
        public bool IsCanMove
        {
            get;
            set;
        }

在解答那八个难点此前,我们先来解答上一篇的截图中窥见的题材:

//…省略N多行…

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

}

是由于在每一遍重置chess.Reset的时候,我们从未去掉棋子列表,造成了有再一次的棋子。找到了原因,化解的不二法门就一定的简约了,

 

假诺在chess象棋类里的确Reset方法里,添加一行棋子列表.clear方法清除下就行了,扩张的唯有首先行:

OK,属性有了,大家经过这些特性来决定是否能移动棋子,接着大家回到棋子类Chessman点击事件里,加上限制,无法移动就不让点:

图片 3图片 4

图片 5图片 6

public void Reset()
{
   ChessmanList.Clear();//增添棋子列表清除
   container.Children.Clear();//棋盘和棋子一并清掉了
   InitBoard();//只能再次起头棋盘了
   InitChessman();//只能再一次开端棋子了
   IsCanMove = false;//设置景况不可以活动了
   IsGaming = false;//这几个少了一些忘了
}

 //新加的风浪措施,棋子点击事件
void chessman_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
            if (!Parent.IsCanMove)
            {
                return;
            }

 

//…上边省略N行…
}

好了,一行代码化解了大家上一节隐藏在图片中的bug。

 

 

有了三个特性和二个限量,轻轻松松几行代码,就消除了,接下去的事,就是要控制哪些时候设置IsCanMove的true或false了.

接下去,大家要对上节留给的三个难题做一下解答了:

OK,让大家回来[上一节]点击”初始“的事件里,找到收到”回复可以起来“的代码里,既然可以伊始了,那那几个天性就要设置为true了。

作者们把标题逐一倒一下,先解答第四个难题啊:观者在回放进度中,突然又不胫而走3个棋步,要求注意哪些?

小编们回到伊夫ntButton.xaml.cs代码里:

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

图片 7图片 8

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

void client_NotifyStartGameReceived(object sender, GameService.NotifyStartGameReceivedEventArgs e)
        {
            //收到新闻了应该咋办
            switch (e.player.AttachInfo)
            {
                //…省略N行代码…                    
                    case “11”:
                    MessageBox.Show(“对方同意初始游戏,请开始下棋”, “游戏公告”, MessageBoxButton.OK);
                    btnGameStart.IsEnabled = false;
                    //那里设置一下Chess.IsCanMove=true;
                    break;
            }
        }

 

 

而上节中,小编只说了后头会用到[很后哦],所以,那节我们要用到了,因为那一个变量可以解答标题:

看清楚罗,就在对方同意早先游戏后,大家要安装为true,那样就足以下棋了,不过咱们的chess对象,在此外三个下棋区控件里,怎么传递音信?

我们即使:当客官在回看棋步的进度中,棋手双方在不停的博弈,不断的传递新的棋步过来;

我们在Silverlight+WCF 新手实例 象棋
主界面-控件音讯传递(二十六)
那节就讲过了,不懂的回来再看看……

那儿,大家仅必要处理的,只是不实施自动播放而已,至于写棋谱区文字和增加到棋谱列表的照常就行了。

 

 

可是呢,本次我们换此外一种艺术来传递消息,终归那特性格或许说chess类是个相比较紧要的类,遍地都大概用到,我们不大概处处委托人的,五次五遍的嘱托人家固然了,件件事都来寄托人家就烦了,代码长了也烦。

为此,大家要做的工作就是:早先广播时,设置App.chessManualPlaying为true;播放完结后,设置为false;

 

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

那用什么样方式?还记得大家的player和client对象没?它们四处都可以每一日用的。所以了,回到App.xmal.cs里,加多三个全局变量了:

图片 9图片 10

有没有发现,近期自身变聪明了,平日性的大约在此在此之前的代码,来让机要的代码变的更直观一点。

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

图片 11图片 12

 

public partial class App : Application
{
        Grid root = new Grid();
        public static GameService.ServiceClient client;//回调的客户端
        public static GameService.Player player;//当前玩家
        public static ChessNewInstance.Chess chess;//象棋类,新扩充的
        public App()
        {
            //…省略…
        }
}

于是大家再回去播放完成时的代码增添:

 

图片 13图片 14

那时候巴塞罗那的苍天在不停的闪雷…

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

 

 

OK,全局也有了,那在哪个地方为这么些大局赋值,总不可以拿3个Null对象到到调吧。

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

为此,大家回去Chess.xaml.cs里,在实例化Chess的地方,为这些大局赋一下值:

收下棋步的布告在Chess.xaml.cs里,大家只要求丰裕半行代码[下面的!App.chessManualPlaying]:

代码较短,就全部Copy进来:

图片 15图片 16

图片 17图片 18

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

public partial class Chess : UserControl
    {
       ChessNewInstance.Chess chess;//那里咱们同时把它涉及全局对象
        public Chess()
        {
            InitializeComponent();
            chess = new ChessNewInstance.Chess(canvasRoot);
            chess.InitBoard();
            chess.InitChessman();
            canvasRoot.Width = chess.Board.Width;
            canvasRoot.Height = chess.Board.Height;
            App.chess = chess;//为大局对象赋值
        }
    }

 

 

其次个难点,至此就化解了,总共添加了2.5行代码。

全体就绪,以往得以随地用App.chess对象了,于是大家茅塞顿开到伊芙ntButton.xaml.cs里,只为了加一行代码:

 

图片 19图片 20

当今重返第三个难题了:下棋者在博弈进度,要不要开放“重放”功效,如若开放,须要小心怎么着?

void client_NotifyStartGameReceived(object sender, GameService.NotifyStartGameReceivedEventArgs e)
        {
            //收到音信了应当咋办
            switch (e.player.AttachInfo)
            {
                //…照样省略N行…

不开放:只须求把“回放”按钮启用情形设置为false就行了;

                case “11”:
                    MessageBox.Show(“对方同意初阶游戏,请先导下棋”, “游戏文告”, MessageBoxButton.OK);
                    btnGameStart.IsEnabled = false;
                    App.chess.IsCanMove=true;//那里设置一下,就加这一行
                    break;
            }
        }

绽放:其实也一见倾心:大家如若限制在播报进度中,不让棋手下棋就行了,

 

同时棋手播放进程也会时有暴发第三个难点:不过,大家刚刚已经消除,加的代码对大师也是同样有效。

 

 

OK,到那里,大家得以F5一下看一下成效,又要开始截图了:

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

我们密切看一下图,看一下会话哦:

是否感觉和第一个难点太相像了?下手吧,依然播放早先和终止,只可是,也要追加三个变量,来存棋手的对弈状态:

图片 21

追加一行全局变量:

棋子区的图就不别截了,细看一下对话区,由于大家只兑现了一有个别,A可以下,B停。所以近来永远是其一情景,A可以直接下,B一贯信停。

图片 22图片 23

这些情状大家要留到下节来拍卖状态,倘诺细看,还会发觉,双方头顶上都以紫色棋子,相当于说双方用的都以乙丑革命棋???

 public partial class ChessManual : UserControl
    {
       //…省略2行代码…
        bool tempIsCanMove;//保存棋手从前的景况
        public ChessManual()
        {
            //…省略N行代码…

本条嘛,大家也另开小节来讲解罗。

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

 

播音时,先取状态,再安装IsCanMove=false[那句在Reset重置里已经有了,可以省了];

图片 24图片 25

 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();
            }
        }

 

继而播放已毕时,状态设置回来[末段一行代码]:

图片 26图片 27

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:棋手正下棋不久:

图片 28

 

2:观者进入了,播放了棋步,定位到实时气象:

图片 29

 

3:观者想看下棋进度,开首“回看”棋步:

图片 30

 

4:“回看”到第壹步棋中:

图片 31

 

5:回看到第4、步棋中:

图片 32

 

OK,截图到就到此了,本连串文章,一不小心就写了40节了,在这一连串的40节里,全体机能已通通的开放源码并主讲完了!

 

 

有趣味的读者欢迎关注本连串小说,明天公司又要搬家了,本种类有没有继续小说,近来情状不明……

 

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