Reputation: 511
I want to replace the destroyed hexagons with other standing hexagons. Existing hexagons should fall from the top. For example if I destroy (0,2) positioned hexagon in the picture below, the top left hexagon which position of that hexagon is (0,0) should be moved to (0,2) position and i should create a new hexagon and put it on (0,0) which is empty now because we moved the hexagon on (0,0) to (0,2) earlier.
I have a two dimensional array that stores all the references of hexagons with an index of the hexagon's coordinate (x,y).
--IMPORTANT--
Moving the objects is not important. The important part is we have to know which hexagon will be replaced with another. We have to tell the ARRAY that we changed those hexagons and the hexagons that were just moved or created should have exactly one reference in the index of their new (x,y) positions.
VIDEO FOR BETTER EXPLAINING WHAT I WANT TO DO
https://www.youtube.com/watch?v=QYhq0qwFmmY
Any ideas or help would be appreciated!
Hexagon Coordinate system (ignore red arrows)
public void CreateGrid(int gridWidth, int gridHeight)
{
for (int y = 0; y < gridHeight; y++)
{
for (int x = 0; x < gridWidth; x++)
{
GameObject Hexagon = Instantiate(HexagonPre, Vector2.zero, Quaternion.identity, HexGrid);
int RandColor = Random.Range(0, 5);
if (RandColor == 0)
{
Hexagon.GetComponent<SpriteRenderer>().color = Color.blue;
}
else if (RandColor == 1)
{
Hexagon.GetComponent<SpriteRenderer>().color = Color.red;
}
else if (RandColor == 2)
{
Hexagon.GetComponent<SpriteRenderer>().color = Color.green;
}
else if (RandColor == 3)
{
Hexagon.GetComponent<SpriteRenderer>().color = Color.yellow;
}
else if (RandColor == 4)
{
Hexagon.GetComponent<SpriteRenderer>().color = Color.cyan;
}
Vector2 gridPos = new Vector2(x, y);
Hexagon.transform.position = CalcWorldPos(gridPos);
Hexagon.GetComponent<HexCoordinates>().Coordinates = new Vector2Int(x, y);
Hexagon.transform.name = "X: " + x + " | Y: " + y;
}
}
}
Code for destroying hexagons
if (MatchedColors == 2)
{
if(!HexToBeDestroyed.Contains(Hexagons[x, y].gameObject))
HexToBeDestroyed.Add(Hexagons[x, y].gameObject);
if (!HexToBeDestroyed.Contains(Hexagons[x - 1, y].gameObject))
HexToBeDestroyed.Add(Hexagons[x - 1, y].gameObject);
if (!HexToBeDestroyed.Contains(Hexagons[x - 1, y - 1].gameObject))
HexToBeDestroyed.Add(Hexagons[x - 1, y - 1].gameObject);
}
MatchedColors = 0;
}
}
}
}
foreach (GameObject G in HexToBeDestroyed)
{
if (G != null)
{
Destroy(G.gameObject);
}
}
Upvotes: 2
Views: 128
Reputation: 20269
Explanation for code is in comments:
void HexagonFall(GameObject[,] hexArray)
{
// Handle fall for base columns and for offset columns
for (int offset = 0 ; offset < 2 ; offset++)
{
// Handle fall for each column at current offset
for (int x = 0 ; x < hexArray.GetLength(0) ; x++)
{
int bottomYIndex = hexArray.GetLength(1) - offset - 1;
// List of indices of where each hexagon in that column will come from.
// We will fill from bottom to top.
List<Vector2Int> sourceIndices = new List<Vector2Int>();
for (int y = bottomYIndex ; y >= 0 ; y-=2)
{
// HexExists returns true if the hex isn't empty.
// Something along the lines of ` return input!=null; `
// depending on what "empty" hexes look like in the array
if (HexExists(hexArray[x,y]))
{
sourceIndices.Add(new Vector2Int(x,y));
}
}
// We have a list of where to get each bottom hexes from, now do the move/create
for (int y = bottomYIndex; y >= 0 ; y-=2)
{
if (sourceIndices.Count > 0)
{
// If we have any available hexes in column,
// use the bottommost one (at index 0)
hexArray[x,y] = hexArray[sourceIndices[0].x, sourceIndices[0].y];
// We have now found a home for hex previously at sourceIndices[0].
// Remove that index from list so hex will stay put.
sourceIndices.RemoveAt(0);
}
else
{
// Otherwise, we need to generate a new hex
hexArray[x,y] = MakeNewHexAt(new Vector2Int(x,y));
}
// Tell the hex about its new home
hexArray[x,y].GetComponent<HexCoordinates>().Coordinates = new Vector2Int(x, y);
hexArray[x,y].transform.name = "X: " + x + " | Y: " + y;
}
}
}
}
In your hex destroying code, I would change HexToBeDestroyed to be a List
of Vector2Int
so you can set the array references to null immediately when you Destroy
the gameobject:
List<Vector2Int> HexToBeDestroyed = new List<Vector2Int>();
// ...
if (MatchedColors == 2)
{
if(!HexToBeDestroyed.Contains(new Vector2Int(x, y))
HexToBeDestroyed.Add(new Vector2Int(x, y));
if (!HexToBeDestroyed.Contains(new Vector2Int(x - 1, y))
HexToBeDestroyed.Add(new Vector2Int(x - 1, y));
if (!HexToBeDestroyed.Contains(new Vector2Int(x - 1, y - 1)))
HexToBeDestroyed.Add(new Vector2Int(x - 1, y - 1));
}
// ...
foreach (Vector2Int V in HexToBeDestroyed)
{
if (Hexagons[V.x,V.y] != null)
{
Destroy(Hexagons[V.x,V.y]);
Hexagons[V.x,V.y] = null;
}
}
As far as moving the hexes goes, I would add this in the Update
of HexCoordinates
:
float fallSpeed = 0.5f;
Vector2 goalWorldPosition = GS.CalcWorldPos(Coordinates);
transform.position = Vector2.MoveTowards(transform.position, goalWorldPosition, fallSpeed * Time.deltaTime);
Upvotes: 1