连连看的规则大家应该都知道,选中的两个图片相同,并且不能多于两个拐点能连在一块,这两个图片就可以消掉;
连通的类型:
1
直线型;
2
一个拐点;
3
两个拐点;
下面开始介绍这三种连通类型
直线型:
直线型分两种,一种是横向,一种是竖向;
首先是横向连接
A,B 两点的 x 坐标相同,图片类型相同,从 A 点开始到 B 点检测,如果 AB 两点之间没有其他图片就销毁 AB 两个图片,竖向的和横向的类似
一个拐点:
AB 两点的 x 坐标和 y 坐标都不相同的时候开始检测一个拐点是否可以连接,通过 AB 两点计算出 CD 两点,然后分别检测 AC , BC,AD,BD 是否可以通过直线型连接到一起,显然 AB 两点可以通过 A>C,C>B 连接到一起,
两个拐点:
AB 两点,从 A 开始,横向和竖向把所有和 A 能直线连接的点找出来,用这些点和 B 点做一个拐点的检测,显然 A 点下边的那个点可以通过绿色的那个点可以通过一个拐点的方式和 B 点连接起来,
哈哈,是不是很简单啊,上边的就是连连看的核心内容
接下来详细介绍一下各个脚本的作用,(哇哈哈,以注释的形式给大家介绍吧)
GameManager.cs 游戏的核心代码,产生图片,判断是否可以销毁等
复制代码
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
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
|
[color=#008ef1][font=宋体]using UnityEngine;[/font][/color]
using System.Collections;
using System.Collections.Generic;
public class GameManager : MonoBehaviour
{
public DrawLine drawLine;//画线
public GameObject tilePrefab;//tile的预制
public List<Tile> tiles;//开始实例化的时候存放tile
public List<Tile> _tiles;//存放随机摆放的tile
public List<Tile> tilesEdge;//为了边界处可以有拐点,把棋盘四周的tile放在这里,这里的tile看不到
public int x, y;//棋牌的大小,两个数必须是偶数
private Tile tileA;
private Tile tileB;
private bool destroy;
private Vector3 mousePos;
private enum stepType//控制游戏的状态
{
one,
two,
three
}
private stepType _stepType;
void Start ()
{
this.gameObject.transform.position = Vector3.zero;
Spawn ();
_stepType = stepType.one;
}
private void Spawn ()//实例化tile
{
float num = (x * y - (2 * x + 2 * y - 4)) * 0.5f;
for (int i = 0; i <num; i ++) {
int idTex = Random.Range (20, 45);
GameObject obj = Instantiate (tilePrefab) as GameObject;
GameObject obj2 = Instantiate (tilePrefab) as GameObject;
Tile tile = obj.GetComponent<Tile> ();
Tile tile2 = obj2.GetComponent<Tile> ();
tile.Init (idTex);
tile2.Init (idTex);
tiles.Add (tile);
tiles.Add (tile2);
}
for (int i = 0; i<((2*x+2*y) -4); i++) {//实例化边缘的tile
GameObject obj = Instantiate (tilePrefab) as GameObject;
obj.name = "edage";
Tile tile = obj.GetComponent<Tile> ();
tilesEdge.Add (tile);
}
CreatTile ();
for (int i = 0; i < _tiles.Count; i++) {
_tiles [i].transform.name = i.ToString ();
_tiles [i].id = i;
}
this.transform.position = new Vector3 (-(x / 2.0f - 0.5f), -(y / 2.0f - 0.5f), 0);
}
private void CreatTile ()//随机摆放tile,如果是边缘的就放在边缘位置
{
int idTex = 0;
float _y = 0.0f;
for (int i = 0; i < y; i ++) {
float _x = 0.0f;
for (int j = 0; j < x; j ++) {
if (i == 0 || j == 0 || i == y - 1 || j == x - 1) {
tilesEdge [0].transform.position = new Vector3 (_x, _y, 0);
tilesEdge [0].pos = new Vector2 (_x, _y);
tilesEdge [0].transform.rotation = new Quaternion (0, 0, 180, 0);
tilesEdge [0].transform.parent = this.gameObject.transform;
_tiles.Add (tilesEdge [0]);
tilesEdge [0].transform.localScale = Vector3.zero;
tilesEdge [0].type = false;
tilesEdge.RemoveAt (0);
} else {
int id = Mathf.FloorToInt (Random.Range (0, tiles.Count));
tiles [id].transform.position = new Vector3 (_x, _y, 0);
tiles [id].pos = new Vector2 (_x, _y);
tiles [id].transform.rotation = new Quaternion (0, 0, 180, 0);
tiles [id].transform.parent = this.gameObject.transform;
_tiles.Add (tiles [id]);
tiles.RemoveAt (id);
}
_x += 1;
}
_y += 1;
}
}
private void SelectTile ()//开始选择图片,通过射线方式选中,如果tileA和tileB不相同,则tileA等于tileB开始下一个检测
{
Ray ray = Camera.mainCamera.ScreenPointToRay (mousePos);
RaycastHit hit;
int mask = 1 << 8;
if (Physics.Raycast (ray, out hit, mask)) {
if (tileA == null) {
tileA = hit.transform.GetComponent<Tile> ();
tileA.SetTileTexture (1);
// print ("tileA = hit.transform.GetComponent<Tile> ();" + tileA.transform.name);
} else {
tileB = hit.transform.GetComponent<Tile> ();
tileB.SetTileTexture (1);
// print ("tileB = hit.transform.GetComponent<Tile> ();" + tileB.transform.name);
Compare (tileA, tileB);
if (tileA == null ;; tileB == null) {
// print ("a and b is null");
}
}
// hit.transform.GetComponent
}
}
private void Compare (Tile tile1, Tile tile2)//比较两个点是否可以连接到一起
{
// same card
_stepType = stepType.one;
drawLine.waypoints.Add (tile1.transform); //第一个选择的tile是画线的起始位置,
drawLine.transform.position = tile1.transform.position;
destroy = false;
print ("compare");
if (tile1.pos.x == tile2.pos.x ;; tile1.pos.y == tile2.pos.y) {如果选中的是同一个图片返回
tileA.SetTileTexture (0);
// tileB.SetTileTexture (0);
tileA = tileB;
tileB = null;
// tileA.SetTileTexture (1);
return;
} else if (tile1.pos.x == tile2.pos.x ;; tile1.pos.y != tile2.pos.y) {//如果两点的x相等,竖向检测
print ("check y");
destroy = CheckY (tile1, tile2);
if (destroy)
drawLine.waypoints.Add (tile2.transform);
} else if (tile1.pos.x != tile2.pos.x ;; tile1.pos.y == tile2.pos.y) {//如果两点的y相等,横向检测
print ("check x");
destroy = CheckX (tile1, tile2);
if (destroy)
drawLine.waypoints.Add (tile2.transform);
}
if (!destroy) {//不符合直线连接方式的开始进行一个拐点的检测
_stepType = stepType.two;
destroy = CheckTwoStep (tile1, tile2);
// print ("destroy = CheckTwoStep (tile1, tile1);:" + destroy);
print ("check two step");
if (!destroy) {//不符合直线和一个拐点检测的开始进行两个拐点的检测
_stepType = stepType.three;
destroy = CheckThreeStep (tile1, tile2);
print ("check three:" + destroy);
print ("tile1.idTex:" + tile1.idTex + "tile1.idTex:" + tile1.idTex);
}
}
if (destroy) {//如果符合销毁条件销毁图片,并开始画线
tile1.transform.localScale = Vector3.zero;
tile2.transform.localScale = Vector3.zero;
tile1.type = false;
tile2.type = false;
tileA = null;
tileB = null;
drawLine.MoveToWaypoint ();
} else {//不符合的话,清除画线中的路径
drawLine.ClearPath ();
tileA.SetTileTexture (0);
// tileB.SetTileTexture (0);
tileA = tileB;
tileB = null;
return;
}
}
// one step横向检测
private bool CheckX (Tile a, Tile b)
{
bool compare = true;
int _min, _max;
if (a.idTex == b.idTex) {
CompareID (a, b, out _min, out _max);
_min += 1;
if (_min == _max)
return true;
for (int i = _min; i < _max; i++) {
if (_tiles [i].type == true) {
compare = false;
break;
}
}
return compare;
} else
return false;
}
//竖向检测
private bool CheckY (Tile a, Tile b)
{
bool compare = true;
int _min, _max;
// int idA = (int)(a.x * x + a.y);
// int idB = (int)(b.x * x + b.y);
// print (_tiles [idA].id.ToString () + "idA:" + idA);
// print (_tiles [idB].id.ToString () + "idB:" + idB);
// print ("a.idtex:" + a.idTex + "b.idtex:" + b.idTex);
if (a.idTex == b.idTex) {
CompareID (a, b, out _min, out _max);
_min += x;
if (_min == _max)
return true;
for (int i = _min; i < _max; i+=x) {
// print ("1step");
if (_tiles [i].type == true) {
compare = false;
break;
}
}
// if (compare) {
// print ("2step");
// a.type = false;
// b.type = false;
// }
return compare;
} else
return false;
}
// two step一个拐点的检测
private bool CheckTwoStep (Tile a, Tile b)
{
if (a.pos.x == b.pos.x || a.pos.y == b.pos.y)
return false;
int id1 = (int)(a.pos.y * x + b.pos.x);
if (_tiles [id1].type == false) {
_tiles [id1].idTex = a.idTex;
if (CheckY (_tiles [id1], b)) {
if (CheckX (a, _tiles [id1])) {
if (_stepType == stepType.two) {
drawLine.waypoints.Add (_tiles [id1].transform);
drawLine.waypoints.Add (b.transform);
} else if (_stepType == stepType.three) {
drawLine.waypoints.Add (_tiles [id1].transform);
print ("=====================:" + 1);
}
return true;
}
// else
// return false;
}
}
int id2 = (int)(b.pos.y * x + a.pos.x);
if (_tiles [id2].type == false) {
_tiles [id2].idTex = b.idTex;
if (CheckY (a, _tiles [id2])) {
if (CheckX (b, _tiles [id2])) {
if (_stepType == stepType.two) {
drawLine.waypoints.Add (_tiles [id2].transform);
drawLine.waypoints.Add (b.transform);
} else if (_stepType == stepType.three) {
drawLine.waypoints.Add (_tiles [id2].transform);
print ("=====================:" + 2);
}
return true;
}
// else
// return false;
}
}
return false;
}
// three step两个拐点的检测
private bool CheckThreeStep (Tile a, Tile b)
{
print ("a:" + a.idTex + "b:" + b.idTex);
// if (a.pos.x == b.pos.x || a.pos.y == b.pos.y) return false;
bool returnValue = false;
print ("returnValue:" + returnValue);
List<Tile> _comparrPointsB;
ComparePoints (b, out _comparrPointsB);//返回b点可以横竖直线相连的点
for (int i =0; i<_comparrPointsB.Count; i++) {
returnValue = CheckTwoStep (a, _comparrPointsB [i]);
if (returnValue) {
drawLine.waypoints.Add (_comparrPointsB [i].transform);
drawLine.waypoints.Add (b.transform);
return returnValue;
}
}
if (!returnValue) {
List<Tile> _comparrPointsA;
ComparePoints (a, out _comparrPointsA);
print (a.name);
print (b.name);
for (int i =0; i<_comparrPointsA.Count; i++) {
print ("--------------" + b.idTex);
returnValue = CheckTwoStep (b, _comparrPointsA [i]);
if (returnValue) {
drawLine.waypoints.Add (_comparrPointsA [i].transform);
drawLine.waypoints.Add (b.transform);
return returnValue;
}
}
}
return returnValue;
}
//两个拐点的时候返回可以与a横竖直线相连的点
private void ComparePoints (Tile a, out List<Tile> comparePoints)
{
print ("a.idtex" + a.idTex);
comparePoints = new List<Tile> ();
comparePoints.Clear ();
// for (int i = 0; i < y; i ++) {
// if (i != a.y) {
// int id = (int)(i * x + a.pos.x);
// if (_tiles [id].type == false) {
// comparePoints.Add (_tiles [id]);
// _tiles [id].idTex = a.idTex;
// }
// }
// }
for (int i = (int)a.pos.y - 1; i >-1; i--) {
int id = (int)(i * x + a.pos.x);
// print ("three step :" + id);
if (_tiles [id].type == false) {
comparePoints.Add (_tiles [id]);
_tiles [id].idTex = a.idTex;
print ("_tiles [id].idTex = a.idTex; " + _tiles [id].idTex);
} else
break;
}
for (int i = (int)a.pos.y + 1; i < y; i++) {
int id = (int)(i * x + a.pos.x);
// print ("three step :" + id);
if (_tiles [id].type == false) {
comparePoints.Add (_tiles [id]);
_tiles [id].idTex = a.idTex;
print ("_tiles [id].idTex = a.idTex; " + _tiles [id].idTex);
} else
break;
}
for (int i = (int)a.pos.x -1; i >-1; i --) {
int id = (int)(a.pos.y * x + i);
if (_tiles [id].type == false) {
comparePoints.Add (_tiles [id]);
_tiles [id].idTex = a.idTex;
print ("_tiles [id].idTex = a.idTex; " + _tiles [id].idTex);
} else
break;
}
for (int i = (int)a.pos.x +1; i < x; i ++) {
int id = (int)(a.pos.y * x + i);
if (_tiles [id].type == false) {
comparePoints.Add (_tiles [id]);
_tiles [id].idTex = a.idTex;
print ("_tiles [id].idTex = a.idTex; " + _tiles [id].idTex);
} else
break;
}
// for (int i = 0; i < x; i ++) {
// if (i != a.x) {
// int id = (int)(a.pos.y * x + i);
// if (_tiles [id].type == false) {
// comparePoints.Add (_tiles [id]);
// _tiles [id].idTex = a.idTex;
// }
// }
// }
}
private void CompareID (Tile a, Tile b, out int min, out int max)
{
if (a.id < b.id) {
min = a.id;
max = b.id;
} else {
min = b.id;
max = a.id;
}
}
Vector2 TexSize ()
{
Vector2 size = new Vector2 (1 / x, 1 / y);
return size;
}
Vector2 TexOffset (int _idTex)
{
int a = (int)(_idTex / x);
// print (a + "a:" + _idTex);
int b = (int)(_idTex % x);
// print (b + "b:" + _idTex);
Vector2 offset = new Vector2 (b / x, (y - 1 - a) / y);
return offset;
}
void Update ()
{
if (Input.GetMouseButtonUp (0)) {
mousePos = Input.mousePosition;
SelectTile ();
}
}
private void ClearTiles (List<Tile> tiles)
{
tiles.Clear ();
// this.gameObject.transform.DetachChildren();
}
}
// ari
|
复制代码
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
|
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class DrawLine : MonoBehaviour
{
public List<Transform> waypoints = new List<Transform> ();
public float rate = 1;
private int currentWaypoint = 1;
public void MoveToWaypoint ()
{
print ("public void MoveToWaypoint (): " + waypoints.Count);
StartCoroutine ("move");
}
public void ClearPath ()
{
waypoints.Clear ();
print ("path.Clear ();");
}
IEnumerator move ()
{
for (int i = 0; i < waypoints.Count; i++) {
iTween.MoveTo (this.gameObject, waypoints [i].position, rate);
print ("now id:" + i);
yield return new WaitForSeconds(rate);
}
waypoints.Clear ();
}
}
|
复制代码
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
|
using UnityEngine;
using System.Collections;
public class Tile : MonoBehaviour
{
public int id;
public int idTex; //通过这个判断两个图片是否相同
public Vector2 pos ;
public bool type = true;//控制图片的状态,当销毁的时候为false,其他判断的时候可以通过该点
public float x, y;
public Texture texA, texB;//鼠标选中的时候可以换贴图
public GameObject mask;//鼠标选中的时候上边显示的框框
public void Init (int _idTex)
{
idTex = _idTex;
Vector2 offset = TexOffset (_idTex);
this.renderer.material.SetTextureOffset ("_MainTex", offset);
this.renderer.material.SetTextureScale ("_MainTex", new Vector2 (0.2f, 0.1f));
}
//设置tile显示的贴图和大小
public void SetTileTexture (int i)
{
if (i == 0) {
this.renderer.material.mainTexture = texA;
mask.transform.localScale = Vector3.zero;
}
if (i == 1) {
this.renderer.material.mainTexture = texB;
mask.transform.localScale = new Vector3 (0.1380835f, 0.1380835f, 0.1380835f);
}
}
//这个就是裁剪一张大图,变成一个个小的,贴到tile上
Vector2 TexOffset (int _idTex)
{
int a = (int)(_idTex / x);
int b = (int)(_idTex % x);
Vector2 offset = new Vector2 (b / x, (y - 1 - a) / y);
return offset;
}
Vector2 TexSize ()
{
Vector2 size = new Vector2 (1 / x, 1 / y);
return size;
}
}
|
Menu.cs 加了两个按钮,可以重新开始,哇哈哈
复制代码
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
|
using UnityEngine;
using System.Collections;
public class Menu : MonoBehaviour
{
public GameManager gameManager;
private GameManager _gameManger;
private bool start = true;
void OnGUI ()
{
if (start) {
if (GUI.Button (new Rect (10, 10, 100, 50), "start")) {
start = false;
_gameManger = Instantiate (gameManager) as GameManager;
}
}
if (GUI.Button (new Rect (10, 70, 100, 50), "restart")) {
if (_gameManger != null) {
Destroy (_gameManger.gameObject);
print ("Destroy(_gameManger.gameObject);");
}
_gameManger = Instantiate (gameManager) as GameManager;
}
}
}
|
from:http://game.ceeger.com/forum/read.php?tid=4855&fid=2&page=1