打算也做个象棋来

 一.引子

     没写过什么游戏的程序,哪怕是拼图或着连连看之类的.前几天看到一个别人在wm5中做的效果图,和旁边的同事聊了会,结果随口说出也打算做个象棋游戏来,身旁另一个同事不信,索性就记在心里了,做着看看.

    由于时间不是很充足,当前只做出了棋盘与棋子,效果如下.至于游戏的逻辑,还没有完全考虑好.因为打算完全独立来做,不想参考任何其他人的代码.

 

二.棋盘与棋子的效果图

 

 

 

 

 

 

 

 

三. 实现原理
            1.棋子
            正如上面图片中显示的类结构图一样,首先定义了一个棋子的接口,包含了标题,是否正向显示,位置3个字段。分别表示棋子显示的标题(例如:“车”,“马”等等),绘制标题的顺序,棋子在棋盘中的相对位置。
                然后创建ChessBase控件,该控件的UI实现采用了我前面的文章“绘制圆型按钮”中的方法,又添加了ValidLocation,ValidInterval,GetChessByLocation等几个Protect的方法,来实现获取有效位置的操作,判断2个棋子间是否有其他棋子间隔的操作,通过一个坐标获得对应方格的操作。定义一个List<Point>的集合,来定义棋盘的全部格子位置。最主要的是InvalidRules方法,它的限定符为public virtual,返回一个 bool 值,这个方法需要所有继承自ChessBase的控件来实现.返回true时,认为操作有效(可能是移动了棋子或吃掉了对方的棋子),否则认为无效。

           2.棋盘

           主要负责绘制棋盘的格子,已经响应OnMouseDown方法,ChessBase等子控件的OnClick事件。同时定义了NewGame方法,IsHandChangedEvent事件。来处理开始一个新游戏以及获取当前行棋方向的改变。

 

 四.具体举例讲解

  

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. namespace GameLibrary
  9. {
  10.     public partial class ChessBing : ChessBase
  11.     {
  12.         public ChessBing()
  13.         {
  14.             InitializeComponent();
  15.         }
  16.         private int _isRiverLand = -1;//是否已经过河
  17.        
  18.         //检查是否符合规则
  19.         public  override bool InvalidRules(ref List<ChessBase> list,Point p)
  20.         {
  21.             //首先确定是否已经过河
  22.             if (_isRiverLand != 1)
  23.             {
  24.                 
  25.                 if (this.IsHandstand)
  26.                 {
  27.                     if (this.ItemLocation.Y < 35 * 5)
  28.                     {
  29.                         this._isRiverLand = 1;
  30.                     }
  31.                 }
  32.                 else
  33.                 {
  34.                     if (this.ItemLocation.Y > 35 * 5)
  35.                     {
  36.                         this._isRiverLand = 1;
  37.                     }
  38.                 }               
  39.             }
  40.             //已经过河
  41.             if (_isRiverLand == 1)
  42.             {
  43.                 if (IsHandstand)
  44.                 {
  45.                     Rectangle leftrect = new Rectangle(this.ItemLocation.X - 35, this.ItemLocation.Y, 35, 35);
  46.                     Rectangle toprect = new Rectangle(this.ItemLocation.X, this.ItemLocation.Y - 35, 35, 35);
  47.                     Rectangle rightrect = new Rectangle(this.ItemLocation.X + 35, this.ItemLocation.Y, 35, 35);
  48.                     if (leftrect.Contains(p) || toprect.Contains(p) || rightrect.Contains(p))
  49.                     {
  50.                         ChessBase chess = GetChessByLocation(list, p);
  51.                         if (chess != null)
  52.                         {
  53.                             list.Remove(chess);
  54.                         }
  55.                         return true;
  56.                     }
  57.                     else
  58.                     {
  59.                         return false;
  60.                     }
  61.                 }
  62.                 else
  63.                 {
  64.                     Rectangle leftrect = new Rectangle(this.ItemLocation.X - 35, this.ItemLocation.Y, 35, 35);
  65.                     Rectangle toprect = new Rectangle(this.ItemLocation.X, this.ItemLocation.Y + 35, 35, 35);
  66.                     Rectangle rightrect = new Rectangle(this.ItemLocation.X + 35, this.ItemLocation.Y, 35, 35);
  67.                     if (leftrect.Contains(p) || toprect.Contains(p) || rightrect.Contains(p))
  68.                     {
  69.                         ChessBase chess = GetChessByLocation(list, p);
  70.                         if (chess != null)
  71.                         {
  72.                             list.Remove(chess);
  73.                         }
  74.                         return true;
  75.                     }
  76.                     else
  77.                     {
  78.                         return false;
  79.                     }
  80.                 }
  81.             }
  82.             else//没过河只能向前
  83.             {
  84.                 if (IsHandstand)//如果是自己的棋,则为反显
  85.                 {
  86.                     Rectangle toprect = new Rectangle(this.ItemLocation.X, this.ItemLocation.Y - 35, 35, 35);
  87.                     if (toprect.Contains(p))
  88.                     {
  89.                         ChessBase chess = GetChessByLocation(list, p);
  90.                         if (chess != null)
  91.                         {
  92.                             list.Remove(chess);
  93.                         }
  94.                         return true;
  95.                     }
  96.                     else
  97.                     {
  98.                         return false;
  99.                     }
  100.                 }
  101.                 else
  102.                 {
  103.                     Rectangle toprect = new Rectangle(this.ItemLocation.X, this.ItemLocation.Y + 35, 35, 35);
  104.                     if (toprect.Contains(p))
  105.                     {
  106.                         ChessBase chess = GetChessByLocation(list, p);
  107.                         if (chess != null)
  108.                         {
  109.                             list.Remove(chess);
  110.                         }
  111.                         return true;
  112.                     }
  113.                     else
  114.                     {
  115.                         return false;
  116.                     }
  117.                 }
  118.             }
  119.             return true;
  120.         }
  121.         
  122.     }
  123. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
功能介绍:<br/> * 本上传软件仅为爱好编程的同仁C#学习之用. <br/> <br/> a. 支持单人/双人游戏; 在开局中任意时刻可以切换单人/双人状态. <br/> b. 音效支持;有三首背景音乐,前台走棋音乐多样,如果您仔细观察的话,连拖动旗子的声音也有了:).<br/> c. 能够自定义残局; 通过*.ini配置文件增加了多个残局棋局.<br/> d. 保存. 能够实现动态保存功能,在下棋过程中能够保存当前下棋棋盘布局状态; 并在任意时刻恢复您保存的状态.<br/> e. 防止作弊. 程式严格控制了没个旗子的走发,比如:卒在过诃之前只能够进攻,过了诃才能够左右移动以及不能够一方连续走棋. <br/> f. 支持键盘鼠标两种操作方式; 双人下棋是一人使用鼠标,一人使用键盘操作最佳!<br/> g. 比较好的智能提示. 即使对象棋规则不台熟悉的人也可以很好的根据提示走棋,比如:当一方走棋后,它会自动提示另一方再走棋;当拿起旗子后,它回自动提示该位置是否可以落棋, 当落棋后它会提示您走了哪个旗子. 下棋结束会有得分和分析当前旗子损失率等.<br/> h. 有点不足的是电脑走棋比较苯,不过这也无妨影响学习大碍. 程式里面用到了许多C#技术细节方面,比如: Graphics,Sound,Repaint Control(Change picture to round),KeyDownPress,MouseClick/Move/Down/Drag picture,game save(Serialization),operate setting file etc.<br/><br/>扩展功能:<br/> i. 重新设计了所有旗子, 选择新的旗盘背景, 换了一个更清爽的面.(界面配色并不是件很容易的事情, 这样的棋类游戏长时间容易使眼睛疲劳, 首先要到选择的色彩不刺激眼睛,其实大部分色彩都比较刺激眼睛,尤其是纯三基色(红/黄/蓝), 还要使界面得漂亮). <br/> j. 增加”回放” 功能. 当下完旗子时,可以重新回味一下, 刚杀完的一盘旗,可以寻找不足和重新感受一下胜利的喜悦! 这个功能比较复杂!<br/> k. 又看了一下电脑走旗, 感觉确实比较难处理, 没有高人指点写这个算法确实比较难, 应该比以前聪明了一些, 但是还是比较笨, 打算有空去找个现在的电脑走旗组件替换上, 自己的电脑走旗算法慢慢研究(当时是因为实在找不到现在的组件, 自己写了个较笨的,如果哪位朋友能够提供组件,在次深表感谢!!!).<br/> l. 扩展走旗的步数容量, 有些网友, 对战的都是高手, 产生数组越界, 这次从 200 扩展到了500, 当然<br/> 您还可以扩展到更大,因为源代码已经开放).<br/> m. 增加图像缓存功能.<br/> (开发语言: C#语言)<br/><br/> * 本上传软件仅为爱好编程的同仁C#学习之用. <br/> <br/><br/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值