上節創建顯示了一顆棋子,由於沒有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屬性了。
{
// 這裏實現畫啦
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