237 lines
7.4 KiB
C#
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);
|
|
}
|
|
}
|