Silverlight+WCF 新手實例 象棋 棋子定位與象棋類(四)

上節創建顯示了一顆棋子,由於沒有margin屬性,所以只能靠邊站。

現在,我們創建一個象棋類,讓它包括棋盤和棋子,同時附加幾個常用函數。

還是對着Silverlight類庫項目右鍵添加類:Chess.cs

///   <summary>
    
///  象棋 by 路過秋天
    
///   </summary>
     public   class  Chess
    {

    }

 

既然要包括象棋當然是要包括棋盤和棋子了,於是我們爲之加兩個屬性,棋子有很多顆,所以用List列表。

05233055_wN53.gif
  ///   <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個的,隔兩個位置一顆,於是就這麼出來了。

05233055_wN53.gif
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的方法。

所以我們需要修改下上節的棋子的構造函數,新增加一個傳參:

 

05233055_wN53.gif 代碼
// 這是棋子類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條線上有棋子,而且總是對稱的。

05233055_wN53.gif
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,  " " );
        }

 

再看一下紅棋的創建函數,其實就一個樣,名字不同而已

05233055_wN53.gif
  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,  " " );
        }

 

好了,現在可以寫出棋子初始化的函數了

05233055_wN53.gif
///   <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應用程序的調用代碼要變一變了

 

05233055_wN53.gif
public   partial   class  MainPage : UserControl
    {
        
public  MainPage()
        {
            InitializeComponent();
            Chess chess 
=   new  Chess(canvas1);
            chess.InitBoard();
            chess.InitChessman();
        }
    }

 

F5運行了,出來了。。

 

yo~~只看到一個帥,還不錯,挺帥的。。。

依呀喲,由於我們的原始座標沒有和像素座標進行轉換呢。

好了,在Chess類裏增加一個座標雙向轉換的函數:

高級用法,本來是加多一個參數true或false來進行是像素-》座標,還是座標->像素的。

後來發現座標x+y怎麼也比像素小,所以裏面加個判斷就搞定了。

裏面還要用到棋盤的一些屬性,所以方法放到這裏來,是比較合適的。

05233055_wN53.gif
  ///   <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屬性了。

 

05233055_wN53.gif
  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

轉載於:https://my.oschina.net/secyaher/blog/274036