总算是等到周末自己的时间了,花了不少时间完善一下做的连连看了,顺便写个小教程分享给大家,哇哈哈~<题外话:北京的冬天太***的冷了,冻的洒家手脚冰凉>
之前上传的工程文件和exe包现在已经更新,加了画线,修改了边缘不能拐点
连通的类型:
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 游戏的核心代码,产生图片,判断是否可以销毁等
[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
DrawLine.cs 画线脚本,用的itween,哈哈
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 ();
}
}
Tile.cs
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 加了两个按钮,可以重新开始,哇哈哈
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;
}
}
}