Unity_2lab/2/Assets/Scripts/CardCollector.cs
2025-10-10 04:09:01 +03:00

161 lines
6.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class CardCollector : MonoBehaviour
{
[Header("Game Setup")]
public Card cardPrefab; // Prefab with the Card.cs script attached
public Sprite cardBackSprite; // The default sprite for the back of all cards
public int rows = 4; // Number of rows for the grid
public int columns = 4; // Number of columns for the grid
[Header("Layout Settings")]
public float horizontalSpacing = 1.5f; // Расстояние между картами по горизонтали
public float verticalSpacing = 1.5f; // Расстояние между картами по вертикали
public float closeDelay = 1.0f; // Задержка перед закрытием несовпадающих карт (1 секунда)
public float cardScale = 1.0f; // НОВЫЙ ПАРАМЕТР: Масштаб (размер) всех карт
[Header("Card Sprites (Specify Pairs)")]
// Список фронтальных спрайтов. Указывайте их парами: SpriteA, SpriteB, SpriteC, SpriteD, ...
public List<Sprite> frontSprites;
private int _totalCards;
private List<(Sprite sprite, int pairIndex)> _cardDataToSpawn = new List<(Sprite, int)>();
private List<Card> _openCards = new List<Card>();
private bool _isChecking = false;
void Start()
{
InitializeGame();
}
private void InitializeGame()
{
_totalCards = rows * columns;
int requiredCards = _totalCards;
int requiredUniqueSprites = _totalCards;
int requiredSpritePairs = requiredCards / 2;
if (_totalCards % 2 != 0)
{
Debug.LogError("Общее количество карт (rows * columns) должно быть четным для пар!");
return;
}
if (frontSprites.Count != requiredUniqueSprites)
{
Debug.LogError($"Неправильное количество спрайтов! Требуется {requiredUniqueSprites} (по 2 на каждую из {requiredSpritePairs} пар). Доступно: {frontSprites.Count}. Проверьте, что указали *обе* картинки для каждой пары.");
return;
}
// 1. Подготовка данных о картах для спавна
for (int i = 0; i < frontSprites.Count; i += 2)
{
int pairIndex = i / 2;
_cardDataToSpawn.Add((frontSprites[i], pairIndex)); // Спрайт A
_cardDataToSpawn.Add((frontSprites[i + 1], pairIndex)); // Спрайт B
}
// 2. Рандомизация списка (Fisher-Yates shuffle)
System.Random rng = new System.Random();
int n = _cardDataToSpawn.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
(_cardDataToSpawn[n], _cardDataToSpawn[k]) = (_cardDataToSpawn[k], _cardDataToSpawn[n]); // Swap
}
// 3. Спавн карт
SpawnCards();
}
private void SpawnCards()
{
// Расчет стартовой позиции для центрирования сетки
float startX = -(columns - 1) * horizontalSpacing / 2f;
float startY = (rows - 1) * verticalSpacing / 2f;
Vector3 scaleVector = new Vector3(cardScale, cardScale, cardScale); // Вектор для нового масштаба
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < columns; c++)
{
int cardIndex = r * columns + c;
var data = _cardDataToSpawn[cardIndex];
Sprite frontSprite = data.sprite;
int pairIndex = data.pairIndex;
Vector3 position = new Vector3(
startX + c * horizontalSpacing,
startY - r * verticalSpacing,
0
);
Card newCard = Instantiate(cardPrefab, position, Quaternion.identity, transform);
newCard.gameObject.name = $"Card ({r},{c}) - Pair {pairIndex} ({frontSprite.name})";
newCard.CardSettings(cardBackSprite, frontSprite, pairIndex);
// ПРИМЕНЕНИЕ НОВОГО МАСШТАБА КО ВСЕМ КАРТАМ
newCard.transform.localScale = scaleVector;
newCard.SetCardCollector(this);
}
}
}
public void OpenCard(Card card)
{
_openCards.Add(card);
if (_openCards.Count == 2)
{
StartCoroutine(CheckForMatch());
}
}
public bool TwoCardsClosed()
{
return _openCards.Count < 2 && !_isChecking;
}
private IEnumerator CheckForMatch()
{
_isChecking = true;
Card card1 = _openCards[0];
Card card2 = _openCards[1];
yield return new WaitForSeconds(0.5f);
if (card1.Index == card2.Index)
{
Debug.Log($"Найдена пара! Индекс: {card1.Index}. Карты исчезают.");
yield return new WaitForSeconds(closeDelay);
// Прежде чем уничтожить, убедимся, что они не пытаются открыться снова.
Destroy(card1.gameObject);
Destroy(card2.gameObject);
}
else
{
Debug.Log("Нет совпадения. Карты закроются через 1 секунду.");
yield return new WaitForSeconds(closeDelay);
// Закрываем карты
card1.CardAnimation();
card2.CardAnimation();
// Снова включаем коллайдеры
card1.EnableCollider();
card2.EnableCollider();
}
_openCards.Clear();
_isChecking = false;
}
}