本文是利用C#實現連連看的小例子,以供學習分享使用。 思路: 涉及知識點: 效果圖圖下(一)【開始,初始化後,倒計時功能,停止功能】: 效果圖(二)【時間結束】 核心代碼如下: 1 /// <summary> 2 /// 連連看幫助類 3 /// </summary> 4 public class ...
本文是利用C#實現連連看的小例子,以供學習分享使用。
思路:
- 初始化佈局(橫豎十行十列,共100個單元格,每一個格一個按鈕,背景圖為水果圖片,隨機生成) 。
- 初始化對應棋盤(用二維數組表示【0表示空白,非0表示界面對象】)和頁面相對應,同步操作。
- 判斷點擊的圖片是否可以消掉(轉化為二維數組【以水平方向,垂直方向,一個拐角,兩個拐角的步驟進行判斷】)。
- 如可以消掉,隱藏圖片,增加分數。
- 時間限制,採用倒計時方式。
涉及知識點:
- 線程:Thread,後臺運行時間控制【倒計時方式】。
- 界面閃爍:當界面中的控制項較多,且有背景圖時,界面就會出現閃爍【解決方式:1,雙緩衝方式 2. 設置控制項創建樣式,統一刷新】。
- TableLayoutPanel:表示一個面板,它可以在一個由行和列組成的網格中對其內容進行動態佈局【新增元素,設置行列,以及樣式】。
- 資源文件:Resources 用於存放圖片及其他資源。
- Button:FlatAppearance獲取用於指示選中狀態和滑鼠狀態的邊框外觀和顏色。
效果圖圖下(一)【開始,初始化後,倒計時功能,停止功能】:
效果圖(二)【時間結束】
核心代碼如下:
1 /// <summary> 2 /// 連連看幫助類 3 /// </summary> 4 public class LinkHelper 5 { 6 /// <summary> 7 /// 連連看,看板 8 /// </summary> 9 public int[,] LinkBoard { get; set; } 10 11 /// <summary> 12 /// 連線成功事件 13 /// </summary> 14 public event EventHandler SucClick; 15 16 /// <summary> 17 /// 連接失敗事件 18 /// </summary> 19 public event EventHandler FailClick; 20 21 private int col = 10; 22 23 public int Col 24 { 25 get 26 { 27 return col; 28 } 29 30 set 31 { 32 col = value; 33 } 34 } 35 36 private int row = 10; 37 38 public int Row 39 { 40 get 41 { 42 return row; 43 } 44 45 set 46 { 47 row = value; 48 } 49 } 50 51 /// <summary> 52 /// 嘗試連線 53 /// </summary> 54 public void LinkLine(Point first, Point second) 55 { 56 EventArgs e = new EventArgs(); 57 if (checkLink(first, second)) 58 { 59 //連線成功 60 this.LinkBoard[first.X, first.Y] = 0; 61 this.LinkBoard[second.X, second.Y] = 0; 62 if (this.SucClick != null) 63 { 64 SucClick(this, e); 65 } 66 } 67 else { 68 //連線失敗 69 if (this.FailClick != null) 70 { 71 FailClick(this, e); 72 } 73 } 74 } 75 76 /// <summary> 77 /// 是否賦值 78 /// </summary> 79 /// <param name="p"></param> 80 /// <returns></returns> 81 public bool IsChecked(Point p) 82 { 83 bool flag = false; 84 if (p.X != -1 && p.Y != -1) 85 { 86 flag = true; 87 } 88 return flag; 89 } 90 91 #region 核心演算法 92 93 /// <summary> 94 /// 判斷是否連線成功 95 /// </summary> 96 /// <param name="a">第一個點擊對象</param> 97 /// <param name="b">第二個點擊對象</param> 98 /// <returns></returns> 99 private bool checkLink(Point a, Point b) 100 { 101 if (!Point.Equals(a, b)) 102 { 103 if (this.LinkBoard[a.X, a.Y] == this.LinkBoard[b.X, b.Y]) 104 { 105 if (a.X == b.X && horizon(a, b)) 106 { 107 return true; 108 } 109 if (a.Y == b.Y && vertical(a, b)) 110 { 111 return true; 112 } 113 if (oneCorner(a, b)) 114 { 115 return true; 116 } 117 else 118 { 119 return twoCorner(a, b); 120 } 121 } 122 else { 123 //如果點擊的不是同一個圖案,直接返回false 124 return false; 125 } 126 } 127 else { 128 //如果點擊的是同一個位置的圖案,直接返回false; 129 return false; 130 } 131 } 132 133 /// <summary> 134 /// 水平連線 135 /// </summary> 136 /// <param name="a"></param> 137 /// <param name="b"></param> 138 /// <returns></returns> 139 private bool horizon(Point a, Point b) 140 { 141 int col_start = a.Y < b.Y ? a.Y : b.Y; //獲取a,b中較小的y值 142 int col_end = a.Y < b.Y ? b.Y : a.Y; //獲取a,b中較大的值 143 144 //遍歷a,b之間是否通路,如果一個不是就返回false; 145 for (int i = col_start + 1; i < col_end; i++) 146 { 147 if (this.LinkBoard[a.X, i] != 0) 148 { 149 return false; 150 } 151 } 152 return true; 153 } 154 155 /// <summary> 156 /// 垂直連線 157 /// </summary> 158 /// <param name="a"></param> 159 /// <param name="b"></param> 160 /// <returns></returns> 161 private bool vertical(Point a, Point b) 162 { 163 int row_start = a.X < b.X ? a.X : b.X; 164 int row_end = a.X < b.X ? b.X : a.X; 165 for (int i = row_start + 1; i < row_end; i++) 166 { 167 if (this.LinkBoard[i, a.Y] != 0) 168 { 169 return false; 170 } 171 } 172 return true; 173 } 174 175 /// <summary> 176 /// 一個拐角 177 /// </summary> 178 /// <param name="a"></param> 179 /// <param name="b"></param> 180 /// <returns></returns> 181 private bool oneCorner(Point a, Point b) 182 { 183 Point c = new Point(b.X, a.Y); 184 Point d = new Point(a.X, b.Y); 185 //判斷C點是否有元素 186 if (this.LinkBoard[c.X, c.Y] == 0) 187 { 188 bool path1 = horizon(b, c) && vertical(a, c); 189 return path1; 190 } 191 //判斷D點是否有元素 192 if (this.LinkBoard[d.X, d.Y] == 0) 193 { 194 bool path2 = horizon(a, d) && vertical(b, d); 195 return path2; 196 } 197 else 198 { 199 return false; 200 } 201 } 202 203 /// <summary> 204 /// 兩個拐角 205 /// </summary> 206 /// <param name="a"></param> 207 /// <param name="b"></param> 208 /// <returns></returns> 209 private bool twoCorner(Point a, Point b) 210 { 211 List<Line> ll = scan(a, b); 212 if (ll.Count == 0) 213 { 214 return false; 215 } 216 for (int i = 0; i < ll.Count; i++) 217 { 218 Line tmpLine = ll[i]; 219 if (tmpLine.direct == 1) 220 { 221 222 if (vertical(a, tmpLine.a) && vertical(b, tmpLine.b)) 223 { 224 return true; 225 } 226 } 227 else if (tmpLine.direct == 0) 228 { 229 if (horizon(a, tmpLine.a) && horizon(b, tmpLine.b)) 230 { 231 return true; 232 } 233 } 234 } 235 return false; 236 } 237 238 /// <summary> 239 /// 掃描A與B之間的連接點組成的線 240 /// </summary> 241 /// <param name="a"></param> 242 /// <param name="b"></param> 243 /// <returns></returns> 244 private List<Line> scan(Point a, Point b) 245 { 246 List<Line> linkList = new List<Line>(); 247 //檢測a點,b點的左側是否能夠垂直直連 248 for (int i = a.Y; i >= 0; i--) 249 { 250 if (this.LinkBoard[a.X, i] == 0 && this.LinkBoard[b.X, i] == 0 && vertical(new Point(a.X, i), new Point(b.X, i))) 251 { 252 linkList.Add(new Line(new Point(a.X, i), new Point(b.X, i), 0)); 253 } 254 } 255 //檢測a點,b點的右側是否能夠垂直直連 256 for (int i = a.Y; i < Col; i++) 257 { 258 if (this.LinkBoard[a.X, i] == 0 && this.LinkBoard[b.X, i] == 0 && vertical(new Point(a.X, i), new Point(b.X, i))) 259 { 260 linkList.Add(new Line(new Point(a.X, i), new Point(b.X, i), 0)); 261 } 262 } 263 //檢測a點,b點的上側是否能夠水平直連 264 for (int j = a.X; j >= 0; j--) 265 { 266 if (this.LinkBoard[j, a.Y] == 0 && this.LinkBoard[j, b.Y] == 0 && horizon(new Point(j, a.Y), new Point(j, b.Y))) 267 { 268 linkList.Add(new Line(new Point(j, a.Y), new Point(j, b.Y), 1)); 269 } 270 } 271 //檢測a點,b點的下側是否能夠水平直連 272 for (int j = a.X; j < Row; j++) 273 { 274 if (this.LinkBoard[j, a.Y] == 0 && this.LinkBoard[j, b.Y] == 0 && horizon(new Point(j, a.Y), new Point(j, b.Y))) 275 { 276 linkList.Add(new Line(new Point(j, a.Y), new Point(j, b.Y), 1)); 277 278 } 279 } 280 281 return linkList; 282 } 283 284 #endregion 285 }View Code