Silverlight+WCF 新手实例 象棋 棋子定位与象棋类(四)

上节创建显示了一颗棋子,由于没有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的方法。

所以我们需要修改下上节的棋子的构造函数,新增加一个传参:

 

代码

 

 

 

好了,现在开始创建黑棋的函数代码相对简洁了一点,这里多了一个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

版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:

http://www.cnblogs.com/cyq1162/archive/2010/07/07/1773033.html

时间: 2024-09-13 00:31:40

Silverlight+WCF 新手实例 象棋 棋子定位与象棋类(四)的相关文章

Silverlight+WCF 新手实例 象棋 棋子移动-规则补充(三十七)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   在Silverlight+WCF 新手实例 象棋 棋子移动-规则[附加上半盘限制](十)中,由Silenus-G提出规则还有点bug: 红车竟然可以走到红马的地盘:这是由于鼠标点在棋子之外的地方时,我们产生的是棋子移动[不是吃子],而在移动之时,我们又没有判断要移动到的位置上是不是有其它棋子从而引发了经济纠纷.因此,解决这个问题,我们只需在点击事件里增加一下判断棋子存不存在就可以了. 而在移动的规则里,这节我们同时进行补

Silverlight+WCF 新手实例 象棋 棋子移动-规则[附加上半盘限制](十)

上上一节,我们对棋子的下半盘棋子做了所有的规则限制,因为我们下棋的总是用下半盘的棋子来下,总没人用上半盘棋来下那么高境界的吧. 不过这节简单追加点代码,让那些企图高境界的人士可以临时性的自己和自己下. 好了,要为上半盘棋子也做限制,所以我们要知道棋子是归属于上半盘还是下半盘的,这里,我们为棋子类Chessman增加一个属性,IsUp,是否上半盘棋,反之就下半盘了.初始为该属性赋值也相当的简单:  /// <summary>         /// 棋子默认在上半盘/反之在下半盘        

Silverlight+WCF 新手实例 象棋 主界面-事件区-游戏开始(二十七)

本专题出产简单原由: 一开始的初衷,只是想写个简单的单机BS人机对战版的,开始还下了点AI算法看看的: 但是写到最后,都写成了通讯版本的对战了,只因中间不小心看到了WCF的相关内容,顺便加了进来; 最后就定局了,反正新手实例,能加多点内容就加多点了. 关于原始初衷,后期再补上了.       好了,先上几个附加索引: 1:Silverlight+WCF 新手实例 象棋 在线演示 2:Silverlight+WCF 简单部署问题集 3:Silverlight4 ListBox bug 4:Silv

Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   本节完后,同时会更新Silverlight+WCF 新手实例 象棋 专题索引,并顺路提供第八阶段源码   在Silverlight+WCF 新手实例 象棋 主界面-棋谱-布局写谱(三十六)节中,我们完成了下棋双方的棋谱传递 在Silverlight+WCF 新手实例 象棋 主界面-棋谱-获取列表(三十八)节中,我们完成了观棋者获取棋谱列表 在本节中,我们要进行最一步了,棋谱回放: 首先,当用户进入列表后,获取完棋谱信息之

Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放-结局(四十)

查看本系列其他相关文章请点击:Silverlight+WCF 新手实例象棋专题索引 在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 在Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)中,我们实现了用户的棋谱回放,在文章的下面,我们曾留下了两个问题: 下棋者在下棋过程,要不要开放"回放"功能,如果开放,需要注意什么? 观众在回放过程中,突然又传来一个棋步,需要注意什么? 在解答这两个问题之前,我们先来解答上一篇的截图中发现的问题: 不知

一起谈.NET技术,Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放-结局(四十)

查看本系列其他相关文章请点击:Silverlight+WCF 新手实例象棋专题索引 在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 在Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)中,我们实现了用户的棋谱回放,在文章的下面,我们曾留下了两个问题: 下棋者在下棋过程,要不要开放"回放"功能,如果开放,需要注意什么? 观众在回放过程中,突然又传来一个棋步,需要注意什么? 在解答这两个问题之前,我们先来解答上一篇的截图中发现的问题: 不知

Silverlight+WCF 新手实例 象棋 主界面-棋谱-获取列表(三十八)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   在Silverlight+WCF 新手实例 象棋 主界面-棋谱-布局写谱(三十六)中,我们完成下棋双方的棋谱显示,这节,我们为观众增加棋子列表: 观众进入房间后,第一时间当然也要获取棋步列表了,不然进来干麻呢?你当这是聊天室啊,光聊天不看棋.   首先,当然是要在服务端添加一个获取棋步列表的接口方法了: WCF服务端,IService.cs:  /// <summary>     /// 服务端方法接口 by 路过秋天

Silverlight+WCF 新手实例 象棋 WCF通讯轮询(十七)

上节说到: 关于双向通讯,官方提供了N种可以双向的,不过今天要用到的, 是pollingDuplexHttpBinding,一个扩展的轮询机制的双向通讯,当你也可以尝试用上面的通讯方式去试一试. 既然是扩展,就说明默认没有,那我们首先就要添加扩展了,用的是默认官方是提供的DLL,就在我们安装的Silverlight4的目录里: 正常路径为:C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries\Server\System.Servic

Silverlight+WCF 新手实例 象棋 棋手颜色(二十九)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   在上一节Silverlight+WCF 新手实例 象棋 该谁下棋-A下B停(二十八),我们在最后聊天对话中看到,双方棋手用的竟然都是红色,这个...... 这节,我们来让双方使用不同的颜色下棋:   我们通过什么来决定棋手的颜色?其实,Player玩家属性里,不就有一个ColorValue么,有了这个,一切就好办了. 我们回到Chess象棋类里,增加一个属性,玩家颜色,同时,扩展一下构造函数,增加传参:  /// <su

Silverlight+WCF 新手实例 象棋 主界面-棋盘区(二十二)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   这节我们要布局Index.xaml界面. 首先,我们定义一下全局的宽和高:1000*620[数字差不多就行了] 一堆代码,都是自动生成的,只是改了两个数字,不说大伙也知道改啥数字了. <UserControl x:Class="NewChessProject.Index"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presen