using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; public class CandyCrush : MonoBehaviour { public List boxPrefabs; public int width; public int height; public Vector2 boxSpacing = new Vector2(0.1f, 0.1f); public float boxSwapDuration = 0.2f; public int minMatchesToExplode = 3; [SerializeField] private float explosionEffectDuration = 0.4f; [SerializeField] private float explosionScale = 0.5f; private GameObject[,] allBoxes; private GameObject selectedBox; void Start() { allBoxes = new GameObject[width, height]; StartCoroutine(SetupAndStartGame()); // Tahta boyutunu hesapla float boardWidth = width + (boxSpacing.x * (width - 1)); float boardHeight = height + (boxSpacing.y * (height - 1)); // Kamera ayarlarını yap float targetCameraSize = Mathf.Max(boardWidth / 2f, boardHeight / 2f) + 5f; // 0.5f eklenmiş hali float targetCameraPositionX = (boardWidth - 1) / 2f; // (Tahtanın genişliği - 1) / 2 float targetCameraPositionY = (boardHeight - 1) / 2f; // (Tahtanın yüksekliği - 1) / 2 Camera.main.transform.position = new Vector3(targetCameraPositionX, targetCameraPositionY, Camera.main.transform.position.z); Camera.main.orthographic = true; Camera.main.orthographicSize = targetCameraSize; } private IEnumerator SetupAndStartGame() { yield return StartCoroutine(SetupBoard()); yield return StartCoroutine(CheckMatchesAndRefill()); } void Update() { if (Input.GetMouseButtonDown(0)) { Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); RaycastHit2D hit = Physics2D.Raycast(mousePosition, Vector2.zero); if (hit.collider != null) { GameObject clickedBox = hit.collider.gameObject; Debug.Log("Kutuya tıklandı: " + clickedBox.name); HandleMouseClick(clickedBox); } } } public void HandleMouseClick(GameObject clickedBox) { if (selectedBox == null) { selectedBox = clickedBox; Debug.Log("Seçili kutu: " + selectedBox.name); } else { if (selectedBox == clickedBox) { // Aynı kutuya tekrar tıklandı, seçimi iptal et selectedBox = null; Debug.Log("Seçim iptal edildi."); } else if (IsAdjacent(selectedBox, clickedBox) && !IsDiagonal(selectedBox, clickedBox)) { // Farklı bir kutuya yanında olarak tıklandı, kutuları takas et StartCoroutine(TrySwapBoxes(selectedBox, clickedBox)); selectedBox = null; // İkinci kutunun seçimini kaldır } else { // Farklı bir kutuya yanında olmadan tıklandı, seçili kutuyu sıfırla Debug.Log("Seçili kutu yanında değil."); selectedBox = clickedBox; Debug.Log("Seçili kutu: " + selectedBox.name); } } } private bool IsDiagonal(GameObject box1, GameObject box2) { Vector2Int box1Index = GetArrayIndexOfBox(box1); Vector2Int box2Index = GetArrayIndexOfBox(box2); int deltaX = Mathf.Abs(box1Index.x - box2Index.x); int deltaY = Mathf.Abs(box1Index.y - box2Index.y); return deltaX == 1 && deltaY == 1; } public void SelectBox(GameObject box) { if (selectedBox == null) { selectedBox = box; // Seçili kutuyu işaretlemek için burada gerekli işlemleri yapabilirsiniz } else { if (IsAdjacent(selectedBox, box)) { StartCoroutine(TrySwapBoxes(selectedBox, box)); } selectedBox = null; // Seçili kutunun işaretini kaldırmak için burada gerekli işlemleri yapabilirsiniz } } private IEnumerator CheckMatchesAndRefill() { var matchedGroup = FindFirstMatchGroup(); if (matchedGroup != null) { yield return StartCoroutine(DestroyMatches(matchedGroup)); yield return StartCoroutine(CollapseColumns()); yield return StartCoroutine(RefillBoard()); // Eşleşmeler kontrol edildiğinde tekrar CheckMatchesAndRefill() çağrılmayacak } } private List FindFirstMatchGroup() { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { GameObject boxToCheck = allBoxes[i, j]; if (boxToCheck == null) continue; List horizontalMatches = new List { boxToCheck }; List verticalMatches = new List { boxToCheck }; for (int x = i + 1; x < width; x++) { GameObject boxToCompare = allBoxes[x, j]; if (boxToCompare != null && boxToCheck.GetComponent().sprite == boxToCompare.GetComponent().sprite) { horizontalMatches.Add(boxToCompare); } else { break; } } for (int y = j + 1; y < height; y++) { GameObject boxToCompare = allBoxes[i, y]; if (boxToCompare != null && boxToCheck.GetComponent().sprite == boxToCompare.GetComponent().sprite) { verticalMatches.Add(boxToCompare); } else { break; } } if (horizontalMatches.Count >= minMatchesToExplode) { return horizontalMatches; } if (verticalMatches.Count >= minMatchesToExplode) { return verticalMatches; } } } return null; } private bool CheckMatchesAtPosition(int x, int y) { if (x >= 0 && x < width && y >= 0 && y < height) { GameObject boxToCheck = allBoxes[x, y]; if (boxToCheck != null) { List horizontalMatches = new List { boxToCheck }; List verticalMatches = new List { boxToCheck }; // Check right for (int i = x + 1; i < width; i++) { GameObject boxToCompare = allBoxes[i, y]; if (boxToCompare != null && boxToCheck.GetComponent().sprite == boxToCompare.GetComponent().sprite) { horizontalMatches.Add(boxToCompare); } else { break; } } // Check left for (int i = x - 1; i >= 0; i--) { GameObject boxToCompare = allBoxes[i, y]; if (boxToCompare != null && boxToCheck.GetComponent().sprite == boxToCompare.GetComponent().sprite) { horizontalMatches.Add(boxToCompare); } else { break; } } // Check up for (int j = y + 1; j < height; j++) { GameObject boxToCompare = allBoxes[x, j]; if (boxToCompare != null && boxToCheck.GetComponent().sprite == boxToCompare.GetComponent().sprite) { verticalMatches.Add(boxToCompare); } else { break; } } // Check down for (int j = y - 1; j >= 0; j--) { GameObject boxToCompare = allBoxes[x, j]; if (boxToCompare != null && boxToCheck.GetComponent().sprite == boxToCompare.GetComponent().sprite) { verticalMatches.Add(boxToCompare); } else { break; } } if (horizontalMatches.Count >= minMatchesToExplode || verticalMatches.Count >= minMatchesToExplode) { return true; } } } return false; } private IEnumerator DestroyMatches(List matchGroup) { List indices = new List(); foreach (var box in matchGroup) { indices.Add(GetArrayIndexOfBox(box)); StartCoroutine(ApplyExplosionEffect(box)); } yield return new WaitForSeconds(explosionEffectDuration); foreach (var index in indices) { GameObject boxToDestroy = allBoxes[index.x, index.y]; Destroy(boxToDestroy); allBoxes[index.x, index.y] = null; } yield return new WaitForSeconds(explosionEffectDuration); // Patlatılan kutuları dikkate alarak collapse işlemini gerçekleştir yield return StartCoroutine(CollapseColumns()); yield return StartCoroutine(RefillBoard()); // Eşleşmeler ve yeniden doldurma işlemi tamamlandıktan sonra tekrar kontrol et yield return StartCoroutine(CheckMatchesAndRefill()); } private IEnumerator ApplyExplosionEffect(GameObject box) { Vector3 originalScale = box.transform.localScale; Vector3 targetScale = originalScale * explosionScale; float elapsedTime = 0f; while (elapsedTime < explosionEffectDuration) { float t = elapsedTime / explosionEffectDuration; box.transform.localScale = Vector3.Lerp(originalScale, targetScale, t); elapsedTime += Time.deltaTime; yield return null; } box.transform.localScale = Vector3.zero; } private IEnumerator SetupBoard() { for (int j = height - 1; j >= 0; j--) { for (int i = 0; i < width; i++) { Vector2 position = new Vector2(i + (boxSpacing.x * i), j + (boxSpacing.y * j)); GameObject boxToCreate = GetRandomBoxPrefab(); GameObject newBox = Instantiate(boxToCreate, position, Quaternion.identity); newBox.transform.parent = transform; newBox.name = "Box_" + i + "_" + j; allBoxes[i, j] = newBox; yield return null; } } } private IEnumerator RefillBoard() { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (allBoxes[i, j] == null) { Vector2 startPosition = new Vector2(i + (boxSpacing.x * i), height + j * boxSpacing.y); Vector2 endPosition = new Vector2(i + (boxSpacing.x * i), j + (boxSpacing.y * j)); GameObject boxToCreate = GetRandomBoxPrefab(); GameObject newBox = Instantiate(boxToCreate, startPosition, Quaternion.identity); newBox.transform.parent = transform; newBox.name = "Box_" + i + "_" + j; allBoxes[i, j] = newBox; yield return StartCoroutine(MoveBox(newBox, startPosition, endPosition, boxSwapDuration)); } } } } private GameObject GetRandomBoxPrefab() { int randomIndex = Random.Range(0, boxPrefabs.Count); return boxPrefabs[randomIndex]; } private IEnumerator MoveBox(GameObject box, Vector2 startPosition, Vector2 endPosition, float duration) { float elapsedTime = 0f; while (elapsedTime < duration) { float t = elapsedTime / duration; box.transform.position = Vector2.Lerp(startPosition, endPosition, t); elapsedTime += Time.deltaTime; yield return null; } box.transform.position = endPosition; } private IEnumerator CollapseColumns() { for (int x = 0; x < width; x++) { int emptySlot = -1; for (int y = 0; y < height; y++) { if (allBoxes[x, y] == null) { if (emptySlot == -1) { emptySlot = y; } } else { if (emptySlot != -1) { GameObject box = allBoxes[x, y]; Vector2 startPosition = box.transform.position; Vector2 endPosition = new Vector2(x + (boxSpacing.x * x), emptySlot + (boxSpacing.y * emptySlot)); allBoxes[x, emptySlot] = box; allBoxes[x, y] = null; StartCoroutine(MoveBox(box, startPosition, endPosition, boxSwapDuration)); emptySlot++; } } } } yield return new WaitForSeconds(boxSwapDuration); } private bool IsAdjacent(GameObject box1, GameObject box2) { Vector2Int box1Index = GetArrayIndexOfBox(box1); Vector2Int box2Index = GetArrayIndexOfBox(box2); int deltaX = Mathf.Abs(box1Index.x - box2Index.x); int deltaY = Mathf.Abs(box1Index.y - box2Index.y); // Sadece sağ, sol, alt veya üstünde olan kutuları kontrol et return (deltaX == 1 && deltaY == 0) || (deltaX == 0 && deltaY == 1); } private Vector2Int GetArrayIndexOfBox(GameObject box) { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (allBoxes[i, j] == box) { return new Vector2Int(i, j); } } } return new Vector2Int(-1, -1); } private IEnumerator TrySwapBoxes(GameObject box1, GameObject box2) { Vector2Int box1Index = GetArrayIndexOfBox(box1); Vector2Int box2Index = GetArrayIndexOfBox(box2); if (IsValidIndex(box1Index) && IsValidIndex(box2Index)) { if (IsAdjacent(box1, box2) && !IsDiagonal(box1, box2)) { yield return StartCoroutine(SwapBoxes(box1, box2, box1Index, box2Index)); bool matchFound = CheckMatchesAtPosition(box1Index.x, box1Index.y) || CheckMatchesAtPosition(box2Index.x, box2Index.y); if (!matchFound) { yield return StartCoroutine(SwapBoxes(box1, box2, box1Index, box2Index)); } else { yield return StartCoroutine(CheckMatchesAndRefill()); } } else { Debug.Log("Kutular çarpraz şekilde seçilemez."); } } } private IEnumerator SwapBoxes(GameObject box1, GameObject box2, Vector2Int box1Index, Vector2Int box2Index) { Vector2 box1Position = box1.transform.position; Vector2 box2Position = box2.transform.position; allBoxes[box1Index.x, box1Index.y] = box2; allBoxes[box2Index.x, box2Index.y] = box1; float elapsedTime = 0f; while (elapsedTime < boxSwapDuration) { float t = elapsedTime / boxSwapDuration; box1.transform.position = Vector2.Lerp(box1Position, box2Position, t); box2.transform.position = Vector2.Lerp(box2Position, box1Position, t); elapsedTime += Time.deltaTime; yield return null; } box1.transform.position = box2Position; box2.transform.position = box1Position; } private bool IsValidIndex(Vector2Int index) { return index.x >= 0 && index.x < width && index.y >= 0 && index.y < height; } }