一.引子
没写过什么游戏的程序,哪怕是拼图或着连连看之类的.前几天看到一个别人在wm5中做的效果图,和旁边的同事聊了会,结果随口说出也打算做个象棋游戏来,身旁另一个同事不信,索性就记在心里了,做着看看.
由于时间不是很充足,当前只做出了棋盘与棋子,效果如下.至于游戏的逻辑,还没有完全考虑好.因为打算完全独立来做,不想参考任何其他人的代码.
二.棋盘与棋子的效果图
三. 实现原理
1.棋子
正如上面图片中显示的类结构图一样,首先定义了一个棋子的接口,包含了标题,是否正向显示,位置3个字段。分别表示棋子显示的标题(例如:“车”,“马”等等),绘制标题的顺序,棋子在棋盘中的相对位置。
然后创建ChessBase控件,该控件的UI实现采用了我前面的文章“绘制圆型按钮”中的方法,又添加了ValidLocation,ValidInterval,GetChessByLocation等几个Protect的方法,来实现获取有效位置的操作,判断2个棋子间是否有其他棋子间隔的操作,通过一个坐标获得对应方格的操作。定义一个List<Point>的集合,来定义棋盘的全部格子位置。最主要的是InvalidRules方法,它的限定符为public virtual,返回一个 bool 值,这个方法需要所有继承自ChessBase的控件来实现.返回true时,认为操作有效(可能是移动了棋子或吃掉了对方的棋子),否则认为无效。
2.棋盘
主要负责绘制棋盘的格子,已经响应OnMouseDown方法,ChessBase等子控件的OnClick事件。同时定义了NewGame方法,IsHandChangedEvent事件。来处理开始一个新游戏以及获取当前行棋方向的改变。
四.具体举例讲解
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Data;
- using System.Text;
- using System.Windows.Forms;
- namespace GameLibrary
- {
- public partial class ChessBing : ChessBase
- {
- public ChessBing()
- {
- InitializeComponent();
- }
- private int _isRiverLand = -1;//是否已经过河
- //检查是否符合规则
- public override bool InvalidRules(ref List<ChessBase> list,Point p)
- {
- //首先确定是否已经过河
- if (_isRiverLand != 1)
- {
- if (this.IsHandstand)
- {
- if (this.ItemLocation.Y < 35 * 5)
- {
- this._isRiverLand = 1;
- }
- }
- else
- {
- if (this.ItemLocation.Y > 35 * 5)
- {
- this._isRiverLand = 1;
- }
- }
- }
- //已经过河
- if (_isRiverLand == 1)
- {
- if (IsHandstand)
- {
- Rectangle leftrect = new Rectangle(this.ItemLocation.X - 35, this.ItemLocation.Y, 35, 35);
- Rectangle toprect = new Rectangle(this.ItemLocation.X, this.ItemLocation.Y - 35, 35, 35);
- Rectangle rightrect = new Rectangle(this.ItemLocation.X + 35, this.ItemLocation.Y, 35, 35);
- if (leftrect.Contains(p) || toprect.Contains(p) || rightrect.Contains(p))
- {
- ChessBase chess = GetChessByLocation(list, p);
- if (chess != null)
- {
- list.Remove(chess);
- }
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- Rectangle leftrect = new Rectangle(this.ItemLocation.X - 35, this.ItemLocation.Y, 35, 35);
- Rectangle toprect = new Rectangle(this.ItemLocation.X, this.ItemLocation.Y + 35, 35, 35);
- Rectangle rightrect = new Rectangle(this.ItemLocation.X + 35, this.ItemLocation.Y, 35, 35);
- if (leftrect.Contains(p) || toprect.Contains(p) || rightrect.Contains(p))
- {
- ChessBase chess = GetChessByLocation(list, p);
- if (chess != null)
- {
- list.Remove(chess);
- }
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- else//没过河只能向前
- {
- if (IsHandstand)//如果是自己的棋,则为反显
- {
- Rectangle toprect = new Rectangle(this.ItemLocation.X, this.ItemLocation.Y - 35, 35, 35);
- if (toprect.Contains(p))
- {
- ChessBase chess = GetChessByLocation(list, p);
- if (chess != null)
- {
- list.Remove(chess);
- }
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- Rectangle toprect = new Rectangle(this.ItemLocation.X, this.ItemLocation.Y + 35, 35, 35);
- if (toprect.Contains(p))
- {
- ChessBase chess = GetChessByLocation(list, p);
- if (chess != null)
- {
- list.Remove(chess);
- }
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- return true;
- }
- }
- }