Create All Needed Scripts
This commit is contained in:
188
Assets/Scripts/Services/GameBoardService.cs
Normal file
188
Assets/Scripts/Services/GameBoardService.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Enums;
|
||||
using Models.Interfaces;
|
||||
using ScriptableObjects;
|
||||
using Services.Interfaces;
|
||||
using UnityEngine;
|
||||
using Views;
|
||||
using Object = UnityEngine.Object;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Services {
|
||||
public class GameBoardService : IGameBoardService {
|
||||
private IGameBoard gameBoard;
|
||||
private GameVariables gameVariables;
|
||||
private IMatchService matchService;
|
||||
private IScoreService scoreService;
|
||||
private Transform gemsHolder;
|
||||
|
||||
public GameBoardService(IGameBoard gameBoard, GameVariables gameVariables, IMatchService matchService, IScoreService scoreSerivce, Transform gemsHolder) {
|
||||
this.gameBoard = gameBoard;
|
||||
this.gameVariables = gameVariables;
|
||||
this.matchService = matchService;
|
||||
this.scoreService = scoreSerivce;
|
||||
this.gemsHolder = gemsHolder;
|
||||
}
|
||||
|
||||
private int RandomGemTypeAsInt() {
|
||||
GemType[] spawnableGems = Enum.GetValues(typeof(GemType))
|
||||
.Cast<GemType>()
|
||||
.Where(gType => gType != GemType.Bomb)
|
||||
.ToArray();
|
||||
|
||||
return Random.Range(0, spawnableGems.Length);
|
||||
}
|
||||
|
||||
public void Setup() {
|
||||
for (int x = 0; x < this.gameBoard.Width; x++)
|
||||
for (int y = 0; y < this.gameBoard.Height; y++)
|
||||
{
|
||||
Vector2 position = new Vector2(x, y);
|
||||
GameObject backgroundTile = Object.Instantiate(this.gameVariables.bgTilePrefabs, position, Quaternion.identity);
|
||||
backgroundTile.transform.SetParent(this.gemsHolder);
|
||||
backgroundTile.name = "BG Tile - " + x + ", " + y;
|
||||
|
||||
|
||||
|
||||
int gemToUse = RandomGemTypeAsInt();
|
||||
|
||||
int iterations = 0;
|
||||
while (this.matchService.MatchesAt(new Vector2Int(x, y), (GemType)gemToUse) && iterations < 100)
|
||||
{
|
||||
gemToUse = RandomGemTypeAsInt();
|
||||
iterations++;
|
||||
}
|
||||
|
||||
//ToDo: change gameVariables.gemsPrefabs[gemToUse] since gemToUse is index, if the order changes it wont work
|
||||
SpawnGem(new Vector2Int(x, y), this.gameVariables.gemsPrefabs[gemToUse], (GemType)gemToUse);
|
||||
}
|
||||
}
|
||||
|
||||
public void SpawnGem(Vector2Int position, GemView gemPrefab, GemType gemType) {
|
||||
if (Random.Range(0, 100f) < this.gameVariables.bombChance)
|
||||
gemPrefab = this.gameVariables.bombPrefab;
|
||||
|
||||
GemView gemView = Object.Instantiate(gemPrefab, new Vector3(position.x, position.y + this.gameVariables.dropHeight, 0f), Quaternion.identity);
|
||||
gemView.transform.SetParent(this.gemsHolder);
|
||||
gemView.name = "Gem - " + position.x + ", " + position.y;
|
||||
SetGem(new Vector2Int(position.x,position.y), new Gem(gemType, position));
|
||||
}
|
||||
|
||||
public void SetGem(Vector2Int position, Gem gem) {
|
||||
this.gameBoard.SetGemAt(new Vector2Int(position.x, position.y), gem);
|
||||
}
|
||||
|
||||
public Gem GetGem(Vector2Int position) {
|
||||
return this.gameBoard.GetGemAt(position);
|
||||
}
|
||||
|
||||
public void DestroyMatches() {
|
||||
for (int i = 0; i < this.matchService.CurrentMatches.Count; i++)
|
||||
if (this.matchService.CurrentMatches[i] != null)
|
||||
{
|
||||
this.scoreService.ScoreCheck(this.matchService.CurrentMatches[i].ScoreValue);
|
||||
DestroyMatchedGems(this.matchService.CurrentMatches[i].Position);
|
||||
}
|
||||
|
||||
MoveGemsDown();
|
||||
}
|
||||
|
||||
public async UniTask MoveGemsDown() {
|
||||
await UniTask.Delay(2);
|
||||
// why the delay though?
|
||||
// yield return new WaitForSeconds(.2f);
|
||||
|
||||
int nullCounter = 0;
|
||||
for (int x = 0; x < this.gameBoard.Width; x++)
|
||||
{
|
||||
for (int y = 0; y < this.gameBoard.Height; y++)
|
||||
{
|
||||
Gem currentGem = this.gameBoard.GetGemAt(new Vector2Int(x, y));
|
||||
if (currentGem == null)
|
||||
{
|
||||
nullCounter++;
|
||||
}
|
||||
else if (nullCounter > 0)
|
||||
{
|
||||
currentGem.SetPosition(new Vector2Int(currentGem.Position.x, currentGem.Position.y - nullCounter));
|
||||
SetGem(currentGem.Position, currentGem);
|
||||
SetGem(new Vector2Int(x,y), null);
|
||||
}
|
||||
}
|
||||
nullCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public async UniTask FillBoard() {
|
||||
await UniTask.Delay(5);
|
||||
RefillBoard();
|
||||
await UniTask.Delay(5);
|
||||
this.matchService.FindAllMatches();
|
||||
if (this.matchService.CurrentMatches.Count > 0)
|
||||
{
|
||||
await UniTask.Delay(5);
|
||||
DestroyMatches();
|
||||
}
|
||||
else
|
||||
{
|
||||
await UniTask.Delay(5);
|
||||
// currentState = GameState.Move;
|
||||
}
|
||||
}
|
||||
|
||||
public void RefillBoard() {
|
||||
for (int x = 0; x < this.gameBoard.Width; x++)
|
||||
{
|
||||
for (int y = 0; y < this.gameBoard.Height; y++)
|
||||
{
|
||||
Gem currentGem = this.gameBoard.GetGemAt(new Vector2Int(x,y));
|
||||
if (currentGem == null) {
|
||||
int gemToUse = RandomGemTypeAsInt();
|
||||
SpawnGem(new Vector2Int(x, y), this.gameVariables.gemsPrefabs[gemToUse], (GemType)gemToUse);
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckMisplacedGems();
|
||||
}
|
||||
|
||||
public void CheckMisplacedGems() {
|
||||
List<GemView> gemsViews = GemsViews();
|
||||
|
||||
for (int x = 0; x < this.gameBoard.Width; x++)
|
||||
{
|
||||
for (int y = 0; y < this.gameBoard.Height; y++)
|
||||
{
|
||||
Gem currentGem = this.gameBoard.GetGemAt(new Vector2Int(x,y));
|
||||
GemView gemView = gemsViews.FirstOrDefault(gv => gv.Gem == currentGem);
|
||||
|
||||
if (gemView != null) {
|
||||
gemsViews.Remove(gemView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (GemView g in gemsViews)
|
||||
Object.Destroy(g.gameObject);
|
||||
}
|
||||
|
||||
public void DestroyMatchedGems(Vector2Int position) {
|
||||
List<GemView> gemsViews = GemsViews();
|
||||
Gem currentGem = this.gameBoard.GetGemAt(position);
|
||||
if (currentGem != null)
|
||||
{
|
||||
GemView gemView = gemsViews.FirstOrDefault(gv => gv.Gem == currentGem);
|
||||
Object.Instantiate(this.gameVariables.destroyEffectPrefabs[(int)currentGem.Type], new Vector2(position.x, position.y), Quaternion.identity);
|
||||
|
||||
Object.Destroy(gemView!.gameObject);
|
||||
SetGem(position, null);
|
||||
}
|
||||
}
|
||||
|
||||
private List<GemView> GemsViews() {
|
||||
return this.gemsHolder.GetComponentsInChildren<GemView>().ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Services/GameBoardService.cs.meta
Normal file
3
Assets/Scripts/Services/GameBoardService.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e52d701a54645898c36c3f407ac890f
|
||||
timeCreated: 1765664126
|
||||
19
Assets/Scripts/Services/Interfaces/IGameBoardService.cs
Normal file
19
Assets/Scripts/Services/Interfaces/IGameBoardService.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Enums;
|
||||
using UnityEngine;
|
||||
using Views;
|
||||
|
||||
namespace Services.Interfaces {
|
||||
public interface IGameBoardService {
|
||||
void Setup();
|
||||
void SpawnGem(Vector2Int position, GemView gemPrefab, GemType gemType);
|
||||
void SetGem(Vector2Int position, Gem gem);
|
||||
Gem GetGem(Vector2Int position);
|
||||
void DestroyMatches();
|
||||
UniTask MoveGemsDown();
|
||||
UniTask FillBoard();
|
||||
void RefillBoard();
|
||||
void CheckMisplacedGems();
|
||||
void DestroyMatchedGems(Vector2Int position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c63053069b7e4791a82ee7dd04eae86c
|
||||
timeCreated: 1765662196
|
||||
9
Assets/Scripts/Services/Interfaces/IInputService.cs
Normal file
9
Assets/Scripts/Services/Interfaces/IInputService.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Services.Interfaces {
|
||||
public interface IInputService {
|
||||
event Action<Vector2> OnPointerDown;
|
||||
event Action<Vector2> OnPointerUp;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Services/Interfaces/IInputService.cs.meta
Normal file
3
Assets/Scripts/Services/Interfaces/IInputService.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73b706bb5eea4fdf9b1f4563aef578cd
|
||||
timeCreated: 1765632542
|
||||
13
Assets/Scripts/Services/Interfaces/IMatchService.cs
Normal file
13
Assets/Scripts/Services/Interfaces/IMatchService.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Enums;
|
||||
|
||||
namespace Services.Interfaces {
|
||||
public interface IMatchService {
|
||||
List<Gem> CurrentMatches { get; }
|
||||
bool MatchesAt(Vector2Int positionToCheck, GemType gemTypeToCheck);
|
||||
void FindAllMatches();
|
||||
void CheckForBombs();
|
||||
void MarkBombArea(Vector2Int bombPosition, int blastSize);
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Services/Interfaces/IMatchService.cs.meta
Normal file
3
Assets/Scripts/Services/Interfaces/IMatchService.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 513ff6c9b21549f088abcb4c83143771
|
||||
timeCreated: 1765656570
|
||||
5
Assets/Scripts/Services/Interfaces/IScoreService.cs
Normal file
5
Assets/Scripts/Services/Interfaces/IScoreService.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
namespace Services.Interfaces {
|
||||
public interface IScoreService {
|
||||
void ScoreCheck(int value);
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Services/Interfaces/IScoreService.cs.meta
Normal file
3
Assets/Scripts/Services/Interfaces/IScoreService.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d61c21960f14353b3f431434d3b4de2
|
||||
timeCreated: 1765674663
|
||||
99
Assets/Scripts/Services/MatchService.cs
Normal file
99
Assets/Scripts/Services/MatchService.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Enums;
|
||||
using Services.Interfaces;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Services {
|
||||
public class MatchService : IMatchService {
|
||||
private List<Gem> currentMatches = new List<Gem>();
|
||||
public List<Gem> CurrentMatches => this.currentMatches;
|
||||
|
||||
private GameBoard gameBoard;
|
||||
|
||||
public MatchService(GameBoard gameBoard) {
|
||||
this.gameBoard = gameBoard;
|
||||
}
|
||||
|
||||
public bool MatchesAt(Vector2Int positionToCheck, GemType gemTypeToCheck) {
|
||||
Gem[,] gems = this.gameBoard.GemsGrid;
|
||||
if (positionToCheck.x > 1)
|
||||
{
|
||||
if (gems[positionToCheck.x - 1, positionToCheck.y].Type == gemTypeToCheck && gems[positionToCheck.x - 2, positionToCheck.y].Type == gemTypeToCheck)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (positionToCheck.y > 1)
|
||||
{
|
||||
if (gems[positionToCheck.x, positionToCheck.y - 1].Type == gemTypeToCheck && gems[positionToCheck.x, positionToCheck.y - 2].Type == gemTypeToCheck)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void FindAllMatches() {
|
||||
this.currentMatches.Clear();
|
||||
|
||||
for (int x = 0; x < this.gameBoard.Width; x++)
|
||||
for (int y = 0; y < this.gameBoard.Height; y++)
|
||||
{
|
||||
Gem currentGem = this.gameBoard.GemsGrid[x, y];
|
||||
if (currentGem != null)
|
||||
{
|
||||
if (x > 0 && x < this.gameBoard.Width - 1)
|
||||
{
|
||||
Gem leftGem = this.gameBoard.GemsGrid[x - 1, y];
|
||||
Gem rightGem = this.gameBoard.GemsGrid[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;
|
||||
this.currentMatches.Add(currentGem);
|
||||
this.currentMatches.Add(leftGem);
|
||||
this.currentMatches.Add(rightGem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (y > 0 && y < this.gameBoard.Height - 1)
|
||||
{
|
||||
Gem aboveGem = this.gameBoard.GemsGrid[x, y - 1];
|
||||
Gem bellowGem = this.gameBoard.GemsGrid[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;
|
||||
this.currentMatches.Add(currentGem);
|
||||
this.currentMatches.Add(aboveGem);
|
||||
this.currentMatches.Add(bellowGem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.currentMatches.Count > 0) this.currentMatches = this.currentMatches.Distinct().ToList();
|
||||
|
||||
CheckForBombs();
|
||||
}
|
||||
|
||||
public void CheckForBombs() {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void MarkBombArea(Vector2Int bombPosition, int blastSize) {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Services/MatchService.cs.meta
Normal file
3
Assets/Scripts/Services/MatchService.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0fca077f5e14456ab09ae9ea6bca7c61
|
||||
timeCreated: 1765665318
|
||||
@@ -2,22 +2,23 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Services.Interfaces;
|
||||
using UnityEngine;
|
||||
using Views;
|
||||
|
||||
namespace Services {
|
||||
public class ObjectPoolService:IObjectPool<GameObject> {
|
||||
private readonly GameObject prefab;
|
||||
public class ObjectPoolService:IObjectPool<GemView> {
|
||||
private readonly GemView prefab;
|
||||
private readonly Transform parent;
|
||||
private readonly int size;
|
||||
|
||||
private readonly Stack<GameObject> pool = new Stack<GameObject>();
|
||||
private readonly Stack<GemView> pool = new Stack<GemView>();
|
||||
|
||||
public ObjectPoolService(GameObject prefab, Transform parent, int size = 5) {
|
||||
public ObjectPoolService(GemView prefab, Transform parent, int size = 5) {
|
||||
this.prefab = prefab;
|
||||
this.parent = parent;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public GameObject Get() {
|
||||
public GemView Get() {
|
||||
return this.pool.Count == 0 ? Object.Instantiate(this.prefab, this.parent) : this.pool.Pop();
|
||||
}
|
||||
|
||||
@@ -27,7 +28,7 @@ namespace Services {
|
||||
}
|
||||
}
|
||||
|
||||
public void Release(GameObject gameObject) {
|
||||
public void Release(GemView gameObject) {
|
||||
this.pool.Push(gameObject);
|
||||
}
|
||||
|
||||
|
||||
11
Assets/Scripts/Services/ScoreService.cs
Normal file
11
Assets/Scripts/Services/ScoreService.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using Services.Interfaces;
|
||||
|
||||
namespace Services {
|
||||
public class ScoreService : IScoreService {
|
||||
private int score = 0;
|
||||
public void ScoreCheck(int value) {
|
||||
this.score += value;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Services/ScoreService.cs.meta
Normal file
3
Assets/Scripts/Services/ScoreService.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5bac284955046708f571939e29d9dff
|
||||
timeCreated: 1765674722
|
||||
Reference in New Issue
Block a user