Implement Bombs
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Cysharp.Threading.Tasks;
|
||||
@@ -14,31 +15,38 @@ using Object = UnityEngine.Object;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace Services {
|
||||
public class GameBoardService : IGameBoardService, ITickable {
|
||||
public class GameBoardService : IGameBoardService, ITickable, IDisposable {
|
||||
#region Inject
|
||||
private readonly IGameBoard gameBoard;
|
||||
private readonly GameVariables gameVariables;
|
||||
private readonly IMatchService matchService;
|
||||
private readonly IScoreService scoreService;
|
||||
private readonly IObjectPool<GemView> objectPool;
|
||||
private readonly Transform gemsHolder;
|
||||
#endregion
|
||||
|
||||
#region Variables
|
||||
private readonly List<GemPresenter> gemPresenters = new List<GemPresenter>();
|
||||
private readonly ScorePresenter scorePresenter;
|
||||
private GameState currentState = GameState.Move;
|
||||
#endregion
|
||||
|
||||
public GameBoardService(IGameBoard gameBoard, GameVariables gameVariables, IMatchService matchService, IScoreService scoreSerivce, IObjectPool<GemView> objectPool, Transform gemsHolder) {
|
||||
public GameBoardService(IGameBoard gameBoard, GameVariables gameVariables, IMatchService matchService, IScoreService scoreSerivce, IObjectPool<GemView> objectPool, Transform gemsHolder, ScorePresenter scorePresenter) {
|
||||
this.gameBoard = gameBoard;
|
||||
this.gameVariables = gameVariables;
|
||||
this.matchService = matchService;
|
||||
this.scoreService = scoreSerivce;
|
||||
this.objectPool = objectPool;
|
||||
this.gemsHolder = gemsHolder;
|
||||
this.scorePresenter = scorePresenter;
|
||||
}
|
||||
|
||||
public void Tick() {
|
||||
int i = 0;
|
||||
foreach (GemPresenter gemPresenter in gemPresenters) {
|
||||
gemPresenter.Tick();
|
||||
i++;
|
||||
}
|
||||
|
||||
this.scorePresenter.Tick();
|
||||
}
|
||||
|
||||
//Instantiates background tiles and calls SpawnGems
|
||||
@@ -61,18 +69,20 @@ namespace Services {
|
||||
iterations++;
|
||||
}
|
||||
|
||||
SpawnGem(new Vector2Int(x, y), this.gameVariables.gemsPrefabs[gemToUse], (GemType)gemToUse);
|
||||
SpawnGem(new Vector2Int(x, y), (GemType)gemToUse);
|
||||
}
|
||||
|
||||
this.currentState = GameState.Move;
|
||||
}
|
||||
|
||||
//Uses the ObjectPool to spawn a gem at the given position
|
||||
public void SpawnGem(Vector2Int position, GemView gemPrefab, GemType gemType) {
|
||||
private void SpawnGem(Vector2Int position, GemType gemType) {
|
||||
if (Random.Range(0, 100f) < this.gameVariables.bombChance)
|
||||
gemPrefab = this.gameVariables.bombPrefab;
|
||||
gemType = GemType.Bomb;
|
||||
|
||||
GemView gemView = this.objectPool.Get(gemType, position, this.gameVariables.dropHeight);
|
||||
gemView.name = "Gem - " + position.x + ", " + position.y;
|
||||
Gem gem = new Gem(gemType, position);
|
||||
gemView.name = "Gem - " + position.x + ", " + position.y + ' ' + gemType;
|
||||
Gem gem = new Gem(gemType, position, 50);
|
||||
gemView.Bind(gem);
|
||||
|
||||
this.gemPresenters.Add(new GemPresenter(gem, gemView));
|
||||
@@ -80,17 +90,65 @@ namespace Services {
|
||||
}
|
||||
|
||||
//Sets the gem on the GameBoard
|
||||
public void SetGem(Vector2Int position, Gem gem) {
|
||||
private void SetGem(Vector2Int position, Gem gem) {
|
||||
this.gameBoard.SetGemAt(new Vector2Int(position.x, position.y), gem);
|
||||
}
|
||||
|
||||
//Gets the gem from the GameBoard
|
||||
public Gem GetGem(Vector2Int position) {
|
||||
private Gem GetGem(Vector2Int position) {
|
||||
return this.gameBoard.GetGemAt(position);
|
||||
}
|
||||
|
||||
//Listens to InputService OnSwapRequest
|
||||
public async UniTask<bool> TrySwap(Vector2Int from, Vector2Int to) {
|
||||
if (this.currentState != GameState.Move)
|
||||
return false;
|
||||
|
||||
if (!InBounds(from) || !InBounds(to))
|
||||
return false;
|
||||
|
||||
if (!AreAdjacentCardinal(from, to))
|
||||
return false;
|
||||
|
||||
Gem fromGem = GetGem(from);
|
||||
Gem toGem = GetGem(to);
|
||||
|
||||
if(fromGem == null || toGem == null)
|
||||
return false;
|
||||
|
||||
this.currentState = GameState.Wait;
|
||||
|
||||
ApplySwap(from, to, fromGem, toGem);
|
||||
|
||||
await UniTask.Delay(600);
|
||||
|
||||
this.matchService.FindAllMatches();
|
||||
bool hasMatch = this.matchService.CurrentMatches.Count > 0;
|
||||
|
||||
if (!hasMatch) {
|
||||
ApplySwap(to, from, fromGem, toGem);
|
||||
await UniTask.Delay(600);
|
||||
this.currentState = GameState.Move;
|
||||
return false;
|
||||
}
|
||||
|
||||
DestroyMatches();
|
||||
this.currentState = GameState.Move;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ApplySwap(Vector2Int posA, Vector2Int posB, Gem gemA, Gem gemB) {
|
||||
// swap their stored positions
|
||||
gemA.SetPosition(posB);
|
||||
gemB.SetPosition(posA);
|
||||
|
||||
// update grid
|
||||
SetGem(posA, gemB);
|
||||
SetGem(posB, gemA);
|
||||
}
|
||||
|
||||
//If there are matches, destroys them and moves the gems down
|
||||
public void DestroyMatches() {
|
||||
private void DestroyMatches() {
|
||||
for (int i = 0; i < this.matchService.CurrentMatches.Count; i++)
|
||||
if (this.matchService.CurrentMatches[i] != null)
|
||||
{
|
||||
@@ -101,8 +159,8 @@ namespace Services {
|
||||
MoveGemsDown();
|
||||
}
|
||||
|
||||
public async UniTask MoveGemsDown() {
|
||||
await UniTask.Delay(2);
|
||||
private async UniTask MoveGemsDown() {
|
||||
await UniTask.Delay(50);
|
||||
|
||||
int nullCounter = 0;
|
||||
for (int x = 0; x < this.gameBoard.Width; x++)
|
||||
@@ -127,7 +185,7 @@ namespace Services {
|
||||
await FillBoard();
|
||||
}
|
||||
|
||||
public async UniTask FillBoard() {
|
||||
private async UniTask FillBoard() {
|
||||
await UniTask.Delay(5);
|
||||
RefillBoard();
|
||||
await UniTask.Delay(5);
|
||||
@@ -140,11 +198,11 @@ namespace Services {
|
||||
else
|
||||
{
|
||||
await UniTask.Delay(5);
|
||||
// currentState = GameState.Move;
|
||||
this.currentState = GameState.Move;
|
||||
}
|
||||
}
|
||||
|
||||
public void RefillBoard() {
|
||||
private void RefillBoard() {
|
||||
for (int x = 0; x < this.gameBoard.Width; x++)
|
||||
{
|
||||
for (int y = 0; y < this.gameBoard.Height; y++)
|
||||
@@ -152,39 +210,13 @@ namespace Services {
|
||||
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);
|
||||
SpawnGem(new Vector2Int(x, y), (GemType)gemToUse);
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckMisplacedGems();
|
||||
}
|
||||
|
||||
//Checks if there are gems that are not in the board
|
||||
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) {
|
||||
RemovePresenterFor(g);
|
||||
|
||||
g.Unbind();
|
||||
this.objectPool.Release(g);
|
||||
}
|
||||
}
|
||||
|
||||
public void DestroyMatchedGems(Vector2Int position) {
|
||||
private void DestroyMatchedGems(Vector2Int position) {
|
||||
List<GemView> gemsViews = GemsViews();
|
||||
Gem currentGem = this.gameBoard.GetGemAt(position);
|
||||
if (currentGem != null)
|
||||
@@ -194,30 +226,38 @@ namespace Services {
|
||||
return;
|
||||
}
|
||||
|
||||
//ToDo: Destroy effect
|
||||
if(this.gameVariables.destroyEffectPrefabs.Length > 0)
|
||||
Object.Instantiate(this.gameVariables.destroyEffectPrefabs[(int)currentGem.Type], new Vector2(position.x, position.y), Quaternion.identity);
|
||||
|
||||
RemovePresenterFor(gemView);
|
||||
gemView.Unbind();
|
||||
this.objectPool.Release(gemView);
|
||||
RemovePresenterFor(gemView);
|
||||
SetGem(position, null);
|
||||
}
|
||||
}
|
||||
|
||||
#region Utils
|
||||
private void RemovePresenterFor(GemView gemView) {
|
||||
if (gemView is null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<GemPresenter> presentersToRemove = this.gemPresenters.Where(p => p.GemView == gemView).ToList();
|
||||
foreach (GemPresenter presenter in presentersToRemove) {
|
||||
this.gemPresenters.Remove(presenter);
|
||||
}
|
||||
|
||||
GemPresenter presenter = this.gemPresenters.FirstOrDefault(p => p.GemView == gemView);
|
||||
this.gemPresenters.Remove(presenter);
|
||||
}
|
||||
|
||||
private List<GemView> GemsViews() {
|
||||
return this.gemsHolder.GetComponentsInChildren<GemView>().ToList();
|
||||
}
|
||||
|
||||
private bool InBounds(Vector2Int p) {
|
||||
return p.x >= 0 && p.x < this.gameBoard.Width && p.y >= 0 && p.y < this.gameBoard.Height;
|
||||
}
|
||||
|
||||
private static bool AreAdjacentCardinal(Vector2Int a, Vector2Int b) {
|
||||
Vector2Int d = b - a;
|
||||
return (Mathf.Abs(d.x) == 1 && d.y == 0) || (Mathf.Abs(d.y) == 1 && d.x == 0);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void Dispose() {
|
||||
this.objectPool.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,31 +5,105 @@ using UnityEngine;
|
||||
namespace Services {
|
||||
public class InputService : MonoBehaviour, IInputService
|
||||
{
|
||||
public event Action<Vector2> OnPointerDown;
|
||||
public event Action<Vector2> OnPointerUp;
|
||||
public event Action<Vector2Int, Vector2Int> OnSwapRequested;
|
||||
|
||||
private bool wasDown;
|
||||
private Camera inputCamera;
|
||||
private Vector2 pointerDownScreenPos;
|
||||
private bool isPointerDown;
|
||||
|
||||
private readonly Vector2 boardOrigin = Vector2.zero;
|
||||
private readonly float minDrag = 0.35f;
|
||||
private readonly float cellSize = 1f;
|
||||
|
||||
private void Awake() {
|
||||
this.inputCamera = Camera.main;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// Mouse
|
||||
var isDown = Input.GetMouseButton(0);
|
||||
if (!wasDown && isDown)
|
||||
OnPointerDown?.Invoke(Input.mousePosition);
|
||||
if (TryGetPrimaryPointerState(out var isDown, out var screenPos))
|
||||
{
|
||||
if (!this.isPointerDown && isDown) {
|
||||
pointerDownScreenPos = screenPos;
|
||||
}
|
||||
|
||||
if (wasDown && !isDown)
|
||||
OnPointerUp?.Invoke(Input.mousePosition);
|
||||
if (this.isPointerDown && !isDown) {
|
||||
TryEmitSwap(pointerDownScreenPos, screenPos);
|
||||
}
|
||||
|
||||
wasDown = isDown;
|
||||
this.isPointerDown = isDown;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No pointer available this frame (rare). Ensure we don't get stuck.
|
||||
this.isPointerDown = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Optional: Touch (if you want both, you can merge logic more carefully)
|
||||
if (Input.touchCount <= 0) return;
|
||||
private void TryEmitSwap(Vector2 downScreen, Vector2 upScreen)
|
||||
{
|
||||
if (this.inputCamera == null) return;
|
||||
|
||||
var t = Input.GetTouch(0);
|
||||
if (t.phase == TouchPhase.Began)
|
||||
OnPointerDown?.Invoke(t.position);
|
||||
else if (t.phase == TouchPhase.Ended || t.phase == TouchPhase.Canceled)
|
||||
OnPointerUp?.Invoke(t.position);
|
||||
Vector2 downWorld = this.inputCamera.ScreenToWorldPoint(downScreen);
|
||||
Vector2 upWorld = this.inputCamera.ScreenToWorldPoint(upScreen);
|
||||
Vector2 dragWorld = upWorld - downWorld;
|
||||
|
||||
if (dragWorld.magnitude < this.minDrag)
|
||||
return;
|
||||
|
||||
Vector2Int fromCell = WorldToCell(downWorld);
|
||||
Vector2Int dir = DragToCardinalDirection(dragWorld);
|
||||
Vector2Int toCell = fromCell + dir;
|
||||
|
||||
// Adjacency is guaranteed by construction (to = from + dir).
|
||||
// Debug.Log($"Swap {fromCell} -> {toCell}");
|
||||
OnSwapRequested?.Invoke(fromCell, toCell);
|
||||
}
|
||||
|
||||
private Vector2Int WorldToCell(Vector2 worldPos)
|
||||
{
|
||||
// Convert to board-local coords first
|
||||
Vector2 local = (worldPos - this.boardOrigin) / this.cellSize;
|
||||
|
||||
// Assumes cell centers lie on integer coordinates in local space
|
||||
int x = Mathf.FloorToInt(local.x + 0.5f);
|
||||
int y = Mathf.FloorToInt(local.y + 0.5f);
|
||||
|
||||
return new Vector2Int(x, y);
|
||||
}
|
||||
|
||||
private static Vector2Int DragToCardinalDirection(Vector2 dragWorld)
|
||||
{
|
||||
if (Mathf.Abs(dragWorld.x) >= Mathf.Abs(dragWorld.y))
|
||||
return dragWorld.x >= 0 ? Vector2Int.right : Vector2Int.left;
|
||||
|
||||
return dragWorld.y >= 0 ? Vector2Int.up : Vector2Int.down;
|
||||
}
|
||||
|
||||
private static bool TryGetPrimaryPointerState(out bool isDown, out Vector2 screenPosition)
|
||||
{
|
||||
// Prefer touch when present (mobile)
|
||||
if (Input.touchCount > 0)
|
||||
{
|
||||
Touch touch = Input.GetTouch(0);
|
||||
screenPosition = touch.position;
|
||||
|
||||
// Treat "Moved/Stationary" as still down, and "Began" as down.
|
||||
isDown = touch.phase == TouchPhase.Began
|
||||
|| touch.phase == TouchPhase.Moved
|
||||
|| touch.phase == TouchPhase.Stationary;
|
||||
|
||||
// Ended/Canceled => not down (we still report position)
|
||||
if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
|
||||
isDown = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fallback to mouse (editor/desktop)
|
||||
screenPosition = Input.mousePosition;
|
||||
isDown = Input.GetMouseButton(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,7 @@ 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);
|
||||
|
||||
UniTask<bool> TrySwap(Vector2Int from, Vector2Int to);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using UnityEngine;
|
||||
|
||||
namespace Services.Interfaces {
|
||||
public interface IInputService {
|
||||
event Action<Vector2> OnPointerDown;
|
||||
event Action<Vector2> OnPointerUp;
|
||||
event Action<Vector2Int, Vector2Int> OnSwapRequested;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ namespace Services.Interfaces {
|
||||
List<Gem> CurrentMatches { get; }
|
||||
bool MatchesAt(Vector2Int positionToCheck, GemType gemTypeToCheck);
|
||||
void FindAllMatches();
|
||||
void CheckForBombs();
|
||||
void MarkBombArea(Vector2Int bombPosition, int blastSize);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Services.Interfaces {
|
||||
public interface IScoreService {
|
||||
event Action<int> OnScoreChanged;
|
||||
int Score { get; }
|
||||
void ScoreCheck(int value);
|
||||
}
|
||||
}
|
||||
@@ -9,16 +9,23 @@ namespace Services
|
||||
{
|
||||
private readonly IObjectPool<GemView> gemViewPool;
|
||||
private readonly IGameBoardService gameBoardService;
|
||||
|
||||
public LevelEntryPoint(IObjectPool<GemView> gemViewPool, IGameBoardService gameBoardService)
|
||||
private readonly IInputService inputService;
|
||||
|
||||
public LevelEntryPoint(IObjectPool<GemView> gemViewPool, IGameBoardService gameBoardService, IInputService inputService)
|
||||
{
|
||||
this.gemViewPool = gemViewPool;
|
||||
this.gameBoardService = gameBoardService;
|
||||
this.inputService = inputService;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
this.gameBoardService.Setup();
|
||||
this.inputService.OnSwapRequested += HandleSwapRequest;
|
||||
}
|
||||
|
||||
private void HandleSwapRequest(Vector2Int from, Vector2Int to) {
|
||||
this.gameBoardService.TrySwap(from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,12 +89,61 @@ namespace Services {
|
||||
CheckForBombs();
|
||||
}
|
||||
|
||||
public void CheckForBombs() {
|
||||
throw new System.NotImplementedException();
|
||||
private void CheckForBombs() {
|
||||
Gem[,] gems = this.gameBoard.GemsGrid;
|
||||
int width = this.gameBoard.Width;
|
||||
int height = this.gameBoard.Height;
|
||||
|
||||
for (int i = 0; i < this.currentMatches.Count; i++)
|
||||
{
|
||||
Gem gem = this.currentMatches[i];
|
||||
int x = gem.Position.x;
|
||||
int y = gem.Position.y;
|
||||
|
||||
Vector2Int[] directions =
|
||||
{
|
||||
Vector2Int.left,
|
||||
Vector2Int.right,
|
||||
Vector2Int.down,
|
||||
Vector2Int.up
|
||||
};
|
||||
|
||||
foreach (Vector2Int direction in directions)
|
||||
{
|
||||
int newX = x + direction.x;
|
||||
int newY = y + direction.y;
|
||||
|
||||
if (newX < 0 || newX >= width || newY < 0 || newY >= height)
|
||||
continue;
|
||||
|
||||
Gem neighbor = gems[newX, newY];
|
||||
if (neighbor?.Type == GemType.Bomb)
|
||||
MarkBombArea(new Vector2Int(newX, newY), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void MarkBombArea(Vector2Int bombPosition, int blastSize) {
|
||||
throw new System.NotImplementedException();
|
||||
Gem[,] gems = this.gameBoard.GemsGrid;
|
||||
int width = this.gameBoard.Width;
|
||||
int height = this.gameBoard.Height;
|
||||
|
||||
for (int x = bombPosition.x - blastSize; x <= bombPosition.x + blastSize; x++)
|
||||
{
|
||||
for (int y = bombPosition.y - blastSize; y <= bombPosition.y + blastSize; y++)
|
||||
{
|
||||
if (x >= 0 && x < width && y >= 0 && y < height)
|
||||
{
|
||||
if (gems[x, y] != null)
|
||||
{
|
||||
gems[x, y].isMatch = true;
|
||||
this.currentMatches.Add(gems[x, y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.currentMatches = this.currentMatches.Distinct().ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using Enums;
|
||||
using Services.Interfaces;
|
||||
using Structs;
|
||||
using UnityEngine;
|
||||
using Utils;
|
||||
using Views;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Services {
|
||||
public class ObjectPoolService:IObjectPool<GemView> {
|
||||
private readonly GemView[] prefabs;
|
||||
private readonly GemTypeValues[] gemValues;
|
||||
private readonly Transform parent;
|
||||
|
||||
private readonly Stack<GemView> pool = new Stack<GemView>();
|
||||
private readonly Dictionary<GemType, Stack<GemView>> gemTypeToPools = new Dictionary<GemType, Stack<GemView>>();
|
||||
|
||||
public ObjectPoolService(GemView[] prefabs, Transform parent) {
|
||||
this.prefabs = prefabs;
|
||||
public ObjectPoolService(GemTypeValues[] gemValues, Transform parent) {
|
||||
this.gemValues = gemValues;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public GemView Get(GemType type, Vector2Int position, float dropHeight) {
|
||||
int typeAsInt = (int) type;
|
||||
if (!this.gemTypeToPools.ContainsKey(type)) {
|
||||
this.gemTypeToPools.Add(type, new Stack<GemView>());
|
||||
}
|
||||
|
||||
GemView gemView;
|
||||
float randomOffset = Random.Range(1f, 2.5f);
|
||||
Vector2 vector2Position = new Vector2(position.x, position.y + dropHeight * randomOffset);
|
||||
if (this.pool.Count > 0) {
|
||||
gemView = this.pool.Pop();
|
||||
if (this.gemTypeToPools[type].Count > 0) {
|
||||
gemView = this.gemTypeToPools[type].Pop();
|
||||
|
||||
|
||||
gemView.transform.localPosition = vector2Position;
|
||||
return gemView;
|
||||
}
|
||||
|
||||
gemView = Object.Instantiate(this.prefabs[typeAsInt], vector2Position, Quaternion.identity, this.parent);
|
||||
gemView = Object.Instantiate(GemUtils.GetGemValues(type, this.gemValues).gemPrefab, vector2Position, Quaternion.identity, this.parent);
|
||||
return gemView;
|
||||
}
|
||||
|
||||
public void Release(GemView gemView) {
|
||||
if (gemView == null)
|
||||
if (gemView is null)
|
||||
return;
|
||||
|
||||
Object.Instantiate(GemUtils.GetGemValues(gemView.Gem.Type, this.gemValues).explosionPrefab, gemView.transform.position, Quaternion.identity, this.parent);
|
||||
|
||||
if (!this.gemTypeToPools.ContainsKey(gemView.Gem.Type)) {
|
||||
this.gemTypeToPools.Add(gemView.Gem.Type, new Stack<GemView>());
|
||||
}
|
||||
|
||||
gemView.gameObject.SetActive(false);
|
||||
this.pool.Push(gemView);
|
||||
this.gemTypeToPools[gemView.Gem.Type].Push(gemView);
|
||||
gemView.Unbind();
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
this.pool.Clear();
|
||||
foreach (Stack<GemView> pool in this.gemTypeToPools.Values) {
|
||||
pool.Clear();
|
||||
}
|
||||
|
||||
this.gemTypeToPools.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
using System;
|
||||
using Services.Interfaces;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Services {
|
||||
public class ScoreService : IScoreService {
|
||||
private int score = 0;
|
||||
public int Score => this.score;
|
||||
public event Action<int> OnScoreChanged;
|
||||
public void ScoreCheck(int value) {
|
||||
this.score += value;
|
||||
|
||||
OnScoreChanged?.Invoke(this.score);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user