转帖地址:http://www.cnblogs.com/cyq1162/archive/2010/07/07/1773033.html
上节创建显示了一颗棋子,由于没有margin属性,所以只能靠边站。
现在,我们创建一个象棋类,让它包括棋盘和棋子,同时附加几个常用函数。
还是对着Silverlight类库项目右键添加类:Chess.cs
/// 象棋 by 路过秋天
/// </summary>
public class Chess
{
}
既然要包括象棋当然是要包括棋盘和棋子了,于是我们为之加两个属性,棋子有很多颗,所以用List列表。
/// 象棋 by 路过秋天
/// </summary>
public class Chess
{
/// <summary>
/// 棋子列表
/// </summary>
public List < Chessman > ChessmanList
{
get ;
set ;
}
/// <summary>
/// 棋盘
/// </summary>
public Board Board
{
get ;
set ;
}
}
我们再将初始化棋盘的行为放到象棋里来,于是增加一个初始棋盘的方法
里面有个container呢,就是Panel容器了
/// 初始化棋盘
/// </summary>
public void InitBoard()
{
Board = new Board();
Board.DrawIn(container);
}
至于棋子嘛,太多了,不好弄啊。。。36颗棋子,颜色又不一样,想for一下,没规律啊,咋整。。。
难道直接复制36条了。。。-_-...
经过研究发现,棋子的数量有1,2,5三种,颜色只有黑和红,于是折腾出了这么个创建的函数:
第一个参数传数量了。分支里,如果是2个的,位置对称,所以[8-x]就OK,5个的,隔两个位置一颗,于是就这么出来了。
{
if (count == 1 )
{
Chessman chessmane = new Chessman(x, y, radius, color, name, this );
ChessmanList.Add(chessmane);
}
if (count == 2 )
{
Chessman chessmane1 = new Chessman(x, y, radius, color, name, this );
Chessman chessmane2 = new Chessman( 8 - x, y, radius, color, name, this );
ChessmanList.Add(chessmane1);
ChessmanList.Add(chessmane2);
}
else if (count == 5 )
{
for ( int i = 0 ; i < 5 ; i ++ )
{
Chessman chessmane = new Chessman(i * 2 , y, radius, color, name, this );
ChessmanList.Add(chessmane);
}
}
}
注意:
1.参数里还有棋子的半径呢,所以呢,记得在外面再定义一个:
private int radius=15;//棋子半径
2.在Chessman的构造函数里,传进了this自身对象,这是为了在棋子函数里可以调用Chess的方法。
所以我们需要修改下上节的棋子的构造函数,新增加一个传参:
public Chess Parent
{
get ;
set ;
}
public Chessman( double x, double y, double radius, Color color, string name,Chess parent)
{
Parent = parent;
InitPoint = new Point(x, y);
MovePoint = InitPoint;
Radius = radius;
Color = color;
Name = name;
}
好了,现在开始创建黑棋的函数代码相对简洁了一点,这里多了一个int[] y,用来干什么的?
本来啊,一开始是直接写数字的,后来比较了下黑棋和红棋的区别,就是这里的不同,可以交换棋子是在上面还是在下面。
棋子弄好时,只有兵 炮 上面一排或下面一排,其实就是只有6条线上有棋子,而且总是对称的。
{
// 黑色棋 将一个,士、象、车、马、炮各两个,卒五个
CreateChessman( 2 , 0 , y[ 0 ], Colors.Black, " 车 " );
CreateChessman( 2 , 1 , y[ 0 ], Colors.Black, " 马 " );
CreateChessman( 2 , 2 , y[ 0 ], Colors.Black, " 象 " );
CreateChessman( 2 , 3 , y[ 0 ], Colors.Black, " 士 " );
CreateChessman( 2 , 1 , y[ 1 ], Colors.Black, " 炮 " );
CreateChessman( 5 , 0 , y[ 2 ], Colors.Black, " 卒 " );
CreateChessman( 1 , 4 , y[ 0 ], Colors.Black, " 将 " );
}
再看一下红棋的创建函数,其实就一个样,名字不同而已
{
// 红色棋 帅一个,仕、相、车、马、炮各两个,兵五个
CreateChessman( 2 , 0 , y[ 0 ], Colors.Red, " 车 " );
CreateChessman( 2 , 1 , y[ 0 ], Colors.Red, " 马 " );
CreateChessman( 2 , 2 , y[ 0 ], Colors.Red, " 相 " );
CreateChessman( 2 , 3 , y[ 0 ], Colors.Red, " 仕 " );
CreateChessman( 2 , 1 , y[ 1 ], Colors.Red, " 炮 " );
CreateChessman( 5 , 0 , y[ 2 ], Colors.Red, " 兵 " );
CreateChessman( 1 , 4 , y[ 0 ], Colors.Red, " 帅 " );
}
好了,现在可以写出棋子初始化的函数了
/// 初始化棋子
/// </summary>
public void InitChessman()
{
int [] up = new [] { 0 , 2 , 3 }; // 棋子在上面
int [] down = new [] { 9 , 7 , 6 }; // 棋子在下面
CreateBlackChessman(up);
CreateRedChessman(down);
ShowChessman();
}
private void ShowChessman()
{
foreach (Chessman chessmane in ChessmanList)
{
chessmane.DrawIn(container);
}
}
这里就定义了棋子在上面还是下面了,换up和down换一下,棋子上下的位置也会发现变化,这里我们以后再利用。
多了一个ShowChessman(),一个循环而已,抽出来放到函数里了,不喜欢就把循环的代码弄上去,再不喜欢就到
ChessmanList.Add(chessmane);的地方直接DrawIn一下,这样就少了这个函数了。
OK,棋盘和棋子都有了。
增加个构造函数传进入Panel先,还有实例化一个棋子列表,不然就报错啦。
{
container = control;
ChessmanList = new List < Chessman > ( 32 );
}
到界面里调用一下看看效果,silghtlight应用程序的调用代码要变一变了
{
public MainPage()
{
InitializeComponent();
Chess chess = new Chess(canvas1);
chess.InitBoard();
chess.InitChessman();
}
}
F5运行了,出来了。。
yo~~只看到一个帅,还不错,挺帅的。。。
依呀哟,由于我们的原始坐标没有和像素坐标进行转换呢。
好了,在Chess类里增加一个坐标双向转换的函数:
高级用法,本来是加多一个参数true或false来进行是像素-》坐标,还是坐标->像素的。
后来发现坐标x+y怎么也比像素小,所以里面加个判断就搞定了。
里面还要用到棋盘的一些属性,所以方法放到这里来,是比较合适的。
/// 棋子坐标和实际像素交换
/// </summary>
public Point SwitchPixelArray(Point point)
{
if (point.X + point.Y > 17 ) // 最大值x=8,y=9,大于17则为像素 ,转为数组
{
return new Point(((point.X - Board.marginLeft) / Board.gap), ((point.Y - Board.marginTop) / Board.gap));
}
// 转为坐标
return new Point(point.X * Board.gap + Board.marginLeft, point.Y * Board.gap + Board.marginTop);
}
好了,回到之前的棋子类的Draw函数里,为Canvas增加一个Margin属性了。
![](https://i-blog.csdnimg.cn/blog_migrate/81178cc93a2a3bb5048d90d76e7ec935.gif)
{
// 这里实现画啦
Ellipse elp = new Ellipse()
{
Width = Radius * 2 ,
Height = Radius * 2 ,
Stroke = new SolidColorBrush(Color),
Fill = new SolidColorBrush(Color),
Opacity = 15
};
TextBlock text = new TextBlock()
{
TextAlignment = TextAlignment.Center,
Foreground = new SolidColorBrush(Colors.White),
Text = Name,
FontFamily = new FontFamily( " 宋体 " ),
FontSize = Radius,
FontWeight = FontWeights.Bold,
Margin = new Thickness(Radius / 2 - 2 , Radius / 2 - 2 , 0 , 0 )
};
chessman = new Canvas();
Point pixel = Parent.SwitchPixelArray(InitPoint); // 新加的一行
chessman.Margin = new Thickness(pixel.X - Radius, pixel.Y - Radius, 0 , 0 ); // 新加的一行
chessman.Children.Add(elp);
chessman.Children.Add(text);
container.Children.Add(chessman);
}
好了,现在重新运行,F5,看到效果图如下:
好了,棋子终于全部尘埃落地了。
到此,提交第一部分的源码:点击下载