Import Test files

This commit is contained in:
2025-12-13 19:57:35 +08:00
parent 227be5bbd9
commit 8915a26407
234 changed files with 27436 additions and 0 deletions

177
Assets/Scripts/GameBoard.cs Normal file
View File

@@ -0,0 +1,177 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class GameBoard
{
#region Variables
private int height = 0;
public int Height { get { return height; } }
private int width = 0;
public int Width { get { return width; } }
private SC_Gem[,] allGems;
// public Gem[,] AllGems { get { return allGems; } }
private int score = 0;
public int Score
{
get { return score; }
set { score = value; }
}
private List<SC_Gem> currentMatches = new List<SC_Gem>();
public List<SC_Gem> CurrentMatches { get { return currentMatches; } }
#endregion
public GameBoard(int _Width, int _Height)
{
height = _Height;
width = _Width;
allGems = new SC_Gem[width, height];
}
public bool MatchesAt(Vector2Int _PositionToCheck, SC_Gem _GemToCheck)
{
if (_PositionToCheck.x > 1)
{
if (allGems[_PositionToCheck.x - 1, _PositionToCheck.y].type == _GemToCheck.type &&
allGems[_PositionToCheck.x - 2, _PositionToCheck.y].type == _GemToCheck.type)
return true;
}
if (_PositionToCheck.y > 1)
{
if (allGems[_PositionToCheck.x, _PositionToCheck.y - 1].type == _GemToCheck.type &&
allGems[_PositionToCheck.x, _PositionToCheck.y - 2].type == _GemToCheck.type)
return true;
}
return false;
}
public void SetGem(int _X, int _Y, SC_Gem _Gem)
{
allGems[_X, _Y] = _Gem;
}
public SC_Gem GetGem(int _X,int _Y)
{
return allGems[_X, _Y];
}
public void FindAllMatches()
{
currentMatches.Clear();
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
{
SC_Gem currentGem = allGems[x, y];
if (currentGem != null)
{
if (x > 0 && x < width - 1)
{
SC_Gem leftGem = allGems[x - 1, y];
SC_Gem rightGem = allGems[x + 1, y];
//checking no empty spots
if (leftGem != null && rightGem != null)
{
//Match
if (leftGem.type == currentGem.type && rightGem.type == currentGem.type)
{
currentGem.isMatch = true;
leftGem.isMatch = true;
rightGem.isMatch = true;
currentMatches.Add(currentGem);
currentMatches.Add(leftGem);
currentMatches.Add(rightGem);
}
}
}
if (y > 0 && y < height - 1)
{
SC_Gem aboveGem = allGems[x, y - 1];
SC_Gem bellowGem = allGems[x, y + 1];
//checking no empty spots
if (aboveGem != null && bellowGem != null)
{
//Match
if (aboveGem.type == currentGem.type && bellowGem.type == currentGem.type)
{
currentGem.isMatch = true;
aboveGem.isMatch = true;
bellowGem.isMatch = true;
currentMatches.Add(currentGem);
currentMatches.Add(aboveGem);
currentMatches.Add(bellowGem);
}
}
}
}
}
if (currentMatches.Count > 0)
currentMatches = currentMatches.Distinct().ToList();
CheckForBombs();
}
public void CheckForBombs()
{
for (int i = 0; i < currentMatches.Count; i++)
{
SC_Gem gem = currentMatches[i];
int x = gem.posIndex.x;
int y = gem.posIndex.y;
if (gem.posIndex.x > 0)
{
if (allGems[x - 1, y] != null && allGems[x - 1, y].type == GlobalEnums.GemType.bomb)
MarkBombArea(new Vector2Int(x - 1, y), allGems[x - 1, y].blastSize);
}
if (gem.posIndex.x + 1 < width)
{
if (allGems[x + 1, y] != null && allGems[x + 1, y].type == GlobalEnums.GemType.bomb)
MarkBombArea(new Vector2Int(x + 1, y), allGems[x + 1, y].blastSize);
}
if (gem.posIndex.y > 0)
{
if (allGems[x, y - 1] != null && allGems[x, y - 1].type == GlobalEnums.GemType.bomb)
MarkBombArea(new Vector2Int(x, y - 1), allGems[x, y - 1].blastSize);
}
if (gem.posIndex.y + 1 < height)
{
if (allGems[x, y + 1] != null && allGems[x, y + 1].type == GlobalEnums.GemType.bomb)
MarkBombArea(new Vector2Int(x, y + 1), allGems[x, y + 1].blastSize);
}
}
}
public void MarkBombArea(Vector2Int bombPos, int _BlastSize)
{
string _print = "";
for (int x = bombPos.x - _BlastSize; x <= bombPos.x + _BlastSize; x++)
{
for (int y = bombPos.y - _BlastSize; y <= bombPos.y + _BlastSize; y++)
{
if (x >= 0 && x < width && y >= 0 && y < height)
{
if (allGems[x, y] != null)
{
_print += "(" + x + "," + y + ")" + System.Environment.NewLine;
allGems[x, y].isMatch = true;
currentMatches.Add(allGems[x, y]);
}
}
}
}
currentMatches = currentMatches.Distinct().ToList();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 05610b3b492499a49bd43c2cc8260ab1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GlobalEnums : MonoBehaviour
{
public enum GemType { blue, green, red, yellow, purple, bomb };
public enum GameState { wait, move }
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e9f1d6e2be833b1469e3565a3c5290af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Scripts/Mono.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bdd6193a9a52f294496fe3b2a212e3db
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GO_Gem : MonoBehaviour {
private Rigidbody rigidBody;
private void Awake()
{
this.rigidBody = GetComponent<Rigidbody>();
}
public void Spawn() {
this.gameObject.SetActive(true);
}
public void Return() {
this.gameObject.SetActive(false);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 247ae442234d0de449a27a3ac5d46cf4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,202 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class SC_GameLogic : MonoBehaviour
{
private Dictionary<string, GameObject> unityObjects;
private int score = 0;
private float displayScore = 0;
private GameBoard gameBoard;
private GlobalEnums.GameState currentState = GlobalEnums.GameState.move;
public GlobalEnums.GameState CurrentState { get { return currentState; } }
#region MonoBehaviour
private void Awake()
{
Init();
}
private void Start()
{
StartGame();
}
private void Update()
{
displayScore = Mathf.Lerp(displayScore, gameBoard.Score, SC_GameVariables.Instance.scoreSpeed * Time.deltaTime);
unityObjects["Txt_Score"].GetComponent<TMPro.TextMeshProUGUI>().text = displayScore.ToString("0");
}
#endregion
#region Logic
private void Init()
{
unityObjects = new Dictionary<string, GameObject>();
GameObject[] _obj = GameObject.FindGameObjectsWithTag("UnityObject");
foreach (GameObject g in _obj)
unityObjects.Add(g.name,g);
gameBoard = new GameBoard(7, 7);
Setup();
}
private void Setup()
{
for (int x = 0; x < gameBoard.Width; x++)
for (int y = 0; y < gameBoard.Height; y++)
{
Vector2 _pos = new Vector2(x, y);
GameObject _bgTile = Instantiate(SC_GameVariables.Instance.bgTilePrefabs, _pos, Quaternion.identity);
_bgTile.transform.SetParent(unityObjects["GemsHolder"].transform);
_bgTile.name = "BG Tile - " + x + ", " + y;
int _gemToUse = Random.Range(0, SC_GameVariables.Instance.gems.Length);
int iterations = 0;
while (gameBoard.MatchesAt(new Vector2Int(x, y), SC_GameVariables.Instance.gems[_gemToUse]) && iterations < 100)
{
_gemToUse = Random.Range(0, SC_GameVariables.Instance.gems.Length);
iterations++;
}
SpawnGem(new Vector2Int(x, y), SC_GameVariables.Instance.gems[_gemToUse]);
}
}
public void StartGame()
{
unityObjects["Txt_Score"].GetComponent<TextMeshProUGUI>().text = score.ToString("0");
}
private void SpawnGem(Vector2Int _Position, SC_Gem _GemToSpawn)
{
if (Random.Range(0, 100f) < SC_GameVariables.Instance.bombChance)
_GemToSpawn = SC_GameVariables.Instance.bomb;
SC_Gem _gem = Instantiate(_GemToSpawn, new Vector3(_Position.x, _Position.y + SC_GameVariables.Instance.dropHeight, 0f), Quaternion.identity);
_gem.transform.SetParent(unityObjects["GemsHolder"].transform);
_gem.name = "Gem - " + _Position.x + ", " + _Position.y;
gameBoard.SetGem(_Position.x,_Position.y, _gem);
_gem.SetupGem(this,_Position);
}
public void SetGem(int _X,int _Y, SC_Gem _Gem)
{
gameBoard.SetGem(_X,_Y, _Gem);
}
public SC_Gem GetGem(int _X, int _Y)
{
return gameBoard.GetGem(_X, _Y);
}
public void SetState(GlobalEnums.GameState _CurrentState)
{
currentState = _CurrentState;
}
public void DestroyMatches()
{
for (int i = 0; i < gameBoard.CurrentMatches.Count; i++)
if (gameBoard.CurrentMatches[i] != null)
{
ScoreCheck(gameBoard.CurrentMatches[i]);
DestroyMatchedGemsAt(gameBoard.CurrentMatches[i].posIndex);
}
StartCoroutine(DecreaseRowCo());
}
private IEnumerator DecreaseRowCo()
{
yield return new WaitForSeconds(.2f);
int nullCounter = 0;
for (int x = 0; x < gameBoard.Width; x++)
{
for (int y = 0; y < gameBoard.Height; y++)
{
SC_Gem _curGem = gameBoard.GetGem(x, y);
if (_curGem == null)
{
nullCounter++;
}
else if (nullCounter > 0)
{
_curGem.posIndex.y -= nullCounter;
SetGem(x, y - nullCounter, _curGem);
SetGem(x, y, null);
}
}
nullCounter = 0;
}
StartCoroutine(FilledBoardCo());
}
public void ScoreCheck(SC_Gem gemToCheck)
{
gameBoard.Score += gemToCheck.scoreValue;
}
private void DestroyMatchedGemsAt(Vector2Int _Pos)
{
SC_Gem _curGem = gameBoard.GetGem(_Pos.x,_Pos.y);
if (_curGem != null)
{
Instantiate(_curGem.destroyEffect, new Vector2(_Pos.x, _Pos.y), Quaternion.identity);
Destroy(_curGem.gameObject);
SetGem(_Pos.x,_Pos.y, null);
}
}
private IEnumerator FilledBoardCo()
{
yield return new WaitForSeconds(0.5f);
RefillBoard();
yield return new WaitForSeconds(0.5f);
gameBoard.FindAllMatches();
if (gameBoard.CurrentMatches.Count > 0)
{
yield return new WaitForSeconds(0.5f);
DestroyMatches();
}
else
{
yield return new WaitForSeconds(0.5f);
currentState = GlobalEnums.GameState.move;
}
}
private void RefillBoard()
{
for (int x = 0; x < gameBoard.Width; x++)
{
for (int y = 0; y < gameBoard.Height; y++)
{
SC_Gem _curGem = gameBoard.GetGem(x,y);
if (_curGem == null)
{
int gemToUse = Random.Range(0, SC_GameVariables.Instance.gems.Length);
SpawnGem(new Vector2Int(x, y), SC_GameVariables.Instance.gems[gemToUse]);
}
}
}
CheckMisplacedGems();
}
private void CheckMisplacedGems()
{
List<SC_Gem> foundGems = new List<SC_Gem>();
foundGems.AddRange(FindObjectsOfType<SC_Gem>());
for (int x = 0; x < gameBoard.Width; x++)
{
for (int y = 0; y < gameBoard.Height; y++)
{
SC_Gem _curGem = gameBoard.GetGem(x, y);
if (foundGems.Contains(_curGem))
foundGems.Remove(_curGem);
}
}
foreach (SC_Gem g in foundGems)
Destroy(g.gameObject);
}
public void FindAllMatches()
{
gameBoard.FindAllMatches();
}
#endregion
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db185b18195d3814aab9ba4ac5f95047
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,37 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//This is basically just the settings, this can maybe be a ScriptableObject
public class SC_GameVariables : MonoBehaviour
{
public GameObject bgTilePrefabs;
public SC_Gem bomb;
public SC_Gem[] gems;
public float bonusAmount = 0.5f;
public float bombChance = 2f;
public int dropHeight = 0;
public float gemSpeed;
public float scoreSpeed = 5;
[HideInInspector]
public int rowsSize = 7;
[HideInInspector]
public int colsSize = 7;
#region Singleton
static SC_GameVariables instance;
public static SC_GameVariables Instance
{
get
{
if (instance == null)
instance = GameObject.Find("SC_GameVariables").GetComponent<SC_GameVariables>();
return instance;
}
}
#endregion
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3b3b891bcdf21df4ab82ea34c3afc99e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

136
Assets/Scripts/SC_Gem.cs Normal file
View File

@@ -0,0 +1,136 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//This is a SINGULAR gem
public class SC_Gem : MonoBehaviour
{
[HideInInspector]
public Vector2Int posIndex;
private Vector2 firstTouchPosition;
private Vector2 finalTouchPosition;
private bool mousePressed;
private float swipeAngle = 0;
private SC_Gem otherGem;
public GlobalEnums.GemType type;
public bool isMatch = false;
private Vector2Int previousPos;
public GameObject destroyEffect;
public int scoreValue = 10;
public int blastSize = 1;
private SC_GameLogic scGameLogic;
void Update()
{
if (Vector2.Distance(transform.position, posIndex) > 0.01f)
transform.position = Vector2.Lerp(transform.position, posIndex, SC_GameVariables.Instance.gemSpeed * Time.deltaTime);
else
{
transform.position = new Vector3(posIndex.x, posIndex.y, 0);
scGameLogic.SetGem(posIndex.x, posIndex.y, this);
}
if (mousePressed && Input.GetMouseButtonUp(0))
{
mousePressed = false;
if (scGameLogic.CurrentState == GlobalEnums.GameState.move)
{
finalTouchPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
CalculateAngle();
}
}
}
public void SetupGem(SC_GameLogic _ScGameLogic,Vector2Int _Position)
{
posIndex = _Position;
scGameLogic = _ScGameLogic;
}
//Not every gem needs this
private void OnMouseDown()
{
if (scGameLogic.CurrentState == GlobalEnums.GameState.move)
{
firstTouchPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePressed = true;
}
}
//Not every gem needs this
private void CalculateAngle()
{
swipeAngle = Mathf.Atan2(finalTouchPosition.y - firstTouchPosition.y, finalTouchPosition.x - firstTouchPosition.x);
swipeAngle = swipeAngle * 180 / Mathf.PI;
if (Vector3.Distance(firstTouchPosition, finalTouchPosition) > .5f)
MovePieces();
}
//Not every gem needs this, maybe
private void MovePieces()
{
previousPos = posIndex;
if (swipeAngle < 45 && swipeAngle > -45 && posIndex.x < SC_GameVariables.Instance.rowsSize - 1)
{
otherGem = scGameLogic.GetGem(posIndex.x + 1, posIndex.y);
otherGem.posIndex.x--;
posIndex.x++;
}
else if (swipeAngle > 45 && swipeAngle <= 135 && posIndex.y < SC_GameVariables.Instance.colsSize - 1)
{
otherGem = scGameLogic.GetGem(posIndex.x, posIndex.y + 1);
otherGem.posIndex.y--;
posIndex.y++;
}
else if (swipeAngle < -45 && swipeAngle >= -135 && posIndex.y > 0)
{
otherGem = scGameLogic.GetGem(posIndex.x, posIndex.y - 1);
otherGem.posIndex.y++;
posIndex.y--;
}
else if (swipeAngle > 135 || swipeAngle < -135 && posIndex.x > 0)
{
otherGem = scGameLogic.GetGem(posIndex.x - 1, posIndex.y);
otherGem.posIndex.x++;
posIndex.x--;
}
scGameLogic.SetGem(posIndex.x,posIndex.y, this);
scGameLogic.SetGem(otherGem.posIndex.x, otherGem.posIndex.y, otherGem);
StartCoroutine(CheckMoveCo());
}
//Why are we checking matches on the Gem itself
public IEnumerator CheckMoveCo()
{
scGameLogic.SetState(GlobalEnums.GameState.wait);
yield return new WaitForSeconds(.5f);
scGameLogic.FindAllMatches();
if (otherGem != null)
{
if (isMatch == false && otherGem.isMatch == false)
{
otherGem.posIndex = posIndex;
posIndex = previousPos;
scGameLogic.SetGem(posIndex.x, posIndex.y, this);
scGameLogic.SetGem(otherGem.posIndex.x, otherGem.posIndex.y, otherGem);
yield return new WaitForSeconds(.5f);
scGameLogic.SetState(GlobalEnums.GameState.move);
}
else
{
scGameLogic.DestroyMatches();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c5d1e13e319aa044e9776fbd351e9d03
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9a7fa3ad43383814aa2fee70fba672f3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: