Silverlight+WCF 实战-网络象棋最终篇之十字轨迹(一)

前言


继之前Silverlight+WCF 新手实例 象棋系列四十篇之后,一个多月的时间都在写CYQ.Data框架系列[CYQ.Data 轻量数据层之路 框架开源系列 索引],

让各位对该Silverlight+WCF 象棋系列有兴趣的网友久候了,上一系列详见:[Silverlight+WCF 新手实例 象棋 专题索引]

今天开始就在之前四十篇续上,直到把 [Silverlight+WCF 新手实例 象棋 在线演示] 上的最新代码写完,谢谢支持!

 

乱七杂八说两句:

一个多月没碰VS2010了,今天回头看原来的象棋系列代码,感觉到有点陌生了,

好多原来的思路,都忘的差不多了,要续写这系列文章,感觉还得像个新手一样重温下代码才行呢。

本系列为进阶优化系列,会在原来的基础上,慢慢改动很多代码的哦,欢迎持续关注!

 

正文:

我们先回顾下,截一张上一系列 最后一节[Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放-结局(四十) ]里的一张图片先:

 

OK,从这图片我知道双方是在下棋了,可是我们并不知道现在该谁下了?

当然了,认真看一下棋谱,还是知道刚刚是黑方下了一步,不过还是要很用力的猜车一平二是怎么个平法。

十字轨迹的出现,解决了这个问题,如果到QQ平台下过棋,也见过的,就是那个棋子周围加上的一个边框了,那这个为啥叫十字轨迹?这个这个...

 

 

好!大伙知道十字轨迹是什么就好了,现在说说实现思路

大伙想啊,十字轨迹是在棋步移动之后,在棋盘上就有两个出现了,一个在移动的棋子的原来位置,一个在移动后的位置,而且整个棋盘就只能有两个,于是,我们的思路定位就很简单了。

一:在棋盘上先创建好两个十字轨迹,默认隐藏

二:在棋手移动完棋子之后,把两个十字轨迹移动到相应的位置

 

 

就这么两步,很简单吧,该出手时就出手。

 

实现步骤如下:

 

一:棋盘Board类画十字轨迹

 

1:增加两个十字轨迹属性


   /// <summary>
    /// 棋盘 by 路过秋天
    /// http://cyq1162.cnblogs.com
    /// </summary>
    public class Board
    {
        /// <summary>
        /// 十字轨迹框
        /// </summary>
        public Canvas TrackFrom
        {
            get;
            set;
        }
        /// <summary>
        /// 十字轨迹框
        /// </summary>
        public Canvas TrackTo
        {
            get;
            set;
        }
        //下面省略N多代码
     }

2:增加一函数,用于画十字轨迹


        private void DrawTrack(Panel panel)
        {
            double width = panel.Width - 8;
            //横线4条
            DrawLine(0, 0, width / 4, 0, 3, panel, false);//L-
            DrawLine(0, width, width / 4, width, 3, panel, false);//LB-
            DrawLine(width * 3 / 4, 0, width, 0, 3, panel, false);//R-
            DrawLine(width * 3 / 4, width, width, width, 3, panel, false);//RB-

            //直线四条
            DrawLine(0, 0, 0, width / 4, 3, panel, false);//L| ok
            DrawLine(width, 0, width, width / 4, 3, panel, false);//R| ok
            DrawLine(0, width, 0, width * 3 / 4, 3, panel, false);//LB|
            DrawLine(width, width * 3 / 4, width, width, 3, panel, false);//RB|
        }

说明:

画这么个框,记得以前还真费了不少劲,在那调坐标和宽度;

注意哦,DrawLine方法变成5个参数了,以前只有四个的。

3:DrawLine方法小调整


        private void DrawLine(double x1, double y1, double x2, double y2)//保留原有方法原型,不用改其它画线代码
        {
            DrawLine(x1, y1, x2, y2, 1, container, true);
        }
        private void DrawLine(double x1, double y1, double x2, double y2, int thick, Panel panel, bool auto)
        {
            double tempGap = ((x1 + y1) > 19 || !auto) ? 1 : gap;//就这行加了一个!Auto,其它没变过
            Line line = new Line()
            {
                X1 = x1 * tempGap + marginLeft,
                Y1 = y1 * tempGap + marginTop,
                X2 = x2 * tempGap + marginLeft,
                Y2 = y2 * tempGap + marginTop,
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = thick
            };
            panel.Children.Add(line);
        }

