上节创建显示了一颗棋子,由于没有margin属性,所以只能靠边站。
现在,我们创建一个象棋类,让它包括棋盘和棋子,同时附加几个常用函数。
还是对着Silverlight类库项目右键添加类:Chess.cs
///
<summary>
///
象棋 by 路过秋天
///
</summary>
public
class
Chess
{
}
既然要包括象棋当然是要包括棋盘和棋子了,于是我们为之加两个属性,棋子有很多颗,所以用List列表。
///
<summary>
///
象棋 by 路过秋天
///
</summary>
public
class
Chess
{
///
<summary>
///
棋子列表
///
</summary>
public
List
<
Chessman
>
ChessmanList
{
get
;
set
;
}
///
<summary>
///
棋盘
///
</summary>
public
Board Board
{
get
;
set
;
}
}
我们再将初始化棋盘的行为放到象棋里来,于是增加一个初始棋盘的方法
里面有个container呢,就是Panel容器了
Panel container;//归属容器
///
<summary>
///
初始化棋盘
///
</summary>
public
void
InitBoard()
{
Board
=
new
Board();
Board.DrawIn(container);
}
至于棋子嘛,太多了,不好弄啊。。。36颗棋子,颜色又不一样,想for一下,没规律啊,咋整。。。
难道直接复制36条了。。。-_-...
经过研究发现,棋子的数量有1,2,5三种,颜色只有黑和红,于是折腾出了这么个创建的函数:
第一个参数传数量了。分支里,如果是2个的,位置对称,所以[8-x]就OK,5个的,隔两个位置一颗,于是就这么出来了。
private
void
CreateChessman(
int
count,
double
x,
double
y,Color color,
string
name)
{
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的方法。
所以我们需要修改下上节的棋子的构造函数,新增加一个传参:
代码
//
这是棋子类Chessman改动的代码。
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条线上有棋子,而且总是对称的。
private
void
CreateBlackChessman(
int
[] y)
{
//
黑色棋 将一个,士、象、车、马、炮各两个,卒五个
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,
"
将
"
);
}
再看一下红棋的创建函数,其实就一个样,名字不同而已
private
void
CreateRedChessman(
int
[] y)
{
//
红色棋 帅一个,仕、相、车、马、炮各两个,兵五个
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>
///
初始化棋子
///
</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先,还有实例化一个棋子列表,不然就报错啦。
public
Chess(Panel control)
{
container
=
control;
ChessmanList
=
new
List
<
Chessman
>
(
32
);
}
到界面里调用一下看看效果,silghtlight应用程序的调用代码要变一变了
public
partial
class
MainPage : UserControl
{
public
MainPage()
{
InitializeComponent();
Chess chess
=
new
Chess(canvas1);
chess.InitBoard();
chess.InitChessman();
}
}
F5运行了,出来了。。
yo~~只看到一个帅,还不错,挺帅的。。。
依呀哟,由于我们的原始坐标没有和像素坐标进行转换呢。
好了,在Chess类里增加一个坐标双向转换的函数:
高级用法,本来是加多一个参数true或false来进行是像素-》坐标,还是坐标->像素的。
后来发现坐标x+y怎么也比像素小,所以里面加个判断就搞定了。
里面还要用到棋盘的一些属性,所以方法放到这里来,是比较合适的。
///
<summary>
///
棋子坐标和实际像素交换
///
</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属性了。
private
void
Draw()
{
//
这里实现画啦
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,看到效果图如下:
好了,棋子终于全部尘埃落地了。
到此,提交第一部分的源码:点击下载
作者博客:http://cyq1162.cnblogs.com