C# 实现连连看功能(推荐)

时间:2022-07-05 04:54:58

本文是利用C#实现连连看的小例子,以供学习分享使用。

思路:

初始化布局(横竖十行十列,共100个单元格,每一个格一个按钮,背景图为水果图片,随机生成) 。

初始化对应棋盘(用二维数组表示【0表示空白,非0表示界面对象】)和页面相对应,同步操作。

判断点击的图片是否可以消掉(转化为二维数组【以水平方向,垂直方向,一个拐角,两个拐角的步骤进行判断】)。

如可以消掉,隐藏图片,增加分数。

时间限制,采用倒计时方式。

涉及知识点:

线程:Thread,后台运行时间控制【倒计时方式】。

界面闪烁:当界面中的控件较多,且有背景图时,界面就会出现闪烁【解决方式:1,双缓冲方式 2. 设置控件创建样式,统一刷新】。

TableLayoutPanel:表示一个面板,它可以在一个由行和列组成的网格中对其内容进行动态布局【新增元素,设置行列,以及样式】。

资源文件:Resources 用于存放图片及其他资源。

Button:FlatAppearance获取用于指示选中状态和鼠标状态的边框外观和颜色。

效果图图下(一)【开始,初始化后,倒计时功能,停止功能】:

C# 实现连连看功能(推荐)

效果图(二)【时间结束】

C# 实现连连看功能(推荐)

核心代码如下:

?
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
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
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
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
/// <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
    {
      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])
        {
          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>
    /// <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));
        }
      }
      //检测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# 实现连连看功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!

原文链接:http://www.cnblogs.com/hsiang/archive/2017/07/03/7108274.html