说明:

增加一个auto是干虾米用的呢?这是因为在画十字轨迹时,我们传进的是实际像素值,然而又可能出现x1+y1<19的情况,为了保证它是按像素计算,所以...你懂的!

还有,为啥是19,其实应该是17[数一下横线+直线有多少条,索引从0开始],这个问题在以前就说过了,这里不多解释了,保留19也没错。

4:初始化画棋盘时,把十字轨迹也画上


        private void Draw()
        {
            //省略画棋盘线代码
      
            #region 画棋步轨迹
            //创建两个十字修饰框
            TrackFrom = new Canvas()
            {
                Width = gap,
                Height = gap,
                Margin = new Thickness(-marginLeft * 12, -marginLeft * 12, 0, 0)
            };
            TrackTo = new Canvas()
            {
                Width = gap,
                Height = gap,
                Margin = new Thickness(-marginLeft * 12, -marginLeft * 12, 0, 0)
            };
            DrawTrack(TrackFrom);
            DrawTrack(TrackTo);
            container.Children.Add(TrackFrom);
            container.Children.Add(TrackTo);
            #endregion
            #region 画楚河汉界
              DrawFont("路过秋天");
            #endregion
        }

 

二:Chess象棋类增加设置十字焦点方法

 

1:增加设置十字焦点方法


        /// <summary>
        /// 设置轨迹十字框
        /// </summary>
        public void SetFocus(Point from, Point to)
        {
            from = SwitchPixelArray(from);
            to = SwitchPixelArray(to);
            double offset = Board.TrackFrom.Width / 2 - Board.marginLeft * 11 - 4;//要减去默认初始位置,默认是*-12
            Canvas.SetLeft(Board.TrackFrom, from.X - offset);
            Canvas.SetTop(Board.TrackFrom, from.Y - offset);
            Canvas.SetLeft(Board.TrackTo, to.X - offset);
            Canvas.SetTop(Board.TrackTo, to.Y - offset);
        }

 

说明:

在移动棋步的时候,我们调用一下这个方法,把两个轨迹移动到相应的位置就OK了,

重点是:移动时,要减去原来的默认初始的位置,这个调整起来很麻烦。

 

三:ChessAction棋子动作类

 

1:棋手移动时调用设置十字轨迹焦点函数


        /// <summary>
        /// 移动棋子
        /// </summary>
        /// <param name="chessman">棋子</param>
        /// <param name="toX">移动到X坐标</param>
        /// <param name="toY">移动到Y坐标</param>
        public bool MoveTo(Chessman chessman, Point moveTo)
        {
            if (Rule.IsCanMove(chessman, moveTo))
            {
                chessman.ReadyMove = false;
                chessman.chessman.Background = null;
                PlayMove(chessman, moveTo);
                Parent.SetFocus(chessman.MovePoint, moveTo);//就这一行代码增加
                HelpMoveStepEvent(chessman, moveTo);
                chessman.MovePoint = moveTo;
                
                return true;
            }
            return false;
        }

 

2:对方棋手下棋手,系统会自动移动棋子,也要自动设置十字轨迹焦点


       /// <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);
                Parent.SetFocus(from, to);//就这一行代码增加
                chessman.MovePoint = to;
                if (eatChessman != null)
                {
                    SetIsGameEnd(eatChessman);
                    eatChessman.GoToDead();
                }
            }
        }

 

四:F5看运行结果

 

1:运行后直接上图了

OK,大伙看到效果了吧!

 

版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:

http://www.cnblogs.com/cyq1162/archive/2010/10/11/1847625.html

时间: 2024-12-02 15:46:45

Silverlight+WCF 实战-网络象棋最终篇之十字轨迹(一)的相关文章

