Je suis nouveau dans Unity et C# et je cherche à apprendre en créant un jeu 2D de type Match 3 (Candy Crush, Bejeweled, etc).
Mon projet a bien avancé grace à un cours que j'ai suivi sur le sujet. Aujourd'hui, j'essaie d'étendre les fonctionnalités du jeu étudié en me basant sur son code pour l'étendre selon mes besoins.
Actuellement, le jeu permet de réaliser des "match" de 3 ou + pieces de même couleur dans une grille à 4 côtés (type carré, rectangle). Lorsqu'on réalise un "match", les pièces correspondantes sont détruites et les pièces au dessus viennent combler le trou laissé dans la grille. De nouvelles pièces viennent ensuite en haut de la grille afin qu'elle soit toujours complète.
Nous avons donc ici différentes pièces (et donc plusieurs Prefab) :
- PieceBG qui est un Prefab contenant un simple Sprite qui définira le "fond" des pièces sur la grille, aucun fond pour les pièces de type NONE;
- EmptyPiecePrefab est simplement un GameObject "vide". Il a le script GamePiece attaché pour la gestion du remplacement des pièces dans la grille (voir plus bas le script);
- NormalPiecePrefab contient une pièce normale qui peut prendre différentes couleurs;
- ColumnClearPiecePrefab est un dérivé de NormalPiecePrefab qui gérera la destruction de toutes les pièces d'une même colonne;
- RowClearPiecePrefab, idem que celui-ci dessus mais pour les "lignes".
Je ne vais pas mettre tous les scripts ici car ce n'est pas vraiment nécessaire, seule le script Grid est nécessaire pour le moment.
Voici les fonctionnalités/correction que j'aimerais ajouter/apporter :
- Permettre la création d'une grille "à trous" ou de forme variée (exemple une grille en forme de +). C'est codé en grande partie maintenant mais il reste un problème : actuellement, la grille se remplit "par le haut". Donc, si le "haut" de la grille est "bouché" par des pièces de type ROCK (indestructibles, non Movable), ICE (destructibles mais non Movable) ou NONE (justement un type de pièce permettant de dessiner une grille de forme autre que carré/rectangle, non Movable), elle ne se remplira pas. Il faut donc modifier FillStep() et SpawnNewPiece à mon avis pour permettre de remplir la grille en tenant compte de ces pièces.
- Corriger la fonction Shuffle pour qu'au lieu de changer aléatoirement la couleur des pièces "Movable", elle les déplace dans la grille.
- Ajouter un système de récolte d'ingrédients. Mais ça, c'est pour plus tard si je trouve quelqu'un pour m'aider.
Je précise qu'étant débutant, j'aimerais bien qu'on m'explique les modifications apportées au code afin que je profite au mieux de votre expérience
Et maintenant, voici le script Grid.cs. Si besoin, je peux fournir un certain type de script sur demande mais je ne pense pas que ce soit utile pour le moment, ce le sera probablement pour la partie ingrédients.
Code : Tout sélectionner
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Grid : MonoBehaviour {
public enum PieceType
{
EMPTY,
NORMAL,
ICE,
ROW_CLEAR,
COLUMN_CLEAR,
RAINBOW,
NONE,
ROCK,
COUNT,
};
[System.Serializable]
public struct PiecePrefab
{
public PieceType type;
public GameObject prefab;
};
[System.Serializable]
public struct PiecePosition
{
public PieceType type;
public int x;
public int y;
};
// Grid size
public int xDim;
public int yDim;
// Time to fill/refill the grid
public float fillTime;
// Used to call the level class
public Level level;
// Array of piece types that can be defined in the inspector
public PiecePrefab[] piecePrefabs;
// GameObject to set a background for our pieces
public GameObject backgroundPrefab;
// Used to set our initial pieces in the inspector, for each level
public PiecePosition[] initialPieces;
// Dictionary for attaching a piece to its prefab
private Dictionary<PieceType, GameObject> piecePrefabDict;
// 2D array to contain all our pieces
private GamePiece[,] pieces;
// Used to move pieces in diag (for filling a grid with obstacles)
private bool inverse = false;
// Used to know wich pieces will be swapped
private GamePiece pressedPiece;
private GamePiece enteredPiece;
Coroutine co;
private bool coroutineIsRunning;
// Set the game over. Doesn't mean that the player loose
private bool gameOver = false;
// Use this for initialization
void Awake () {
piecePrefabDict = new Dictionary<PieceType, GameObject> ();
// First we need to check if we have keys in our dictionary. If not, add them
for (int i = 0; i < piecePrefabs.Length; i++) {
if (!piecePrefabDict.ContainsKey (piecePrefabs [i].type)) {
piecePrefabDict.Add (piecePrefabs [i].type, piecePrefabs [i].prefab);
}
}
// Now we need to add our initial and empty pieces on the grid
pieces = new GamePiece[xDim, yDim];
for (int i = 0; i < initialPieces.Length; i++) {
if (initialPieces [i].x >= 0 && initialPieces [i].x < xDim
&& initialPieces [i].y >= 0 && initialPieces [i].y < yDim) {
SpawnNewPiece (initialPieces [i].x, initialPieces [i].y, initialPieces [i].type);
}
}
// Instantiate the background for all our pieces on the grid
for (int x = 0; x < xDim; x++) {
for (int y = 0; y < yDim; y++) {
if (pieces [x, y] == null || pieces [x, y].Type != PieceType.NONE) { // No background for NONE pieces
GameObject background = (GameObject)Instantiate (backgroundPrefab, GetWorldPosition (x, y), Quaternion.identity);
background.transform.parent = transform;
}
}
}
for (int x = 0; x < xDim; x++) {
for (int y = 0; y < yDim; y++) {
if (pieces [x, y] == null) {
SpawnNewPiece (x, y, PieceType.EMPTY);
}
}
}
// Now the grid is filled with empty pieces, we need to replace them by our non-empty pieces with animation
StartCoroutine(Fill ());
}
// Update is called once per frame
void Update () {
}
// Fill the grid
public IEnumerator Fill()
{
bool needsRefill = true;
if (coroutineIsRunning) {
StopCoroutine (co);
}
while (needsRefill) {
yield return new WaitForSeconds (fillTime);
while (FillStep ()) {
inverse = !inverse;
yield return new WaitForSeconds (fillTime);
}
needsRefill = ClearAllValidMatches ();
}
co = StartCoroutine (advert());
}
// Move a piece to fill the grid
// Todo : add a check for ROCK Pieces so that they'll be ignored when filling the grid as they can't be destroyed and can be on top of the grid
public bool FillStep()
{
bool movedPiece = false;
for (int y = yDim-2; y >= 0; y--)
{
for (int loopX = 0; loopX < xDim; loopX++)
{
int x = loopX;
if (inverse) {
x = xDim - 1 - loopX;
}
GamePiece piece = pieces [x, y];
if (piece.IsMovable ())
{
GamePiece pieceBelow = pieces [x, y + 1];
if (pieceBelow.Type == PieceType.EMPTY) {
Destroy (pieceBelow.gameObject);
piece.MovableComponent.Move (x, y + 1, fillTime);
pieces [x, y + 1] = piece;
SpawnNewPiece (x, y, PieceType.EMPTY);
movedPiece = true;
} else {
for (int diag = -1; diag <= 1; diag++)
{
if (diag != 0)
{
int diagX = x + diag;
if (inverse)
{
diagX = x - diag;
}
if (diagX >= 0 && diagX < xDim)
{
GamePiece diagonalPiece = pieces [diagX, y + 1];
if (diagonalPiece.Type == PieceType.EMPTY)
{
bool hasPieceAbove = true;
for (int aboveY = y; aboveY >= 0; aboveY--)
{
GamePiece pieceAbove = pieces [diagX, aboveY];
if (pieceAbove.IsMovable ())
{
break;
}
else if(!pieceAbove.IsMovable() && pieceAbove.Type != PieceType.EMPTY)
{
hasPieceAbove = false;
break;
}
}
if (!hasPieceAbove)
{
Destroy (diagonalPiece.gameObject);
piece.MovableComponent.Move (diagX, y + 1, fillTime);
pieces [diagX, y + 1] = piece;
SpawnNewPiece (x, y, PieceType.EMPTY);
movedPiece = true;
break;
}
}
}
}
}
}
}
}
}
for (int x = 0; x < xDim; x++)
{
GamePiece pieceBelow = pieces [x, 0];
if (pieceBelow.Type == PieceType.EMPTY)
{
Destroy (pieceBelow.gameObject);
GameObject newPiece = (GameObject)Instantiate(piecePrefabDict[PieceType.NORMAL], GetWorldPosition(x, -1), Quaternion.identity);
newPiece.transform.parent = transform;
pieces [x, 0] = newPiece.GetComponent<GamePiece> ();
pieces [x, 0].Init (x, -1, this, PieceType.NORMAL);
pieces [x, 0].MovableComponent.Move (x, 0, fillTime);
pieces [x, 0].ColorComponent.SetColor ((ColorPiece.ColorType)Random.Range (0, pieces [x, 0].ColorComponent.NumColors));
movedPiece = true;
}
}
return movedPiece;
}
// Used to get the offset of our pieces
public Vector2 GetWorldPosition(int x, int y)
{
return new Vector2 (transform.position.x - xDim / 2.0f + x,
transform.position.y + yDim / 2.0f - y);
}
// Spawn a new piece
public GamePiece SpawnNewPiece(int x, int y, PieceType type)
{
GameObject newPiece = (GameObject)Instantiate (piecePrefabDict [type], GetWorldPosition (x, y), Quaternion.identity);
newPiece.transform.parent = transform;
pieces [x, y] = newPiece.GetComponent<GamePiece> ();
pieces [x, y].Init (x, y, this, type);
return pieces [x, y];
}
// Used to know if piece1 is adjacent to piece2
public bool IsAdjacent(GamePiece piece1, GamePiece piece2)
{
return (piece1.X == piece2.X && (int)Mathf.Abs (piece1.Y - piece2.Y) == 1)
|| (piece1.Y == piece2.Y && (int)Mathf.Abs (piece1.X - piece2.X) == 1);
}
// Swap pieces if they are adjacent
public void SwapPieces(GamePiece piece1, GamePiece piece2)
{
// If the game is over, just disabled this function
if (gameOver) {
return;
}
// Swap only if they are movable
if (piece1.IsMovable () && piece2.IsMovable ()) {
pieces [piece1.X, piece1.Y] = piece2;
pieces [piece2.X, piece2.Y] = piece1;
if (GetMatch (piece1, piece2.X, piece2.Y) != null || GetMatch (piece2, piece1.X, piece1.Y) != null
|| piece1.Type == PieceType.RAINBOW || piece2.Type == PieceType.RAINBOW) {
int piece1X = piece1.X;
int piece1Y = piece1.Y;
// Make some animation while swaping
piece1.MovableComponent.Move (piece2.X, piece2.Y, fillTime);
piece2.MovableComponent.Move (piece1X, piece1Y, fillTime);
// Clear the Rainbow piece manually before clearing matches
if (piece1.Type == PieceType.RAINBOW && piece1.IsClearable () && piece2.IsColored ()) {
ClearColorPiece clearColor = piece1.GetComponent<ClearColorPiece> ();
if (clearColor) {
clearColor.Color = piece2.ColorComponent.Color;
}
ClearPiece (piece1.X, piece1.Y);
}
if (piece2.Type == PieceType.RAINBOW && piece2.IsClearable () && piece1.IsColored ()) {
ClearColorPiece clearColor = piece2.GetComponent<ClearColorPiece> ();
if (clearColor) {
clearColor.Color = piece1.ColorComponent.Color;
}
ClearPiece (piece2.X, piece2.Y);
}
// Now we need to clear all pieces from this match
ClearAllValidMatches ();
if (piece1.Type == PieceType.ROW_CLEAR || piece1.Type == PieceType.COLUMN_CLEAR) {
ClearPiece (piece1.X, piece1.Y);
}
if (piece2.Type == PieceType.ROW_CLEAR || piece2.Type == PieceType.COLUMN_CLEAR) {
ClearPiece (piece2.X, piece2.Y);
}
pressedPiece = null;
enteredPiece = null;
// And finally refilling the board
StartCoroutine (Fill ());
// Declares a player move
level.OnMove();
} else {
// No match, return pieces to their own positions
pieces [piece1.X, piece1.Y] = piece1;
pieces [piece2.X, piece2.Y] = piece2;
}
}
}
// Assign piece when piece is pressed
public void PressPiece(GamePiece piece)
{
pressedPiece = piece;
}
// Assign piece when piece is entered
public void EnterPiece(GamePiece piece)
{
enteredPiece = piece;
}
// Swap pieces when piece is released
public void ReleasePiece()
{
if (IsAdjacent (pressedPiece, enteredPiece)) {
SwapPieces (pressedPiece, enteredPiece);
}
}
// Used to know if pieces can match
public List<GamePiece> GetMatch(GamePiece piece, int newX, int newY)
{
if (piece.IsColored ()) {
ColorPiece.ColorType color = piece.ColorComponent.Color;
List<GamePiece> horizontalPieces = new List<GamePiece> ();
List<GamePiece> verticalPieces = new List<GamePiece> ();
List<GamePiece> matchingPieces = new List<GamePiece> ();
// First check horizontal
horizontalPieces.Add(piece);
for (int dir = 0; dir <= 1; dir++) {
for (int xOffset = 1; xOffset < xDim; xOffset++) {
int x;
if (dir == 0) { // Left
x = newX - xOffset;
} else { // Right
x = newX + xOffset;
}
if (x < 0 || x >= xDim) {
break;
}
if (pieces [x, newY].IsColored () && pieces [x, newY].ColorComponent.Color == color) {
horizontalPieces.Add (pieces [x, newY]);
} else {
break;
}
}
}
if (horizontalPieces.Count >= 3) {
for (int i = 0; i < horizontalPieces.Count; i++) {
matchingPieces.Add (horizontalPieces [i]);
}
}
// Traverse vertically if we found a match (for L and T shapes)
if (horizontalPieces.Count >= 3) {
for (int i = 0; i < horizontalPieces.Count; i++) {
for (int dir = 0; dir <= 1; dir++) {
for (int yOffset = 1; yOffset < yDim; yOffset++) {
int y;
if (dir == 0) { // Up
y = newY - yOffset;
} else { // Down
y = newY + yOffset;
}
if (y < 0 || y >= yDim) {
break;
}
if (pieces [horizontalPieces [i].X, y].IsColored () && pieces [horizontalPieces [i].X, y].ColorComponent.Color == color) {
verticalPieces.Add (pieces [horizontalPieces [i].X, y]);
} else {
break;
}
}
}
if (verticalPieces.Count < 2) {
verticalPieces.Clear ();
} else {
for (int j = 0; j < verticalPieces.Count; j++) {
matchingPieces.Add (verticalPieces [j]);
}
break;
}
}
}
if (matchingPieces.Count >= 3) {
return matchingPieces;
}
// Didn't find anything going horizontally first,
// so now check vertically
horizontalPieces.Clear();
verticalPieces.Clear ();
verticalPieces.Add(piece);
for (int dir = 0; dir <= 1; dir++) {
for (int yOffset = 1; yOffset < yDim; yOffset++) {
int y;
if (dir == 0) { // Up
y = newY - yOffset;
} else { // Down
y = newY + yOffset;
}
if (y < 0 || y >= yDim) {
break;
}
if (pieces [newX, y].IsColored () && pieces [newX, y].ColorComponent.Color == color) {
verticalPieces.Add (pieces [newX, y]);
} else {
break;
}
}
}
if (verticalPieces.Count >= 3) {
for (int i = 0; i < verticalPieces.Count; i++) {
matchingPieces.Add (verticalPieces [i]);
}
}
// Traverse horizontally if we found a match (for L and T shapes)
if (verticalPieces.Count >= 3) {
for (int i = 0; i < verticalPieces.Count; i++) {
for (int dir = 0; dir <= 1; dir++) {
for (int xOffset = 1; xOffset < xDim; xOffset++) {
int x;
if (dir == 0) { // Left
x = newX - xOffset;
} else { // Right
x = newX + xOffset;
}
if (x < 0 || x >= xDim) {
break;
}
if (pieces [x, verticalPieces[i].Y].IsColored () && pieces [x, verticalPieces[i].Y].ColorComponent.Color == color) {
horizontalPieces.Add (pieces [x, verticalPieces[i].Y]);
} else {
break;
}
}
}
if (horizontalPieces.Count < 2) {
horizontalPieces.Clear ();
} else {
for (int j = 0; j < horizontalPieces.Count; j++) {
matchingPieces.Add (horizontalPieces [j]);
}
break;
}
}
}
if (matchingPieces.Count >= 3) {
return matchingPieces;
}
}
return null;
}
// Clear all matches for one player move
public bool ClearAllValidMatches()
{
bool needsRefill = false;
for (int y = 0; y < yDim; y++) {
for (int x = 0; x < xDim; x++) {
if (pieces [x, y].IsClearable ()) {
List<GamePiece> match = GetMatch (pieces [x, y], x, y);
if (match != null) {
// Start Special piece spawning
PieceType specialPieceType = PieceType.COUNT;
GamePiece randomPiece = match [Random.Range (0, match.Count)];
int specialPieceX = randomPiece.X;
int specialPieceY = randomPiece.Y;
if (match.Count == 4) {
if (pressedPiece == null || enteredPiece == null) {
specialPieceType = (PieceType)Random.Range ((int)PieceType.ROW_CLEAR, (int)PieceType.COLUMN_CLEAR);
} else if (pressedPiece.Y == enteredPiece.Y) {
specialPieceType = PieceType.ROW_CLEAR;
} else {
specialPieceType = PieceType.COLUMN_CLEAR;
}
} else if (match.Count >= 5) {
specialPieceType = PieceType.RAINBOW;
}
// End Special piece spawning
for (int i = 0; i < match.Count; i++) {
if (ClearPiece (match [i].X, match [i].Y)) {
needsRefill = true;
if (match [i] == pressedPiece || match [i] == enteredPiece) {
specialPieceX = match [i].X;
specialPieceY = match [i].Y;
}
}
}
// Spawn the special piece
if (specialPieceType != PieceType.COUNT) {
Destroy (pieces [specialPieceX, specialPieceY]);
GamePiece newPiece = SpawnNewPiece (specialPieceX, specialPieceY, specialPieceType);
if ((specialPieceType == PieceType.ROW_CLEAR || specialPieceType == PieceType.COLUMN_CLEAR)
&& newPiece.IsColored () && match [0].IsColored ()) {
newPiece.ColorComponent.SetColor(match[0].ColorComponent.Color);
} else if (specialPieceType == PieceType.RAINBOW && newPiece.IsColored ()) {
newPiece.ColorComponent.SetColor (ColorPiece.ColorType.ANY);
}
}
}
}
}
}
return needsRefill;
}
// Clear a piece and respawn an empty piece
public bool ClearPiece(int x, int y)
{
if (pieces [x, y].IsClearable () && !pieces [x, y].ClearableComponent.IsBeingCleared) {
pieces [x, y].ClearableComponent.Clear ();
SpawnNewPiece (x, y, PieceType.EMPTY);
ClearObstacles (x, y);
return true;
}
return false;
}
// Used to clear Ice pieces
public void ClearObstacles(int x, int y)
{
for (int adjacentX = x - 1; adjacentX <= x + 1; adjacentX++) {
if (adjacentX != x && adjacentX >= 0 && adjacentX < xDim) {
if (pieces [adjacentX, y].Type == PieceType.ICE && pieces [adjacentX, y].IsClearable ()) {
pieces [adjacentX, y].ClearableComponent.Clear ();
SpawnNewPiece (adjacentX, y, PieceType.EMPTY);
}
}
}
for (int adjacentY = y - 1; adjacentY <= y + 1; adjacentY++) {
if (adjacentY != y && adjacentY >= 0 && adjacentY < yDim) {
if (pieces [x, adjacentY].Type == PieceType.ICE && pieces [x, adjacentY].IsClearable ()) {
pieces [x, adjacentY].ClearableComponent.Clear ();
SpawnNewPiece (x, adjacentY, PieceType.EMPTY);
}
}
}
}
// Clear entire row
public void ClearRow(int row)
{
for (int x = 0; x < xDim; x++) {
ClearPiece (x, row);
}
}
// Clear entire column
public void ClearColumn(int column)
{
for (int y = 0; y < yDim; y++) {
ClearPiece (column, y);
}
}
// Clear all pieces with the same color
public void ClearColor(ColorPiece.ColorType color)
{
for (int x = 0; x < xDim; x++) {
for (int y = 0; y < yDim; y++) {
if (pieces [x, y].IsColored () && (pieces [x, y].ColorComponent.Color == color
|| color == ColorPiece.ColorType.ANY)) {
ClearPiece (x, y);
}
}
}
}
// Set the game over so the current level ends
public void GameOver()
{
gameOver = true;
}
// Returns a list of pieces on the grid with the given type parameter
public List<GamePiece> GetPiecesOfType(PieceType type)
{
List<GamePiece> piecesOfType = new List<GamePiece> ();
for (int x = 0; x < xDim; x++) {
for (int y = 0; y < yDim; y++) {
if (pieces [x, y].Type == type) {
piecesOfType.Add (pieces [x, y]);
}
}
}
return piecesOfType;
}
/* // Used to know if two pieces have the same color
public bool IsSameColor(int x, int y, int color)
{
if (pieces [x, y].IsColored ()) {
return (int)pieces [x, y].ColorComponent.Color == color;
} else {
return false;
}
}*/
// Used to know if two pieces have the same color
public bool IsSameColor(int x, int y, ColorPiece.ColorType color)
{
if (pieces [x, y].IsColored ()) {
return pieces [x, y].ColorComponent.Color == color;
} else {
return false;
}
}
// Used to know if two pieces have the same color
public bool IsMovableAndMatching(int x, int y)
{
return pieces [x, y].IsMovable ();
}
// Used to check all possible matches on the grid
public List<GamePiece> CheckAllPossibleMatches()
{
// We add a list of possible matches
List<GamePiece> matchingPieces = new List<GamePiece> ();
// Vertical check
for (int x = 0; x < xDim; x++) {
for (int y = 0; y < yDim - 2; y++) {
// Only if piece is colored and clearable
if (pieces [x, y].IsClearable () && pieces [x, y].IsColored ()) {
if (y < yDim - 3)
{
/*
&
*
&
&
*/
if (IsSameColor (x, y + 2, pieces [x, y].ColorComponent.Color) && IsSameColor (x, y + 3, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 1)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x, y + 2]);
matchingPieces.Add (pieces [x, y + 3]);
return matchingPieces;
}
/*
&
&
*
&
*/
if (IsSameColor (x, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x, y + 3, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 2)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x, y + 1]);
matchingPieces.Add (pieces [x, y + 3]);
return matchingPieces;
}
}
if (x > 0)
{
/*
* &
& *
& *
*/
if (IsSameColor (x - 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x - 1, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x - 1, y)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x - 1, y + 1]);
matchingPieces.Add (pieces [x - 1, y + 2]);
return matchingPieces;
}
/*
* &
* &
& *
*/
if (IsSameColor (x, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x - 1, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 2)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x, y + 1]);
matchingPieces.Add (pieces [x - 1, y + 2]);
return matchingPieces;
}
/*
* &
& *
* &
*/
if (IsSameColor (x - 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 1)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x - 1, y + 1]);
matchingPieces.Add (pieces [x, y + 2]);
return matchingPieces;
}
}
if (x < xDim - 1)
{
/*
& *
& *
* &
*/
if (IsSameColor (x, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 1, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 2)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x, y + 1]);
matchingPieces.Add (pieces [x + 1, y + 2]);
return matchingPieces;
}
/*
& *
* &
* &
*/
if (IsSameColor (x + 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 1, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 1, y)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 1, y + 1]);
matchingPieces.Add (pieces [x + 1, y + 2]);
return matchingPieces;
}
/*
& *
* &
& *
*/
if (IsSameColor (x + 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x, y + 2, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 1)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 1, y + 1]);
matchingPieces.Add (pieces [x, y + 2]);
return matchingPieces;
}
}
}
}
}
// Horizontal check
for (int y = 0; y < yDim; y++) {
for (int x = 0; x < xDim - 2; x++) {
// Only if piece is colored and clearable
if (pieces [x, y].IsClearable () && pieces [x, y].IsColored ()) {
if (x < xDim - 3)
{
/*
& * & &
*/
if (IsSameColor (x + 2, y, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 3, y, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 1, y)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 2, y]);
matchingPieces.Add (pieces [x + 3, y]);
return matchingPieces;
}
/*
& & * &
*/
if (IsSameColor (x + 1, y, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 3, y, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 2, y)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 1, y]);
matchingPieces.Add (pieces [x + 3, y]);
return matchingPieces;
}
}
if (y > 0)
{
/*
* & &
& * *
*/
if (IsSameColor (x + 1, y - 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y - 1, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y - 1)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 1, y - 1]);
matchingPieces.Add (pieces [x + 2, y - 1]);
return matchingPieces;
}
/*
* * &
& & *
*/
if (IsSameColor (x + 1, y, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y - 1, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 2, y)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 1, y]);
matchingPieces.Add (pieces [x + 2, y - 1]);
return matchingPieces;
}
/*
* & *
& * &
*/
if (IsSameColor (x + 1, y - 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 1, y)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 1, y - 1]);
matchingPieces.Add (pieces [x + 2, y]);
return matchingPieces;
}
}
if (y < yDim - 1)
{
/*
& * *
* & &
*/
if (IsSameColor (x + 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y + 1, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x, y + 1)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 1, y + 1]);
matchingPieces.Add (pieces [x + 2, y + 1]);
return matchingPieces;
}
/*
& & *
* * &
*/
if (IsSameColor (x + 1, y, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y + 1, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 2, y)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 1, y]);
matchingPieces.Add (pieces [x + 2, y + 1]);
return matchingPieces;
}
/*
& * &
* & *
*/
if (IsSameColor (x + 1, y + 1, pieces [x, y].ColorComponent.Color) && IsSameColor (x + 2, y, pieces [x, y].ColorComponent.Color) && IsMovableAndMatching(x + 1, y)) {
matchingPieces.Add (pieces [x, y]);
matchingPieces.Add (pieces [x + 1, y + 1]);
matchingPieces.Add (pieces [x + 2, y]);
return matchingPieces;
}
}
}
}
}
// No matches?
return matchingPieces;
}
// Shuffle the grid
public void Shuffle()
{
// If the game is over, just disabled this function
if (!gameOver) {
for (int x = 0; x < xDim; x++) {
for (int y = 0; y < yDim; y++) {
// We only need to shuffle movable pieces
if (pieces [x, y].IsMovable ()) {
// Todo : replace this code. We need some kind of list of colored and movable pieces and shuffle it
pieces [x, y].ColorComponent.SetColor ((ColorPiece.ColorType)Random.Range (0, 5));
}
if (ClearAllValidMatches ())
StartCoroutine (Fill ());
}
}
}
}
// Used to advertise the user with possible match
public IEnumerator advert()
{
coroutineIsRunning = true;
// Check for possible moves
List<GamePiece> matchingPieces = new List<GamePiece> ();
List<GamePiece> piecesOfType = new List<GamePiece> ();
piecesOfType = GetPiecesOfType(PieceType.RAINBOW);
// Checking for a rainbow piece
if (piecesOfType.Count == 0) {
matchingPieces = CheckAllPossibleMatches ();
if (matchingPieces.Count != 0) {
// We have a match, we can advert the player
yield return new WaitForSeconds (5);
// advert the player
pieces [matchingPieces [0].X, matchingPieces [0].Y].ClearableComponent.AdvertMatch ();
pieces [matchingPieces [1].X, matchingPieces [1].Y].ClearableComponent.AdvertMatch ();
pieces [matchingPieces [2].X, matchingPieces [2].Y].ClearableComponent.AdvertMatch ();
coroutineIsRunning = false;
} else {
// No match and no rainbows, shuffle the grid
yield return new WaitForSeconds (2);
coroutineIsRunning = false;
Shuffle ();
}
} else {
// We have rainbows so highlight them !
yield return new WaitForSeconds (5);
pieces [piecesOfType [0].X, piecesOfType [0].Y].ClearableComponent.AdvertMatch ();
coroutineIsRunning = false;
}
}
}
Voilà, j'espère que quelqu'un ici saura m'apporter son aide.