From b7518b77da6511a396501b51b5046ed86ce8d98b Mon Sep 17 00:00:00 2001
From: miepzerino <o.skotnik@gmail.com>
Date: Fri, 28 Mar 2025 21:08:03 +0000
Subject: [PATCH] #22 Reworked background dynamic generation

---
 Assets/Scripts/Tiling.cs |  172 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 157 insertions(+), 15 deletions(-)

diff --git a/Assets/Scripts/Tiling.cs b/Assets/Scripts/Tiling.cs
index ce70561..1f40aa7 100644
--- a/Assets/Scripts/Tiling.cs
+++ b/Assets/Scripts/Tiling.cs
@@ -5,8 +5,17 @@
 [RequireComponent(typeof(SpriteRenderer))]
 public class Tiling : MonoBehaviour
 {
+    [System.Serializable]
+    public class HeightSpritePair
+    {
+        public float minHeight;
+        public float maxHeight;
+        public Sprite sprite;
+    }
+
     public int offsetX = 2;
     public int offsetY = 2;
+    public HeightSpritePair[] heightSprites;
 
     public bool hasRightBuddy = false;
     public bool hasLeftBuddy = false;
@@ -19,65 +28,198 @@
     private float spriteHeight = 0f;
     private Camera cam;
     private Transform myTransform;
+    private SpriteRenderer spriteRenderer;
 
     private void Awake()
     {
         cam = Camera.main;
         myTransform = transform;
+        spriteRenderer = GetComponent<SpriteRenderer>();
     }
-    // Start is called before the first frame update
+
     void Start()
     {
-        SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
+        UpdateSpriteForHeight();
         spriteWidth = spriteRenderer.sprite.bounds.size.x;
         spriteHeight = spriteRenderer.sprite.bounds.size.y;
-
-        //GenerateBackground();
     }
 
-    // Update is called once per frame
     void Update()
+    {
+        if (CheckOffscreenAndDestroy()) return; // Return early if destroyed
+        CheckHorizontalTiling();
+        CheckVerticalTiling();
+    }
+
+    private void UpdateSpriteForHeight()
+    {
+        if (heightSprites == null || heightSprites.Length == 0) return;
+
+        float worldY = transform.position.y;
+        Sprite oldSprite = spriteRenderer.sprite;
+
+        foreach (HeightSpritePair pair in heightSprites)
+        {
+            if (pair.sprite == null) continue; // Skip invalid sprites
+
+            if ((pair.minHeight == 0 && pair.maxHeight == 0) ||
+                (worldY >= pair.minHeight && worldY <= pair.maxHeight))
+            {
+                if (oldSprite != pair.sprite)
+                {
+                    spriteRenderer.sprite = pair.sprite;
+                    // Update sprite dimensions if sprite changed
+                    spriteWidth = spriteRenderer.sprite.bounds.size.x;
+                    spriteHeight = spriteRenderer.sprite.bounds.size.y;
+                }
+                break;
+            }
+        }
+    }
+
+    private void CheckHorizontalTiling()
     {
         if (!hasLeftBuddy || !hasRightBuddy)
         {
             float camHorizontalExtend = cam.orthographicSize * Screen.width / Screen.height;
-
             float edgeVisiblePositionRight = (transform.position.x + spriteWidth / 2) - camHorizontalExtend;
             float edgeVisiblePositionLeft = (transform.position.x - spriteWidth / 2) + camHorizontalExtend;
 
             if (cam.transform.position.x >= edgeVisiblePositionRight - offsetX && !hasRightBuddy)
             {
-                MakeNewRightOrLeftBuddy(1);
+                MakeNewBuddy(1, 0);
                 hasRightBuddy = true;
             }
             else if (cam.transform.position.x <= edgeVisiblePositionLeft + offsetX && !hasLeftBuddy)
             {
-                MakeNewRightOrLeftBuddy(-1);
+                MakeNewBuddy(-1, 0);
                 hasLeftBuddy = true;
             }
         }
     }
 
-    private void MakeNewRightOrLeftBuddy(int rightOrLeft)
+    private void CheckVerticalTiling()
     {
-        Vector3 newPosition = new Vector3(myTransform.position.x + spriteWidth * rightOrLeft, myTransform.position.y, myTransform.position.z);
+        if (!hasTopBuddy || !hasBottomBuddy)
+        {
+            float camVerticalExtend = cam.orthographicSize;
+            float edgeVisiblePositionTop = (transform.position.y + spriteHeight / 2) - camVerticalExtend;
+            float edgeVisiblePositionBottom = (transform.position.y - spriteHeight / 2) + camVerticalExtend;
+
+            if (cam.transform.position.y >= edgeVisiblePositionTop - offsetY && !hasTopBuddy)
+            {
+                MakeNewBuddy(0, 1);
+                hasTopBuddy = true;
+            }
+            else if (cam.transform.position.y <= edgeVisiblePositionBottom + offsetY && !hasBottomBuddy)
+            {
+                MakeNewBuddy(0, -1);
+                hasBottomBuddy = true;
+            }
+        }
+    }
+
+    private void MakeNewBuddy(int rightOrLeft, int topOrBottom)
+    {
+        Vector3 newPosition = new Vector3(
+            myTransform.position.x + spriteWidth * rightOrLeft,
+            myTransform.position.y + spriteHeight * topOrBottom,
+            myTransform.position.z
+        );
+
         Transform newBuddy = Instantiate(myTransform, newPosition, myTransform.rotation);
+        Tiling buddyTiling = newBuddy.GetComponent<Tiling>();
 
         if (reverseScale)
         {
-            newBuddy.localScale = new Vector3(newBuddy.localScale.x * -1, newBuddy.localScale.y, newBuddy.localScale.z);
+            newBuddy.localScale = new Vector3(
+                rightOrLeft != 0 ? newBuddy.localScale.x * -1 : newBuddy.localScale.x,
+                topOrBottom != 0 ? newBuddy.localScale.y * -1 : newBuddy.localScale.y,
+                newBuddy.localScale.z
+            );
         }
 
         newBuddy.parent = myTransform.parent;
         newBuddy.name = myTransform.name;
 
-        if (rightOrLeft > 0)
+        if (rightOrLeft > 0) buddyTiling.hasLeftBuddy = true;
+        else if (rightOrLeft < 0) buddyTiling.hasRightBuddy = true;
+        if (topOrBottom > 0) buddyTiling.hasBottomBuddy = true;
+        else if (topOrBottom < 0) buddyTiling.hasTopBuddy = true;
+
+        buddyTiling.UpdateSpriteForHeight();
+    }
+
+    private bool CheckOffscreenAndDestroy()
+    {
+        Vector3 viewportPosition = cam.WorldToViewportPoint(transform.position);
+        float buffer = 1.5f;
+
+        if (viewportPosition.x < -buffer || viewportPosition.x > 1 + buffer ||
+            viewportPosition.y < -buffer || viewportPosition.y > 1 + buffer)
         {
-            newBuddy.GetComponent<Tiling>().hasLeftBuddy = true;
+            NotifyNeighbors();
+            Destroy(gameObject);
+            return true;
         }
-        else if (rightOrLeft < 0)
+        return false;
+    }
+    private void NotifyNeighbors()
+    {
+        // Use a slightly smaller size than the sprite to ensure we only hit immediate neighbors
+        Vector2 checkSize = new Vector2(spriteWidth * 0.9f, spriteHeight * 0.9f);
+        Vector2 position = transform.position;
+        ContactFilter2D filter = new ContactFilter2D().NoFilter();
+        Collider2D[] results = new Collider2D[1];
+
+        // Check each direction using OverlapBox
+        // Right neighbor
+        if (Physics2D.OverlapBox(position + new Vector2(spriteWidth, 0), 
+            checkSize, 0f,
+            filter, results) > 0)
         {
-            newBuddy.GetComponent<Tiling>().hasRightBuddy = true;
+            Tiling rightTile = results[0].GetComponent<Tiling>();
+            if (rightTile != null) rightTile.hasLeftBuddy = false;
+        }
+
+        // Left neighbor
+        if (Physics2D.OverlapBox(position + new Vector2(-spriteWidth, 0),
+            checkSize, 0f,
+            filter, results) > 0)
+        {
+            Tiling leftTile = results[0].GetComponent<Tiling>();
+            if (leftTile != null) leftTile.hasRightBuddy = false;
+        }
+
+        // Top neighbor
+        if (Physics2D.OverlapBox(position + new Vector2(0, spriteHeight),
+            checkSize, 0f,
+            filter, results) > 0)
+        {
+            Tiling topTile = results[0].GetComponent<Tiling>();
+            if (topTile != null) topTile.hasBottomBuddy = false;
+        }
+
+        // Bottom neighbor
+        if (Physics2D.OverlapBox(position + new Vector2(0, -spriteHeight),
+            checkSize, 0f,
+            filter, results) > 0)
+        {
+            Tiling bottomTile = results[0].GetComponent<Tiling>();
+            if (bottomTile != null) bottomTile.hasTopBuddy = false;
         }
     }
+    //private void OnDrawGizmos()
+    //{
+    //    if (!Application.isPlaying) return;
+
+    //    Vector2 checkSize = new Vector2(spriteWidth * 0.9f, spriteHeight * 0.9f);
+    //    Gizmos.color = Color.yellow;
+
+    //    // Draw detection boxes for each direction
+    //    Gizmos.DrawWireCube((Vector2)transform.position + new Vector2(spriteWidth, 0), checkSize);
+    //    Gizmos.DrawWireCube((Vector2)transform.position + new Vector2(-spriteWidth, 0), checkSize);
+    //    Gizmos.DrawWireCube((Vector2)transform.position + new Vector2(0, spriteHeight), checkSize);
+    //    Gizmos.DrawWireCube((Vector2)transform.position + new Vector2(0, -spriteHeight), checkSize);
+    //}
 }

--
Gitblit v1.9.3