前言
继之前Silverlight+WCF 新手实例 象棋系列四十篇之后,一个多月的时间都在写CYQ.Data框架系列[],让各位对该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,大伙看到效果了吧!