新手silverlight练习--五子棋( 三 )

       在上一篇文章中,我们经过之前的千辛万苦终于让棋子在棋盘上面给显示出来了。现在我们就要想办法,让它实现下棋子的功能。

下棋子是怎么下的呢?

 

思考片刻:五子棋有两个人下(虽然是自己和自己下,也勉强算两个人啦),所以当你触发一次鼠标按下事件,就得下一个棋子,而且棋子的颜色会是交替的,一黑一白这样下。然后把它放在你点击的地方。

       有了思路,就得按照这个是实现,要怎么做呢?方法其实很多的,我暂时想到两个:

 

一、可以在初始化棋盘的时候,就让每个可以放棋子的坐标点上面生成一个棋子,因为棋子其实是一个Ellipse对象,所以把他的opcity设为0,这样就透明,看不见了,就当是没有棋子在这个地方(自欺欺人下吧,反正别人不知道);然后呢,就要开始响应鼠标点击了----好棋,我就要下在这个地方了,然后我就点击这个位置,鼠标获取坐标,然后就把这个地方的棋子的opcity设为1,就不透明了,然后根据下棋的先后判断是黑棋还是白棋,把它颜色给设好,这样,一个棋子就出现在这个位置了。

 

按照正常的方法,开始的时候棋盘上是没有棋子的,然后,根据你下棋下的位置,同样通过鼠标获取坐标点,然后在这个位置生成一个棋子对象,设定棋子颜色,再加进棋盘画布。

 

            这里,我用的是第二种方法,好了,马上开始行动----------------》

我们继续来完善GameEnigin类,刚才说了,要根据你下棋的位置,然后通过坐标生成棋子,所以,我们就来做两个函数,一个是生成黑色棋子的函数,一个是生成白色棋子的函数,这样,以后我们就根据情况来调用它们。

 

 1 /// <summary>
 2         /// 创建黑色棋子
 3         /// </summary>
 4         /// <param name="pt"></param>
 5         /// <param name="con"></param>
 6         
 7         public void CreateBlackChessman(Point pt,Canvas con)
 8         {
 9             Point ptn=new Point();
10             ChessMan cm = new ChessMan(pt, radius, Colors.Black,1);
11                      
12             cm.DrowChessman(con);
13         
14         }
15 
16         /// <summary>
17         /// 创建白色棋子
18         /// </summary>
19         public void CreateWhiteChessman(Point pt, Canvas con)
20         {
21             Point ptn = new Point();
22             ChessMan cm = new ChessMan(pt, radius, Colors.White,2);
23            
24             cm.DrowChessman(con);
25         
26         }
27 

 

           这个函数,通过参数传进鼠标点击时的坐标,和容器对象(这里就传进棋盘画布,因为我们的棋子也是画在棋盘上的);

然后通过棋子类生成一个棋子,并设定颜色,大小等信息。这样,黑白棋子的生成函数就写好了。接着我们考虑棋子黑白交替下的方法,为了实现这个功能。我又在GameEnigin类中增加了一个GameStart函数,来控制:

 

  int turns = 1;
        
/// <summary>
        
/// 游戏开始
        
/// </summary>
        public void GameStart(int x,int y, Canvas con)
        {
            Point pt 
= new Point(x, y);
         
           
               
                  
switch(turns)
            {
                
case 1: {
                           CreateBlackChessman(pt, con);
                             turns 
= 2;
                         }
break;
                 
case 2: {
                         CreateWhiteChessman(pt, con);
                          turns
=1;
                          }
break;
              }
          }

 

 

这里通过turns来控制黑白棋子交替生成,很简单吧?嘿嘿~~

 

有了这个,我们就要使用他们,所以,我们回到

MainPage.xaml文件,修改Canvas如下:

 

 <Canvas Background="LightGray" Grid.Column="1" x:Name="Board" MouseLeftButtonDown="Board_MouseLeftButtonDown"></Canvas>

 

这里其实就是增加了一个MouseLeftButtonDown的事件,然后在隐藏代码中会相应的出现鼠标左键按下的事件响应函数 

private void Board_MouseLeftButtonDown(object sender, MouseButtonEventArgs e);于是,我们打开MainPage.xaml.cs文件。找到这个函数

开始获取坐标啊,生成棋子等操作,代码如下:

 

 

