Get the full commented source code of

HTML5 Suika Watermelon Game

Talking about SameGame game, C#, Game development and Unity3D.

If you are enjoying my tutorial series about SameGame game, I am sure you will appreciate this new step, featuring the Unity prototype I blogged about last week with animations and commented code, which I strongly recommend you to compare with the same prototype made with Phaser, this will allow you to learn two languages at the price of one. First, look at the game:
You know how to play, just look at the animations. This is the commented code I want you to compare with the code of the HTML5 game you can find in this post. They are very similar in my opinion, and although Unity does not natively support tweens, with LeanTween you can use tweens pretty much the same way you are used to do with Phaser.
using UnityEngine; using System.Collections; using System.Collections.Generic; public class Script : MonoBehaviour { // the tile itself public GameObject tileObject; // array with game colors private Color[] colors = new Color[4]; // howw many rows? private int numRows = 8; // how many columns? private int numCols = 8; // two dimensional array which will contain the game table private GameObject[,] tilesArray = new GameObject[8, 8]; // this List (basically an array with a twist) will be used to store flood fill results. private List filled; // tilesToMove is used to see how many tiles we have to move with LeanTween private int tilesToMove = 0; // can the player pick a tile? private bool canPick = true; void Start () { // defining colors to be used as tile tint colors [0] = new Color(1f, 0f, 0f, 1f); colors [1] = new Color(0f, 1f, 0f, 1f); colors [2] = new Color(0f, 0f, 1f, 1f); colors [3] = new Color(1f, 1f, 0f, 1f); // looping through the whole table for (int i = 0; i < numRows; i++) { for (int j = 0; j < numCols; j++){ // function to create a tile createTile (i, j); } } } // this function is executed at each frame void Update () { // if the player clicked/touched AND can pick a tile... if (Input.GetButtonDown ("Fire1") && canPick) { // getting mouse position Vector2 firePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); // each tile has a collider to determine if mouse position overlaps Collider2D hitCollider = Physics2D.OverlapPoint(firePosition); // if there is a collider, that is if we clicked a tile... if (hitCollider) { // filled List is set to empty list filled = new List (); // running flood fill algorithm floodFill (hitCollider.GetComponent ().coordinate, hitCollider.GetComponent ().value); // if there are more than one tile in the flood fill result… if (filled.Count > 1) { // player can’t pick anymore at the moment canPick = false; // looping through filled List for (int i = 0; i < filled.Count; i++) { // destroying the game object Destroy (tilesArray [(int)filled [i].y, (int)filled [i].x]); // setting list entry to null tilesArray [(int)filled [i].y, (int)filled [i].x] = null; } // fill vertical holes, if any fillVerticalHoles (); } } } } void createTile(int row, int col){ // creation of a new tileObject instance GameObject tile = Instantiate(tileObject); // determining vertical position float yPos = 3.5f - 1f * row; // determining horizontal position float xPos = -3.5f + 1f * col; // placing the tile at the proper position tile.transform.position = new Vector2 (xPos, yPos); // choosing a random color int tileColor = Random.Range (0, colors.Length); // setting value property with the chosen color tile.GetComponent ().value = tileColor; // saving coordinate property tile.GetComponent ().coordinate = new Vector2 (col, row); // applying the tint color to the tile tile.GetComponent ().material.color = colors [tileColor]; // adding the tile to tilesArray array tilesArray [row,col] = tile; } // function to fill holes by making tiles fall down void fillVerticalHoles(){ for (int i = numRows – 2; i >= 0; i–) { for (int j = 0; j < numCols; j++) { if (tilesArray [i, j] != null) { int holesBelow = 0; for (int z = i + 1; z < numRows; z++) { if (tilesArray [z, j] == null) { holesBelow++; } } if (holesBelow>0) { tilesToMove ++; moveTile (i, j, i + holesBelow, j); } } } } if(tilesToMove==0){ fillHorizontalHoles(); } } // function to fill holes horizontally, that is to move columns to the left to replace missing columns void fillHorizontalHoles(){ for (int i = 0; i < numCols - 1; i++) { if (tilesInColumn (i) == 0) { for (int j = i + 1; j < numCols; j++) { if (tilesInColumn (j) != 0) { for (int z = 0; z < numRows; z++) { if (tilesArray [z, j] != null) { tilesToMove ++; moveTile (z, j, z, i); } } break; } } } } if(tilesToMove==0){ canPick = true; } } // function to move a tile, this is where LeanTween comes into play void moveTile(int fromRow, int fromCol, int toRow, int toCol){ tilesArray [toRow, toCol] = tilesArray [fromRow, fromCol]; tilesArray [toRow, toCol].GetComponent ().coordinate = new Vector2 (toCol, toRow); // vertical tween if(fromRow != toRow){ LeanTween.moveY (tilesArray [toRow, toCol], 3.5f – 1f * toRow, 0.5f).setOnComplete(completeYMovement); } // horizontal tween else{ LeanTween.moveX (tilesArray [toRow, toCol], -3.5f + 1f * toCol, 0.5f).setEase(LeanTweenType.easeOutBounce).setOnComplete(completeXMovement); } tilesArray [fromRow, fromCol] = null; } // this function is executed each time a vertical tween is completed. // we decrease tilesToMove and once it reaches zero (no more tiles to move) // we call fillHorizontalHoles function to move tiles horizontally, if we have to. void completeYMovement(){ tilesToMove –; if(tilesToMove == 0){ fillHorizontalHoles (); } } // this function is executed each time an horizontal tween is completed. // we decrease tilesToMove and once it reaches zero (no more tiles to move) // we set canPick to true so the player can pick again void completeXMovement(){ tilesToMove –; if(tilesToMove == 0){ canPick = true; } } // function to count how many tiles we have in a column, simply counting values different than “null” int tilesInColumn(int col){ int result = 0; for (int i = 0; i < numRows; i++) { if (tilesArray [i, col] != null) { result++; } } return result; } // flood fill function, for more information // http://emanueleferonato.com/2008/06/06/flash-flood-fill-implementation/ void floodFill(Vector2 p, int n){ if (p.x < 0 || p.y < 0 || p.x > numCols – 1 || p.y > numRows – 1) { return; } if (tilesArray [(int)p.y, (int)p.x] != null && tilesArray [(int)p.y, (int)p.x].GetComponent ().value == n && !filled.Contains(p)) { filled.Add (p); floodFill (new Vector2 (p.x + 1, p.y),n); floodFill (new Vector2 (p.x – 1, p.y),n); floodFill (new Vector2 (p.x, p.y + 1),n); floodFill (new Vector2 (p.x, p.y – 1),n); } } }
You can also download the entire project and play with it.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.