C#实现连连看功能(推荐)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C#实现连连看功能(推荐)
本⽂是利⽤C#实现连连看的⼩例⼦,以供学习分享使⽤。
初始化布局(横竖⼗⾏⼗列,共100个单元格,每⼀个格⼀个按钮,背景图为⽔果图⽚,随机⽣成)。
初始化对应棋盘(⽤⼆维数组表⽰【0表⽰空⽩,⾮0表⽰界⾯对象】)和页⾯相对应,同步操作。
判断点击的图⽚是否可以消掉(转化为⼆维数组【以⽔平⽅向,垂直⽅向,⼀个拐⾓,两个拐⾓的步骤进⾏判断】)。
如可以消掉,隐藏图⽚,增加分数。
时间限制,采⽤倒计时⽅式。
线程:Thread,后台运⾏时间控制【倒计时⽅式】。
界⾯闪烁:当界⾯中的控件较多,且有背景图时,界⾯就会出现闪烁【解决⽅式:1,双缓冲⽅式 2. 设置控件创建样式,统⼀刷新】。
TableLayoutPanel:表⽰⼀个⾯板,它可以在⼀个由⾏和列组成的⽹格中对其内容进⾏动态布局【新增元素,设置⾏列,以及样式】。
资源⽂件:Resources ⽤于存放图⽚及其他资源。
Button:FlatAppearance获取⽤于指⽰选中状态和⿏标状态的边框外观和颜⾊。
效果图图下(⼀)【开始,初始化后,倒计时功能,停⽌功能】:
效果图(⼆)【时间结束】
核⼼代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34/// <summary>
/// 连连看帮助类
/// </summary>
public class LinkHelper
{
/// <summary>
/// 连连看,看板
/// </summary>
public int[,] LinkBoard { get; set; } /// <summary>
/// 连线成功事件
/// </summary>
public event EventHandler SucClick; /// <summary>
/// 连接失败事件
/// </summary>
public event EventHandler FailClick; private int col = 10;
public int Col
{
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 get
{
return col;
}
set
{
col = value;
}
}
private int row = 10;
public int Row
{
get
{
return row;
}
set
{
row = value;
}
}
/// <summary>
/// 尝试连线
/// </summary>
public void LinkLine(Point first, Point second)
{
EventArgs e = new EventArgs();
if(checkLink(first, second))
{
//连线成功
this.LinkBoard[first.X, first.Y] = 0;
this.LinkBoard[second.X, second.Y] = 0;
if(this.SucClick != null)
{
SucClick(this, e);
}
}
else{
//连线失败
if(this.FailClick != null)
{
FailClick(this, e);
}
}
}
/// <summary>
/// 是否赋值
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public bool IsChecked(Point p)
{
bool flag = false;
if(p.X != -1 && p.Y != -1)
{
flag = true;
}
return flag;
}
#region 核⼼算法
/// <summary>
/// 判断是否连线成功
/// </summary>
/// <param name="a">第⼀个点击对象</param>
/// <param name="b">第⼆个点击对象</param>
/// <returns></returns>
private bool checkLink(Point a, Point b)
{
if(!Point.Equals(a, b))
{
if(this.LinkBoard[a.X, a.Y] == this.LinkBoard[b.X, b.Y]) {
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 if(a.X == b.X && horizon(a, b))
{
return true;
}
if(a.Y == b.Y && vertical(a, b))
{
return true;
}
if(oneCorner(a, b))
{
return true;
}
else
{
return twoCorner(a, b);
}
}
else{
//如果点击的不是同⼀个图案,直接返回false
return false;
}
}
else{
//如果点击的是同⼀个位置的图案,直接返回false;
return false;
}
}
/// <summary>
/// ⽔平连线
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private bool horizon(Point a, Point b)
{
int col_start = a.Y < b.Y ? a.Y : b.Y; //获取a,b中较⼩的y值 int col_end = a.Y < b.Y ? b.Y : a.Y; //获取a,b中较⼤的值 //遍历a,b之间是否通路,如果⼀个不是就返回false;
for(int i = col_start + 1; i < col_end; i++)
{
if(this.LinkBoard[a.X, i] != 0)
{
return false;
}
}
return true;
}
/// <summary>
/// 垂直连线
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private bool vertical(Point a, Point b)
{
int row_start = a.X < b.X ? a.X : b.X;
int row_end = a.X < b.X ? b.X : a.X;
for(int i = row_start + 1; i < row_end; i++)
{
if(this.LinkBoard[i, a.Y] != 0)
{
return false;
}
}
return true;
}
/// <summary>
/// ⼀个拐⾓
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 /// <returns></returns>
private bool oneCorner(Point a, Point b)
{
Point c = new Point(b.X, a.Y);
Point d = new Point(a.X, b.Y);
//判断C点是否有元素
if(this.LinkBoard[c.X, c.Y] == 0)
{
bool path1 = horizon(b, c) && vertical(a, c);
return path1;
}
//判断D点是否有元素
if(this.LinkBoard[d.X, d.Y] == 0)
{
bool path2 = horizon(a, d) && vertical(b, d);
return path2;
}
else
{
return false;
}
}
/// <summary>
/// 两个拐⾓
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private bool twoCorner(Point a, Point b)
{
List<Line> ll = scan(a, b);
if(ll.Count == 0)
{
return false;
}
for(int i = 0; i < ll.Count; i++)
{
Line tmpLine = ll[i];
if(tmpLine.direct == 1)
{
if(vertical(a, tmpLine.a) && vertical(b, tmpLine.b))
{
return true;
}
}
else if(tmpLine.direct == 0)
{
if(horizon(a, tmpLine.a) && horizon(b, tmpLine.b))
{
return true;
}
}
}
return false;
}
/// <summary>
/// 扫描A与B之间的连接点组成的线
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private List<Line> scan(Point a, Point b)
{
List<Line> linkList = new List<Line>();
//检测a点,b点的左侧是否能够垂直直连
for(int i = a.Y; i >= 0; i--)
{
if(this.LinkBoard[a.X, i] == 0 && this.LinkBoard[b.X, i] == 0 && vertical(new Point(a.X, i), new Point(b.X, i))) {
linkList.Add(new Line(new Point(a.X, i), new Point(b.X, i), 0));
221222223224225226227228229230231232233234235236237238239240241242243244245246247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
}
}
//检测a 点,b 点的右侧是否能够垂直直连 for (int i = a.Y; i < Col; i++) { if (this.LinkBoard[a.X, i] == 0 && this.LinkBoard[b.X, i] == 0 && vertical(new Point(a.X, i), new Point(b.X, i))) {
linkList.Add(new Line(new Point(a.X, i), new Point(b.X, i), 0));
}
}
//检测a 点,b 点的上侧是否能够⽔平直连 for (int j = a.X; j >= 0; j--) { if (this.LinkBoard[j, a.Y] == 0 && this.LinkBoard[j, b.Y] == 0 && horizon(new Point(j, a.Y), new Point(j, b.Y))) { linkList.Add(new Line(new Point(j, a.Y), new Point(j, b.Y), 1));
}
}
//检测a 点,b 点的下侧是否能够⽔平直连 for (int j = a.X; j < Row; j++) { if (this.LinkBoard[j, a.Y] == 0 && this.LinkBoard[j, b.Y] == 0 && horizon(new Point(j, a.Y), new Point(j, b.Y))) { linkList.Add(new Line(new Point(j, a.Y), new Point(j, b.Y), 1)); }
}
return linkList;
} #endregion }以上所述是⼩编给⼤家介绍的C# 实现连连看功能,希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。
在此也⾮常感谢⼤家对⽹站的⽀持!。