Here’s the main class :
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Grid : MonoBehaviour
{
public static int score = 0;
public static string message = "";
public static string recordText = "RECORD
<size=20>“+PlayerPrefs.GetInt(“Player Best Score”)+”";
public static bool stocked = false;
public static Group stockedGroup = null;
public static Group actualGroup = null;
public static Group cancelActualGroup = null;
public static Group cancelRandomGroup = null;
public static int cancelScore = 0;
public static int w = 10;
public static int h = 10;
public static bool quitCheck = false;
public static bool muted = false;
public static List<int> deletedRows;
public static List<int> deletedColumns;
public static Transform[,] grid = new Transform[w, h];
public static Transform[,] deleted = new Transform[w, h];
public static Spawner spawner;
void Start()
{
quitCheck = false;
}
public static Vector2 roundVec2(Vector2 v)
{
return new Vector2(Mathf.Round(v.x),
Mathf.Round(v.y));
}
public static Vector3 roundVec3(Vector3 v)
{
return new Vector3(Mathf.Round(v.x),
Mathf.Round(v.y),
v.z);
}
public static bool insideBorder(Vector2 pos)
{
return ((int)pos.x >= 0 &&
(int)pos.x < w &&
(int)pos.y >= 0 &&
(int)pos.y < h);
}
public static void deleteRow(int y)
{
for (int x = 0; x < w; x++)
{
grid[x, y].renderer.enabled = false;
//grid[x, y].position += new Vector3(-10F,0F,0F);
deleted[x, y] = grid[x, y];
grid[x, y] = null;
}
}
public static void deleteColumn(int x)
{
for (int y = 0; y < h; y++)
{
if (grid[x, y] != null)
{
grid[x, y].renderer.enabled = false;
//grid[x, y].position += new Vector3(-10F, 0F, 0F);
deleted[x, y] = grid[x, y];
grid[x, y] = null;
}
}
}
public static void decreaseRow(int y)
{
for (int x = 0; x < w; x++)
{
grid[x, y - 1] = grid[x, y]; // Move one towards bottom
if (grid[x, y - 1] != null) { grid[x, y - 1].position += new Vector3(0, -1, 0); } // Update Block position
grid[x, y] = null;
}
}
public static void increaseRow(int y)
{
for (int x = 0; x < w; x++)
{
grid[x, y + 1] = grid[x, y]; // Move one towards top
if (grid[x, y + 1] != null) { grid[x, y + 1].position += new Vector3(0, 1, 0); } // Update Block position
grid[x, y] = null;
}
}
public static void decreaseColumn(int x)
{
for (int y = 0; y < h; y++)
{
grid[x - 1, y] = grid[x, y]; // Move one towards left
if (grid[x - 1, y] != null) { grid[x - 1, y].position += new Vector3(-1, 0, 0); } // Update Block position
grid[x, y] = null;
}
}
public static void increaseColumn(int x)
{
for (int y = 0; y < h; y++)
{
if (grid[x, y] != null)
{
grid[x + 1, y] = grid[x, y]; // Move one towards right
if (grid[x + 1, y] != null) { grid[x + 1, y].position += new Vector3(1, 0, 0); } // Update Block position
grid[x, y] = null;
}
}
}
public static void decreaseRowsAbove(int y)
{
for (int i = y; i < h; i++)
decreaseRow(i);
}
public static void increaseRowsAbove(int y)
{
for (int i = h-2; i >= y; i--)
increaseRow(i);
}
public static void increaseRowsUnder(int y)
{
for (int i = y; i >= 0; i--)
increaseRow(i);
}
public static void decreaseRowsUnder(int y)
{
for (int i = 1; i <= y; i++)
decreaseRow(i);
}
public static void decreaseColumnsAbove(int x)
{
for (int i = x; i < w; i++)
decreaseColumn(i);
}
public static void decreaseColumnsUnder(int x)
{
for (int i = 1; i <= x; i++)
decreaseColumn(i);
}
public static void increaseColumnsUnder(int x)
{
for (int i = x; i >= 0; i--)
increaseColumn(i);
}
public static void increaseColumnsAbove(int x)
{
for (int i = w-2; i >= x; i--)
increaseColumn(i);
}
public static bool isRowFull(int y)
{
for (int x = 0; x < w; ++x)
if (grid[x, y] == null)
return false;
return true;
}
public static bool isColumnFull(int x)
{
int compteur = 0;
for (int y = 0; y < h; ++y)
{
if (grid[x, y] != null)
{ compteur++; }
}
if (compteur >= h - deletedRows.Count) { return true; }
else { return false; }
}
public static void clearDeleted()
{
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
if (deleted[x,y] != null)
{
Destroy(deleted[x, y].gameObject);
deleted[x, y] = null;
}
}
}
}
public static void deleteFullRowsAndColumns()
{
clearDeleted();
deletedRows = new List<int>();
for (int y = 0; y < 5; ++y)
{
if (isRowFull(y))
{
deleteRow(y);
deletedRows.Add(y);
increaseRowsUnder(y - 1);
}
}
for (int y = h-1; y >= 5; --y)
{
if (isRowFull(y))
{
deleteRow(y);
deletedRows.Add(y);
decreaseRowsAbove(y + 1);
}
}
deletedColumns = new List<int>(); ;
for (int x = 0; x < 5; ++x)
{
if (isColumnFull(x))
{
deleteColumn(x);
deletedColumns.Add(x);
increaseColumnsUnder(x - 1);
}
}
for (int x = w-1; x >= 5; --x)
{
if (isColumnFull(x))
{
deleteColumn(x);
deletedColumns.Add(x);
decreaseColumnsAbove(x + 1);
}
}
score += (deletedRows.Count + deletedColumns.Count) * (deletedRows.Count + deletedColumns.Count);
if (deletedRows.Count + deletedColumns.Count > 0)
{
if (score > PlayerPrefs.GetInt("Player Best Score"))
{
recordText = "
NEW RECORD";
PlayerPrefs.SetInt(“Player Best Score”, score);
PlayerPrefs.Save();
}
spawner.updateScore();
}
foreach (Group grp in FindObjectsOfType())
{
if (grp.transform.childCount == 0)
{ Destroy(grp.gameObject); }
}
}
public static void restoreRow(int y)
{
for (int x = 0; x<w; x++)
{
if (deleted[x, y] != null)
{
grid[x, y] = deleted[x, y];
grid[x, y].renderer.enabled = true;
//deleted[x, y].position -= new Vector3(-10F, 0F, 0F);
deleted[x, y] = null;
}
}
}
public static void restoreColumn(int x)
{
for (int y = 0; y < h; y++)
{
if (deleted[x, y] != null)
{
grid[x, y] = deleted[x, y];
grid[x, y].renderer.enabled = true;
//deleted[x, y].position -= new Vector3(-10F, 0F, 0F);
deleted[x, y] = null;
}
}
}
public static void stock()
{
if (stockedGroup == null)
{
stockedGroup = actualGroup;
actualGroup = null;
FindObjectOfType<Spawner>().spawnNext(); // Spawn next Group
stockedGroup.recolorate();
stockedGroup.enabled = false;
stockedGroup.transform.position = new Vector3(1, h+1.75F, (float)-0.5);
stockedGroup.transform.localScale = new Vector3(0.5F, 0.5F, 1);
}
else
{
Group temp = stockedGroup;
stockedGroup = actualGroup;
actualGroup = temp;
stockedGroup.recolorate();
stockedGroup.enabled = false;
actualGroup.enabled = true;
stockedGroup.transform.position = new Vector3(1, h + 1.75F, (float)-0.5);
stockedGroup.transform.localScale = new Vector3(0.5F, 0.5F, 1);
actualGroup.transform.position = new Vector3((int)(w/2), (int)(h/2), (float)-0.5);
actualGroup.transform.localScale = new Vector3(1, 1, 1);
}
stocked = !stocked;
}
//public static bool lost()
//{
// if (stockedGroup != null && actualGroup != null)
// { return !actualGroup.canPlace() && !stockedGroup.canPlace(); }
// Debug.Log("Result : False");
// return false;
//}
public static void blit()
{
actualGroup.blit();
spawner.updateMessage();
}
public static void rotate()
{
actualGroup.rotate();
}
public static List<int> mySort(List<int> l)
{
List<int> l1 = new List<int>();
List<int> l2 = new List<int>();
l1 = l.FindAll(delegate(int i) { return i < 5; });
l2 = l.FindAll(delegate(int i) { return i >= 5; });
l1.Sort(delegate(int x, int y) { return -x.CompareTo(y); });
l2.Sort(delegate(int x, int y) { return x.CompareTo(y); });
l1.AddRange(l2);
return l1;
}
public static void cancel()
{
if (cancelActualGroup != null)
{
score = cancelScore;
spawner.updateScore();
if (deletedColumns.Count > 0)
{
deletedColumns = mySort(deletedColumns);
foreach (int y in deletedColumns)
{
if (y >= 5)
{
increaseColumnsAbove(y);
restoreColumn(y);
}
else
{
decreaseColumnsUnder(y);
restoreColumn(y);
}
}
}
if (deletedRows.Count > 0)
{
deletedRows = mySort(deletedRows);
foreach (int x in deletedRows)
{
if (x >= 5)
{
increaseRowsAbove(x);
restoreRow(x);
}
else
{
decreaseRowsUnder(x);
restoreRow(x);
}
}
}
if (stocked) // if the actualGroup had been stocked then it means that stockedGroup is supposed to be actualGroup
{
stock();
}
cancelRandomGroup = actualGroup;
cancelRandomGroup.enabled = false;
foreach (Transform child in cancelRandomGroup.transform)
{
child.renderer.enabled = false;
}
actualGroup = cancelActualGroup;
actualGroup.unblit();
actualGroup.enabled = true;
cancelActualGroup = null;
}
else
{
message = "Sorry, you can only revert once in a row !";
spawner.updateMessage();
}
}
public static void mute()
{
AudioListener.pause = true;
//AudioListener.volume = 100;
muted = true;
}
public static void unmute()
{
AudioListener.pause = false;
//AudioListener.volume = 0;
muted = false;
}
public static void quit()
{
if (quitCheck)
{
Application.LoadLevel("Menu");
}
else
{
spawner.quitText.text = "SURE ?";
quitCheck = true;
}
}
public static void unquit()
{
spawner.quitText.text = "QUIT";
quitCheck = false;
}
}
The group class :
using UnityEngine;
using System.Collections;
public class Group : MonoBehaviour
{
public Sprite block;
public Sprite original;
private Color colour;
// Use this for initialization
void Start()
{
Grid.actualGroup = this;
colour = RandomColour();
foreach (Transform child in transform)
{
child.renderer.material.color = colour;
child.localScale = new Vector3(0.75F, 0.75F, 1);
}
//Debug.Log("Verif defaite");
//if (Grid.lost()) { Debug.Log(" DEFAAAAIIIIITE"); } //Application.LoadLevel("Menu"); }
}
public Color RandomColour()
{
int rnd = Random.Range(0, 6);
switch (rnd)
{
case 0: return Color.blue;
case 1: return Color.cyan;
case 2: return Color.white;
case 3: return Color.grey;
case 4: return Color.magenta;
case 5: return Color.yellow;
case 6: return Color.green;
default: return Color.white;
}
}
// Update is called once per frame
void Update()
{
colorate();
// Only if 1 finger :
//for (int i = 0; i < Input.touchCount; i++)
if (Input.touchCount == 1)
{
Touch touch = Input.GetTouch(0);
// -- Touch
// ------------------------------------------------
if ( touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved )
{
// Touch are screens location. Convert to world
Vector3 position = Camera.main.ScreenToWorldPoint(touch.position);
//Grid.message = "Touch position : " + touch.position + ", world position : " + position;
if (position.y >= -1 && position.y < Grid.h )
{
// Reset quit
Grid.unquit();
// Effect for feedback
position.z = (float)-0.5;
transform.position = Grid.roundVec3(position);
validatePos();
}
}
}
#if UNITY_EDITOR
if (Input.GetMouseButtonDown(0))
{
Vector3 position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
//Grid.message = "Touch position : " + touch.position + ", world position : " + position;
if (position.y >= -1 && position.y < Grid.h)
{
// Reset quit
Grid.unquit();
// Effect for feedback
position.z = (float)-0.5;
transform.position = Grid.roundVec3(position);
validatePos();
}
}
#endif
}
public void colorate()
{
foreach (Transform child in transform)
{
Vector2 v = Grid.roundVec2(child.position);
{ child.renderer.material.color = colour; }
if (Grid.grid[(int)v.x, (int)v.y] != null)
{ child.renderer.material.color = Color.red; }
}
}
public void recolorate()
{
foreach (Transform child in transform)
{
{ child.renderer.material.color = colour; }
}
}
public bool canBlit()
{
foreach (Transform child in transform)
{
Vector2 v = Grid.roundVec2(child.position);
if (Grid.grid[(int)v.x, (int)v.y] != null)
{ return false; }
}
return true;
}
public void blit()
{
if (canBlit())
{
// Blit children
foreach (Transform child in transform)
{
Vector2 v = Grid.roundVec2(child.position);
child.position += new Vector3(0, 0, (float)0.5);
Grid.grid[(int)v.x, (int)v.y] = child;
child.renderer.material.color = colour;
child.localScale = new Vector3(1, 1, 1);
child.GetComponent<SpriteRenderer>().sprite = block;
}
// Disable script
enabled = false;
// Save groups to enventually revert later
Grid.cancelActualGroup = this;
Grid.cancelScore = Grid.score;
// Clear filled horizontal lines
Grid.deleteFullRowsAndColumns();
// Spawn next Group
FindObjectOfType<Spawner>().spawnNext();
// Reset stocked
Grid.stocked = false;
// Reset message
Grid.message = "";
}
}
public void unblit()
{
foreach (Transform child in transform)
{
Vector2 v = Grid.roundVec2(child.position);
child.position -= new Vector3(0, 0, (float)0.5);
Grid.grid[(int)v.x, (int)v.y] = null;
child.localScale = new Vector3(0.75F, 0.75F, 1);
child.GetComponent<SpriteRenderer>().sprite = original;
}
}
public static int min ( int a, int b)
{
if (a < b) { return a; }
else { return b; }
}
bool isValidGridPos()
{
foreach (Transform child in transform)
{
Vector2 v = Grid.roundVec2(child.position);
// Not inside Border?
if (!Grid.insideBorder(v))
return false;
}
return true;
}
void validatePos()
{
bool invalid = true;
while (invalid)
{
invalid = false;
foreach (Transform child in transform)
{
Vector2 v = Grid.roundVec2(child.position);
if (v.x >= Grid.w) { transform.position += new Vector3(-1, 0, 0); invalid = true; }
if (v.x < 0) { transform.position += new Vector3(1, 0, 0); invalid = true; }
if (v.y >= Grid.h) { transform.position += new Vector3(0, -1, 0); invalid = true; }
if (v.y < 0) { transform.position += new Vector3(0, 1, 0); invalid = true; }
}
}
}
//public bool canPlace()
//{
// for (int k = 0; k < 4; k++)
// {
// for (int i = 0; i < Grid.w; i++)
// {
// for (int j = 0; j < Grid.h; j++)
// {
// if (canPlace(i, j)) { Debug.Log("CAN PLACE "+transform+" AT : ("+i+","+j+")"); return true; }
// }
// }
// transform.Rotate(0, 0, -90);
// }
// return false;
//}
//public bool canPlace(int x, int y)
//{
// foreach (Transform child in transform)
// {
// Vector2 v = Grid.roundVec2(child.localPosition);
// v.x += x;
// v.y += y;
// if (v.x >= Grid.w || v.x < 0 || v.y >= Grid.h || v.y < 0) { Debug.Log(" Check (" + v.x + "," + v.y + ") : HORS LIMITES"); return false; }
// if (Grid.grid[(int)v.x, (int)v.y] != null) { Debug.Log(" Check (" + v.x + "," + v.y + ") : PEUT PAS POSER"); return false; }
// }
// return true;
//}
public void rotate()
{
// Rotate
transform.Rotate(0, 0, -90);
validatePos();
colorate();
}
}
And finally the Spawner class :
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Spawner : MonoBehaviour
{
// Groups
public Text buttonText;
public Text scoreText;
public Text messageText;
public Text muteText;
public Text quitText;
public GameObject[] groups;
public void spawnNext()
{
if (Grid.cancelRandomGroup != null)
{
Grid.actualGroup = Grid.cancelRandomGroup;
Grid.cancelRandomGroup = null;
Grid.actualGroup.enabled = true;
foreach (Transform child in Grid.actualGroup.transform)
{
child.renderer.enabled = true;
}
}
else
{
// Random Index
int i = Random.Range(0, Group.min((groups.Length), (int)(6 + (Grid.score) / 6)));
// Spawn Group at current Position
Instantiate(groups*, transform.position, Quaternion.identity);*
}
}
void Start()
{
// Mute if set to true
if (Grid.muted) { Grid.mute(); muteText.text = “UNMUTE”; }
else { muteText.text = “MUTE”; }
// Refer to Spawner in Grid
Grid.spawner = this;
// Spawn initial Group
spawnNext();
// Set score to 0
scoreText.text = “SCORE
<color=red><size=20>” + Grid.score + "<color=cyan>
" + Grid.recordText + “”;
}
void Update()
{
}
public void updateScore()
{
scoreText.text = “SCORE
<color=red><size=20>” + Grid.score + "<color=cyan>
" + Grid.recordText + “”;
}
public void updateMessage()
{
messageText.text = Grid.message;
}
public void demandeStock() { buttonText.text = “” ; Grid.stock(); }
public void demandeTourner() { Grid.rotate(); }
public void demandeBlit() { Grid.blit(); }
public void demandeCancel() { Grid.cancel(); }
public void demandeQuit() { Grid.quit(); }
public void demandeMute()
{
if (Grid.muted) { Grid.unmute(); muteText.text = “MUTE”; }
else { Grid.mute(); muteText.text = “UNMUTE”; }
}
}