180 lines
7.0 KiB
C#
180 lines
7.0 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Cysharp.Threading.Tasks;
|
|
using Enums;
|
|
using Models.Interfaces;
|
|
using ScriptableObjects;
|
|
using Services.Interfaces;
|
|
using UnityEngine;
|
|
using Utils;
|
|
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 IObjectPool<GemView> objectPool;
|
|
private Transform gemsHolder;
|
|
|
|
public GameBoardService(IGameBoard gameBoard, GameVariables gameVariables, IMatchService matchService, IScoreService scoreSerivce, IObjectPool<GemView> objectPool, Transform gemsHolder) {
|
|
this.gameBoard = gameBoard;
|
|
this.gameVariables = gameVariables;
|
|
this.matchService = matchService;
|
|
this.scoreService = scoreSerivce;
|
|
this.objectPool = objectPool;
|
|
this.gemsHolder = gemsHolder;
|
|
}
|
|
|
|
public void Setup() {
|
|
Debug.Log("Setting up the board");
|
|
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 = RandomUtils.RandomGemTypeAsInt();
|
|
|
|
int iterations = 0;
|
|
while (this.matchService.MatchesAt(new Vector2Int(x, y), (GemType)gemToUse) && iterations < 100)
|
|
{
|
|
gemToUse = RandomUtils.RandomGemTypeAsInt();
|
|
iterations++;
|
|
}
|
|
|
|
SpawnGem(new Vector2Int(x, y), this.gameVariables.gemsPrefabs[gemToUse], (GemType)gemToUse);
|
|
}
|
|
}
|
|
|
|
public void SpawnGem(Vector2Int position, GemView gemPrefab, GemType gemType) {
|
|
Debug.Log("Spawning gem at " + position + " with type " + gemType + "");
|
|
if (Random.Range(0, 100f) < this.gameVariables.bombChance)
|
|
gemPrefab = this.gameVariables.bombPrefab;
|
|
|
|
GemView gemView = this.objectPool.Get(gemType, position, this.gameVariables.dropHeight);
|
|
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 = RandomUtils.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);
|
|
if(this.gameVariables.destroyEffectPrefabs.Length > 0)
|
|
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();
|
|
}
|
|
}
|
|
} |