TO SQUASH: Nuke ball explosion.
This commit is contained in:
@@ -9,6 +9,12 @@ public class WorldFiller : MonoBehaviour
|
||||
|
||||
public GameObject wallPrefab;
|
||||
|
||||
public BallSpawner ballSpawner;
|
||||
|
||||
public AudioClip areaDestroyed;
|
||||
|
||||
private AudioSource audioSource;
|
||||
|
||||
[SerializeField]
|
||||
private float fallbackBarThicknessWorldUnits = 0.08f;
|
||||
|
||||
@@ -33,6 +39,7 @@ public class WorldFiller : MonoBehaviour
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
void Start()
|
||||
{
|
||||
audioSource = GetComponent<AudioSource>();
|
||||
gameBoardBounds = gameBoardSpriteRenderer.bounds;
|
||||
InitializeFreeAreas();
|
||||
ClearWalls();
|
||||
@@ -299,7 +306,7 @@ public class WorldFiller : MonoBehaviour
|
||||
return false;
|
||||
}
|
||||
|
||||
public float GetAreaPercentOfFreeRegion(Vector2 position)
|
||||
public float GetAreaPercentOfFreeRegion(Vector2 position)
|
||||
{
|
||||
if (freeAreas.Count == 0 && gameBoardSpriteRenderer != null)
|
||||
{
|
||||
@@ -317,6 +324,75 @@ public float GetAreaPercentOfFreeRegion(Vector2 position)
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
public Rect? GetFreeRegionOfPosition(Vector2 position)
|
||||
{
|
||||
if (freeAreas.Count == 0 && gameBoardSpriteRenderer != null)
|
||||
{
|
||||
InitializeFreeAreas();
|
||||
}
|
||||
|
||||
for (int i = 0; i < freeAreas.Count; i++)
|
||||
{
|
||||
if (RectContainsWithTolerance(freeAreas[i], position))
|
||||
{
|
||||
return freeAreas[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool FillFreeRegion(Rect freeRegion)
|
||||
{
|
||||
if ((freeAreas.Count == 0 || boardArea <= geometryEpsilon) && gameBoardSpriteRenderer != null)
|
||||
{
|
||||
InitializeFreeAreas();
|
||||
}
|
||||
|
||||
if (!TryGetMatchingFreeArea(freeRegion, out Rect regionToFill))
|
||||
{
|
||||
Debug.LogWarning("Requested region is not currently a free area.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TrySpawnWallInRect(regionToFill))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
audioSource.PlayOneShot(areaDestroyed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Queue<GameObject> GetBallsInSameFreeRegion(Vector2 position)
|
||||
{
|
||||
Queue<GameObject> ballsInSameRegion = new Queue<GameObject>();
|
||||
|
||||
if (ballSpawner == null)
|
||||
{
|
||||
return ballsInSameRegion;
|
||||
}
|
||||
|
||||
var targetRegion = GetFreeRegionOfPosition(position);
|
||||
|
||||
if (targetRegion == null)
|
||||
{
|
||||
return ballsInSameRegion;
|
||||
}
|
||||
|
||||
foreach (var ball in ballSpawner.GetBalls())
|
||||
{
|
||||
var ballRegion = GetFreeRegionOfPosition(ball.transform.position);
|
||||
if (ballRegion != null && ballRegion.Value == targetRegion.Value)
|
||||
{
|
||||
ballsInSameRegion.Enqueue(ball);
|
||||
}
|
||||
}
|
||||
|
||||
return ballsInSameRegion;
|
||||
}
|
||||
|
||||
public Vector2 GetRandomPositionInFreeAreas(Bounds? clearingArea = null)
|
||||
{
|
||||
if (freeAreas.Count == 0 && gameBoardSpriteRenderer != null)
|
||||
@@ -531,6 +607,180 @@ public float GetAreaPercentOfFreeRegion(Vector2 position)
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryGetMatchingFreeArea(Rect requestedRegion, out Rect matchedRegion)
|
||||
{
|
||||
for (int i = 0; i < freeAreas.Count; i++)
|
||||
{
|
||||
if (RectsApproximatelyEqual(freeAreas[i], requestedRegion))
|
||||
{
|
||||
matchedRegion = freeAreas[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
matchedRegion = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool RectsApproximatelyEqual(Rect a, Rect b)
|
||||
{
|
||||
return Mathf.Abs(a.xMin - b.xMin) <= geometryEpsilon
|
||||
&& Mathf.Abs(a.yMin - b.yMin) <= geometryEpsilon
|
||||
&& Mathf.Abs(a.xMax - b.xMax) <= geometryEpsilon
|
||||
&& Mathf.Abs(a.yMax - b.yMax) <= geometryEpsilon;
|
||||
}
|
||||
|
||||
private bool TrySpawnWallInRect(Rect targetRect)
|
||||
{
|
||||
if (wallPrefab == null)
|
||||
{
|
||||
Debug.LogError("Wall prefab is not assigned.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gameBoardSpriteRenderer == null)
|
||||
{
|
||||
Debug.LogError("Game board SpriteRenderer is not assigned.");
|
||||
return false;
|
||||
}
|
||||
|
||||
gameBoardBounds = gameBoardSpriteRenderer.bounds;
|
||||
|
||||
Rect boardRect = Rect.MinMaxRect(
|
||||
gameBoardBounds.min.x,
|
||||
gameBoardBounds.min.y,
|
||||
gameBoardBounds.max.x,
|
||||
gameBoardBounds.max.y
|
||||
);
|
||||
|
||||
if (!TryGetRectIntersection(targetRect, boardRect, out Rect clampedRect))
|
||||
{
|
||||
Debug.LogWarning("Target wall rectangle is outside the game board bounds.");
|
||||
return false;
|
||||
}
|
||||
|
||||
GameObject wall = Instantiate(wallPrefab, Vector3.zero, Quaternion.identity);
|
||||
var wallRenderer = wall.GetComponentInChildren<SpriteRenderer>();
|
||||
|
||||
if (wallRenderer == null)
|
||||
{
|
||||
Debug.LogError("Wall prefab is missing a SpriteRenderer in children.");
|
||||
Destroy(wall);
|
||||
return false;
|
||||
}
|
||||
|
||||
float wallPaddingWorldUnits = PixelsToWorldUnits(wallPaddingPixelsPerSide, wallRenderer);
|
||||
Rect paddedWallRect = ExpandRectInsideBounds(clampedRect, wallPaddingWorldUnits, boardRect);
|
||||
|
||||
ApplyWallTransform(wall.transform, wallRenderer, paddedWallRect);
|
||||
spawnedWalls.Enqueue(wall);
|
||||
|
||||
UpdateFreeAreas(paddedWallRect);
|
||||
ResolveWallIntersections(wallRenderer.bounds);
|
||||
DestroyBarSegments();
|
||||
|
||||
if (boardArea <= geometryEpsilon)
|
||||
{
|
||||
boardArea = boardRect.width * boardRect.height;
|
||||
}
|
||||
|
||||
int areaPercentage = boardArea > geometryEpsilon
|
||||
? Mathf.RoundToInt((paddedWallRect.width * paddedWallRect.height / boardArea) * 100.0f)
|
||||
: 0;
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
player.OnWallSpawned(areaPercentage);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ResolveWallIntersections(Bounds wallBounds)
|
||||
{
|
||||
// Yummies and multipliers are awarded if intersected by the spawned wall.
|
||||
var yummies = GameObject.FindGameObjectsWithTag("Yummy");
|
||||
var multipliers = GameObject.FindGameObjectsWithTag("Multiplier");
|
||||
var shark = GameObject.FindGameObjectWithTag("Shark");
|
||||
|
||||
foreach (var yummy in yummies)
|
||||
{
|
||||
if (yummy == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var yummyRenderer = yummy.GetComponent<SpriteRenderer>();
|
||||
if (yummyRenderer == null || !wallBounds.Intersects(yummyRenderer.bounds))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
YummyBase yummyBase = yummy.GetComponent<YummyBase>();
|
||||
|
||||
if (yummyBase != null)
|
||||
{
|
||||
yummyBase.AwardToPlayer(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("YummyBase component not found on yummy object.");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var multiplier in multipliers)
|
||||
{
|
||||
if (multiplier == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var multiplierRenderer = multiplier.GetComponent<SpriteRenderer>();
|
||||
if (multiplierRenderer == null || !wallBounds.Intersects(multiplierRenderer.bounds))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Multiplier multiplierComponent = multiplier.GetComponent<Multiplier>();
|
||||
|
||||
if (multiplierComponent != null)
|
||||
{
|
||||
multiplierComponent.AwardToPlayer(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Multiplier component not found on multiplier object.");
|
||||
}
|
||||
}
|
||||
|
||||
if (shark == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sharkRenderer = shark.GetComponent<SpriteRenderer>();
|
||||
if (sharkRenderer == null || !wallBounds.Intersects(sharkRenderer.bounds))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Shark sharkComponent = shark.GetComponent<Shark>();
|
||||
if (sharkComponent != null)
|
||||
{
|
||||
sharkComponent.KillShark();
|
||||
}
|
||||
}
|
||||
|
||||
private void DestroyBarSegments()
|
||||
{
|
||||
GameObject[] barSegments = GameObject.FindGameObjectsWithTag("Bar");
|
||||
|
||||
foreach (GameObject barSegment in barSegments)
|
||||
{
|
||||
Destroy(barSegment);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyWallTransform(Transform wallTransform, SpriteRenderer wallRenderer, Rect targetRect)
|
||||
{
|
||||
Vector2 baseSize = wallRenderer.bounds.size;
|
||||
|
||||
Reference in New Issue
Block a user