zoukankan      html  css  js  c++  java
  • 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(00, width / 403, panel, false);//L-
                DrawLine(0, width, width / 4, width, 3, panel, false);//LB-
                DrawLine(width * 3 / 40, width, 03, panel, false);//R-
                DrawLine(width * 3 / 4, width, width, width, 3, panel, false);//RB-


                
    //直线四条
                DrawLine(000, width / 43, panel, false);//L| ok
                DrawLine(width, 0, width, width / 43, panel, false);//R| ok
                DrawLine(0, width, 0, width * 3 / 43, 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 * 1200)
                };
                TrackTo 
    = new Canvas()
                {
                    Width 
    = gap,
                    Height 
    = gap,
                    Margin 
    = new Thickness(-marginLeft * 12-marginLeft * 1200)
                };
                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,大伙看到效果了吧!

    版权声明:本文原创发表于 博客园,作者为 路过秋天 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
    个人微信公众号
    创业QQ群:617713515
    Donation(扫码支持作者):支付宝:
    Donation(扫码支持作者):微信:
  • 相关阅读:
    SDOI Day2
    SDOI Day1
    Codeforces 506E Mr. Kitayuta's Gift (矩阵乘法,动态规划)
    CEOI 2014 wall (最短路)
    BZOJ 3926: [Zjoi20150]诸神眷顾的幻想乡(后缀自动机)
    BZOJ 3925: [Zjoi2015]地震后的幻想乡(概率)
    BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)
    Nginx与Lua的开发
    Nginx访问控制
    Nginx模块
  • 原文地址:https://www.cnblogs.com/cyq1162/p/1847625.html
Copyright © 2011-2022 走看看