代码

  private void Board_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            
            Point pt 
= e.GetPosition(this);
                      
            List 
<Point> pList = new List<Point>();
           
            
for(int i=350;i<=900;i+=50)
            {
                
for (int j = 28; j <= 578; j += 50)
                {

                    pList.Add(
new Point(i, j));
                   
           
                }
            }
           if (pList.Contains(pt)
            {
              ge.GameStart((
int)px.X, (int)px.Y, Board);
            }
}

 

 

        这里先获取鼠标点击的坐标点,然后,再new一个Point的列表对象,然后把棋盘上可以放棋子的各个坐标点放进这个列表中,这两个for循环就是生成对应的坐标点,i,j的具体范围大家根据实际设定,因为我当初设定的间隔大小是50,所以以50递增。

        然后判断当前点击时的坐标点是不是在这个列表中,如果在,就调用GameStart函数,在这个坐标点生成一个棋子,看下GameStart函数的最后一个参数。是Board,这个就是棋盘Canvas对象。最后别忘了,在MainPage.xaml.cs的类中声明下 GameEnigin ge;然后在 public MainPage()构造函数中加上:

ge = new GameEnigin(Board);因为,ge在后面都要用到。

好哦,终于离成功又进一步了,运行运行。。。。

----------------------------------问题来了 问题来了------------------------------->>

>>>啥问题?当点棋盘的时候咋没反应呢,我点呀点呀,终于有反应了,原来,坐标定位太精确了,只有在那一个点上点击才能生成棋子啊!!!

我 ¥……%&……%……#%$%   

 那下棋也太累了吧,每次都要点那个准。。。得想个办法把它的范围给扩大,因为现在能点的坐标只有(350,28),(400,28),(450,28).........(350,56),(350,84).......

怎么办呢?

于是,我终于想到一个笨办法,不管了,能解决问题就行(如果哪位有更好的方法,赐教),方法是这样的:

再定义一个Ponit 对象px ,然后。。。。还是看代码先:

 

代码
  Point px = new Point();
  
for (int i = -23; i < 24; i++)                  //x轴方向范围-23---23
            {
                
for (int j = -23; j < 24; j++)    //y轴方向范围 -23--23
                {
                    px.X 
= pt.X;
                    px.Y 
= pt.Y;

                    px.X 
+= i;
                    px.Y 
+= j;
             
if (pList.Contains(pt) || pList.Contains(px))
              ge.GameStart((
int)px.X, (int)px.Y, Board);
            }
}

 

为什么要选范围-23--23 呢?因为和我们的格子间的距离50有关。这样选的话,可以更好的判断应该定位在哪个位置。

这样把原来坐标点边上更多的坐标点也加到了坐标列表,然后这里将通过px来定位位置,不能用pt坐标了哦。。。。

好了,现在可以在一个范围内点击,然后定位到你想下棋的位置。现在我们基本上已经能够在棋盘上下棋了,现在要做的就是要实现五子棋的基本算法啦。因此我们需要在GameEnigin类中增加一个 ChessMan[,] chess=new ChessMan[12,12];通过它,我们将实现五子棋游戏的基本逻辑。

但是这个数组的范围是12,12而我们之前得到的是屏幕坐标,因此。我们还需要做一个屏幕坐标到逻辑坐标的转换函数,以实现,通过用户的行为,而反映到具体的逻辑。那么我们接下来就来做这个转换函数吧:)

 

  函数很简单:

 

 /// <summary>
        
///物理坐标转换成逻辑坐标
        
/// </summary>
        public Point ChangePos(Point pt)
        {
            Point LogPos 
= new Point();
            LogPos.X = (pt.X - 350/ 50;
            LogPos.Y = (pt.Y - 28/ 50;
            
return LogPos;      
        }

 

 

通过它可以根据屏幕坐标,返回相应的逻辑坐标点。如,屏幕坐标最左上角的(350,28)转换后变为(0,0);依次转换、、、简单吧、、这样我们就可以通过获取屏幕坐标。然后把棋子放进逻辑数组里面,之后嘛,就根据逻辑数组,来算五子棋是不是5个同色的棋子连在一起的算法了。

       今天写到这里,剩下的下次写啦。。。天气好热。。

posted @ 2010-08-14 11:51  Sirk  阅读(951)  评论(4编辑  收藏  举报