Silverlight+WCF 实战-网络象棋最终篇之房间装修-Silverlight端[带第九阶段源码](三)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 上一系列四十篇索引:Silverlight+WCF 新手实例 象棋 专题索引     本篇紧接着上一篇:Silverlight+WCF 实战-网络象棋最终篇之房间装修-WCF端(二) 继续为房间进行如下的装修:   代码实现[Silverlight端] 说明: 由于更换背景引入图片,房间的属性发生了较大的变化,由此引发了客户端房间类较大的改动.     1:Silverlight端:GameRoom类大调整[被注释的是原来的

Silverlight+WCF 实战-网络象棋最终篇之对战视频-下篇[客户端发送与服务端中转](六)

本篇继上一篇:Silverlight+WCF 实战-网络象棋最终篇之对战视频-上篇[客户端开启视频/注册编号/接收视频](五)    一:对战视频 简单原理 略,内容见上篇.   二:对战视频 步骤解析: 略,内容见上篇.   三:对战视频 具体实施 1:如何打开视频 略,内容见上篇.   2:Silverlight如何使用Socket进行通讯 2.1:与远程建立链接: 2.2:注册编号[这里的规则是"房间号+棋手颜色值"] 2.3:开新线程,等待接收对方视频 2.4:将视频显示出来,

Silverlight+WCF 实战-网络象棋最终篇之对战视频-上篇[客户端开启视频/注册编号/接收视频](五)

前言: 近期在忙点"秋色园"的事情,所以网络象棋这一块文章就写的相对慢,而且刚好接上篇:Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四)  之后, 是一些代码修改,会比较枯燥,所以没接着写,不过有昨天有网页表示对象棋在线演示中的 对战视频 感兴趣,希望可以提前看到代码,所以本次就提前写里面的对战视频这一块. 由于对战视频采用控制台程序,并没有在服务器运行,所以在线演示版本里一进入显示是显示"未链接"的提示. 作者:路过秋天 博客:ht

Silverlight+WCF 实战-网络象棋最终篇之解决重复的消息提示-状态重置(九)

上节留下的问题: 在上一节:Silverlight+WCF 网络象棋 终极篇 解决重复的消息提示(八) 中,我们解决了重复登陆时产生的多次消息的重复提示. 不过由此优化产生的另一个问题:全局只有一个实例,在来回的切换房间或进出时,需要重置状态,我们这节来解决这个问题.     在上节的,我留下了几行这样的注释代码: //loginObj.Reset();//roomObj.Reset();//indexObj.Reset();   本节就顺路把这三个注册的方法给实现了: 1:loginObje.

Silverlight+WCF 实战-网络象棋最终篇之房间装修-WCF端(二)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 上一系列四十篇索引:Silverlight+WCF 新手实例 象棋 专题索引   佛靠金装,人要衣裳,房间也要加金砖.本篇我们来把房间装修下,让它看起来专业一点!   一:效果预览,先上图   这是之前的房间图片: 今天我们要装修成的房间图片: 再上一张游戏中的效果图:   二:实现说明   1:新增加图片 为了实现装修,我这里新增加了3张图片: 1:房间图片 2:房间游戏中状态的图片 3:QQ用户头像 图片是从QQ象棋游戏

Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四)

前言: 在前面的系列中,我们虽然完成了其大部分功能,但是,离正真运行,还是有一大段距离 当你F5运行时,在弹出对话框之后,如果你不即时点确定,或者上个WC回来之后,你会发现已经提示出错了 这节开始,我们将对其进行一小步一小步的优化,来避免一些明显容易引发的错误.   感知一下最原始的消息弹出框如下图:     一:传统消息框,容易引发命案   1:原始的消息框,是线程阻塞类型的,很容易引发超时问题 线程阻塞?怎么理解? 简单的说就是,WCF服务端给客户端发送了消息提示之后,一直进入等待状态,直到

Silverlight+WCF 实战-网络象棋最终篇之解决重复的消息提示(八)

前言: 最近有网友经常会问,在跟着做象棋对战的通讯中,在重复退出进入的时候,消息会重复出现,本节就这问题进行解说与优化.   一:分析问题产生的原因?   1:首先看App.xaml,里面定义了一个全局客户端回调: public static GameService.ServiceClient client;//回调的客户端   并且这个回调我们全局只实例化一次,并且默认加载时定位到登陆页面: private void Application_Startup(object sender, Sta

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

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

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

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   事隔几篇,我们又回到事件区,继续其它两个按钮事件,来张图吧: 在Silverlight+WCF 新手实例 象棋 主界面-事件区-游戏开始(二十七) 和之后的几篇,我们实现了游戏开始, 在这篇之前,基本上双方已可以对战了,看似主体功能已完成.只是,大伙都知道,细节的东西,才是花时间的,漫长的路还在后面....... 如标题所示,这节实现"求和+认输"两个事件.   每次开始,我们都习惯的先写WCF服务端代码,再回