bubble_shooter/Assets/Scripts/BubblesGenerator.cs
2025-05-20 10:03:01 +05:30

237 lines
7.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BubblesGenerator : MonoBehaviour
{
public bool drawGizmos = false;
public Vector2 NumberOfBubbles;
public GameObject BubblePrefab;
public float BubbleSize;
public Sprite[] BubbleSprites;
public Sprite GetRandomBubbleSprite()
{
return BubbleSprites[Random.Range(0, BubbleSprites.Length)];
}
public Dictionary<Vector2, GameObject> bubbles;
public GameObject GetBubble(Vector2 gridPosition)
{
GameObject output = bubbles[gridPosition];
float minDistance = float.MaxValue;
GameObject closestBubble = null;
if (output == null)
{
foreach (KeyValuePair<Vector2, GameObject> bubble in bubbles)
{
float distance = Vector2.Distance(gridPosition, bubble.Key);
if (distance < minDistance)
{
minDistance = distance;
closestBubble = bubble.Value;
}
}
}
if (minDistance < BubbleSize / 4f)
{
output = closestBubble;
}
return output;
}
public void UpdateAllNeighbors()
{
foreach (KeyValuePair<Vector2, GameObject> bubble in bubbles)
{
if(bubble.Value == null){
continue;
}
Bubble bub = bubble.Value.GetComponent<Bubble>();
HashSet<GameObject> checkedBubbles = new HashSet<GameObject>();
List<GameObject> bubblesToCheck = new List<GameObject>();
List<GameObject> allMatchingBubbles = new List<GameObject>();
bub.neighbors = new List<GameObject>();
bubblesToCheck.Add(bubble.Value);
checkedBubbles.Add(bubble.Value);
int lowestNeightbourY = 10;
while (bubblesToCheck.Count > 0)
{
GameObject currentBubble = bubblesToCheck[0];
bubblesToCheck.RemoveAt(0);
allMatchingBubbles.Add(currentBubble);
List<GameObject> neighbors = GetNeighbors(currentBubble);
foreach (GameObject neighbor in neighbors)
{
if (!checkedBubbles.Contains(neighbor))
{
bubblesToCheck.Add(neighbor);
checkedBubbles.Add(neighbor);
}
if (neighbor != null && neighbor.GetComponent<Bubble>() != null)
{
if (neighbor.GetComponent<Bubble>().gridPosition.y < lowestNeightbourY)
{
lowestNeightbourY = (int)neighbor.GetComponent<Bubble>().gridPosition.y;
}
bub.neighbors.Add(neighbor);
}
}
}
bub.processNeighbors(lowestNeightbourY);
}
}
public List<GameObject> GetNeighbors(GameObject bubble, bool filter = false)
{
List<GameObject> neighbors = new List<GameObject>();
try
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(bubble.transform.position, BubbleSize);
foreach (Collider2D collider in colliders)
{
if (collider.gameObject == bubble) { continue; }
if (collider.gameObject != bubble)
{
if (filter)
{
if (bubble.GetComponent<SpriteRenderer>().sprite == collider.gameObject.GetComponent<SpriteRenderer>().sprite)
{
neighbors.Add(collider.gameObject);
}
}
else
{
neighbors.Add(collider.gameObject);
}
if (collider.gameObject.GetComponent<Bubble>() != null)
{
}
}
}
}
catch
{
}
return neighbors;
}
void Start()
{
GenerateBubbles();
}
void GenerateBubbles()
{
List<Vector2> positions = GetBubblePositions();
bubbles = new Dictionary<Vector2, GameObject>();
foreach (Vector2 gridPosition in positions)
{
Vector2 position = GetBubblePosition(gridPosition);
AddBubble(gridPosition);
}
}
public GameObject AddBubble(Vector2 gridPosition, Sprite sprite = null)
{
Sprite _sprite;
if (sprite == null)
{
_sprite = GetRandomBubbleSprite();
}
else
{
_sprite = sprite;
}
Vector2 position = GetBubblePosition(gridPosition);
if (bubbles.ContainsKey(gridPosition))
{
// Try to find a free neighboring position
Vector2[] possibleNeighbors = new Vector2[] {
new Vector2(gridPosition.x + 1, gridPosition.y),
new Vector2(gridPosition.x - 1, gridPosition.y),
new Vector2(gridPosition.x, gridPosition.y + 1),
new Vector2(gridPosition.x, gridPosition.y - 1),
new Vector2(gridPosition.x + 1, gridPosition.y + 1),
new Vector2(gridPosition.x - 1, gridPosition.y + 1)
};
foreach (Vector2 neighborPos in possibleNeighbors)
{
if (!bubbles.ContainsKey(neighborPos))
{
gridPosition = neighborPos;
position = GetBubblePosition(gridPosition);
break;
}
}
}
GameObject bubble = Instantiate(BubblePrefab, position, Quaternion.identity);
bubble.GetComponent<SpriteRenderer>().sprite = _sprite;
bubble.GetComponent<Bubble>().gridPosition = gridPosition;
bubble.GetComponent<Bubble>().bubblesGenerator = this;
bubbles.Add(gridPosition, bubble);
return bubble;
}
public void RemoveBubble(GameObject _bubble)
{
foreach (KeyValuePair<Vector2, GameObject> bubble in bubbles)
{
if (bubble.Value == _bubble)
{
bubbles.Remove(bubble.Key);
Destroy(_bubble);
break;
}
}
}
void OnDrawGizmos()
{
if (!drawGizmos) { return; }
Gizmos.color = Color.red;
foreach (Vector2 gridPosition in GetBubblePositions())
{
Vector2 position = GetBubblePosition(gridPosition);
Gizmos.DrawWireSphere(position, BubbleSize / 2);
}
}
List<Vector2> GetBubblePositions()
{
List<Vector2> positions = new List<Vector2>();
for (int i = 0; i < NumberOfBubbles.x; i++)
{
for (int j = 0; j < NumberOfBubbles.y; j++)
{
positions.Add(new Vector2(i, j));
if (i > 0)
{
positions.Add(new Vector2(-i, j));
}
}
}
return positions;
}
public Vector2 GetBubblePosition(Vector2 gridPosition)
{
int i = (int)gridPosition.x;
int j = (int)gridPosition.y;
float xOffset = (j % 2 == 0) ? 0 : BubbleSize / 2;
float yMult = 0.9f;
return (Vector2)transform.position + (new Vector2(i + xOffset, -j * yMult) * BubbleSize);
}
}