Advertisement
AtomicRogue1

Untitled

Jul 9th, 2025
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.11 KB | Software | 0 0
  1. using Godot;
  2. using System;
  3. using System.Collections.Generic;
  4.  
  5. public partial class PlayerPlacement : Node2D
  6. {
  7.     public int[,] currentMap;   // int[,] map will be passed by reference from GameManager when connecting signal
  8.     int biggestAreaSize;
  9.     List<Vector2I> finalAreas;
  10.     public TileMap levelTilemap;
  11.  
  12.     void calculatePlayField(int currentRow, int currentCol, ref bool[,] visited)
  13.     {
  14.         List<Vector2I> potentialAreas = new List<Vector2I>();
  15.         Stack<Vector2I> dfsStack = new Stack<Vector2I>();
  16.         dfsStack.Push(new Vector2I(currentRow,currentCol));
  17.         int sizeOfArea=0;
  18.  
  19.         Vector2I currTop;
  20.  
  21.         while(dfsStack.Count!=0)
  22.         {
  23.             currTop=dfsStack.Pop();
  24.             potentialAreas.Add(currTop);
  25.             visited[currTop.X,currTop.Y]=true;
  26.  
  27.             if(currTop.X-1>=0)
  28.             if(currentMap[currTop.X-1,currTop.Y]==1 && !visited[currTop.X-1,currTop.Y])
  29.             dfsStack.Push(new Vector2I(currTop.X-1, currTop.Y));
  30.            
  31.             if(currTop.X+1<currentMap.GetLength(0))
  32.             if(currentMap[currTop.X+1,currTop.Y]==1 && !visited[currTop.X+1,currTop.Y])
  33.             dfsStack.Push(new Vector2I(currTop.X+1, currTop.Y));
  34.            
  35.             if(currTop.Y-1>=0)
  36.             if(currentMap[currTop.X,currTop.Y-1]==1 && !visited[currTop.X,currTop.Y-1])
  37.             dfsStack.Push(new Vector2I(currTop.X, currTop.Y-1));
  38.  
  39.             if(currTop.Y+1<currentMap.GetLength(1))
  40.             if(currentMap[currTop.X,currTop.Y+1]==1 && !visited[currTop.X,currTop.Y+1])
  41.             dfsStack.Push(new Vector2I(currTop.X, currTop.Y+1));
  42.  
  43.             sizeOfArea+=1;
  44.         }
  45.  
  46.         if(potentialAreas.Count > biggestAreaSize)
  47.         {
  48.             biggestAreaSize = potentialAreas.Count;
  49.             finalAreas = potentialAreas;
  50.         }
  51.     }
  52.  
  53.     void bfs(int currentRow, int currentCol, ref bool[,] visited)
  54.     {
  55.         if (currentRow < 0 || currentRow >= currentMap.GetLength(0) || currentCol < 0 || currentCol >= currentMap.GetLength(1))
  56.         return;
  57.  
  58.         if (visited[currentRow, currentCol])
  59.         return;
  60.  
  61.         visited[currentRow,currentCol] = true;
  62.         if(currentMap[currentRow, currentCol]!=0)  
  63.         calculatePlayField(currentRow, currentCol, ref visited);
  64.  
  65.         if(currentRow-1>=0)
  66.         bfs(currentRow-1, currentCol, ref visited);
  67.         if(currentRow+1<currentMap.GetLength(0))
  68.         bfs(currentRow+1, currentCol, ref visited);
  69.         if(currentCol-1>=0)
  70.         bfs(currentRow, currentCol-1, ref visited);
  71.         if(currentCol+1<currentMap.GetLength(1))
  72.         bfs(currentRow, currentCol+1, ref visited);
  73.     }
  74.  
  75.     void identifyBiggestEmptyArea() // same map will be used as parameter. will return areas within biggest area
  76.     {
  77.         if (currentMap == null)
  78.         {
  79.         GD.PrintErr("PlayerPlacement: currentMap is null! Assign it before calling identifyBiggestEmptyArea().");
  80.         return;
  81.         }
  82.         bool[,] visited = new bool[currentMap.GetLength(0),currentMap.GetLength(1)]; // all initialized to 0
  83.  
  84.         biggestAreaSize = 0;
  85.         finalAreas = new List<Vector2I>();
  86.  
  87.         bfs(0,0,ref visited);
  88.     }
  89.  
  90.     void playerPositioning()
  91.     {
  92.  
  93.         Random rand = new Random();
  94.         Vector2 tileWorldPos;
  95.         Node2D playerNode = GetTree().Root.FindChild("Player", true, false) as Node2D;
  96.  
  97.         foreach(Vector2I pos in finalAreas)
  98.         {
  99.             if
  100.             (
  101.                 currentMap[pos.X+0,pos.Y+1]==0 &&  // ground should be right below
  102.                 currentMap[pos.X+(-1),pos.Y+1]==0 &&  // checking for surrounding blocks of air
  103.                 currentMap[pos.X+0,pos.Y-1]==1 &&
  104.                 currentMap[pos.X+1,pos.Y+1]==0 &&
  105.                 currentMap[pos.X+(-1),pos.Y+0]==1 &&
  106.                 currentMap[pos.X+1,pos.Y+0]==1 &&
  107.                 currentMap[pos.X+(-1),pos.Y+(-1)]==1 &&
  108.                 currentMap[pos.X+(1),pos.Y+(-1)]==1
  109.             )
  110.             {
  111.                 // So that positioning stays a little random,
  112.                 // I am going to have a random number decide the chance that I will place the player here.
  113.                 if(rand.Next(0, 100)>=50)
  114.                 {
  115.                     GD.Print("Found a suitable place!");
  116.                     tileWorldPos = levelTilemap.MapToLocal(pos);
  117.                     tileWorldPos=levelTilemap.ToGlobal(tileWorldPos);
  118.                     playerNode.GlobalPosition = tileWorldPos;
  119.                    
  120.                     // Uncomment for debugging
  121.                     // levelTilemap.SetCell(
  122.                     // 0,
  123.                     // pos,
  124.                     // 0,
  125.                     // new Vector2I(7, 5), 0
  126.                     // ); // Red marker for where player is placed.
  127.                     break;
  128.                 }
  129.             }
  130.         }
  131.     }
  132.  
  133.     void placePlayer() // int[,] map will be passed by reference from GameManager when connecting signal
  134.     {
  135.         if (levelTilemap == null)
  136.         {
  137.             GD.PushError("PlayerPlacement.cs: levelTilemap is null! Cannot place player. Make sure SetTileMap() is called with a valid TileMap before placePlayer().");
  138.             return;
  139.         }
  140.         if (currentMap == null)
  141.         {
  142.             GD.PushError("PlayerPlacement.cs: currentMap is null! Cannot place player. Make sure SetBitmap() is called with a valid map before placePlayer().");
  143.             return;
  144.         }
  145.         GD.Print("Identify biggest area for setting up level within map...");
  146.         identifyBiggestEmptyArea();
  147.         GD.Print("Placing player...");
  148.         playerPositioning();
  149.     }
  150.  
  151.     public void SetTileMap(TileMap tilemap)
  152.     {
  153.         if(tilemap == null)
  154.             GD.PushError("PlayerPlacement.cs: SetTileMap called with null tilemap!");
  155.         GD.Print("SetTilemap from PlayerPlacement called!");
  156.         levelTilemap = tilemap;
  157.     }
  158.  
  159.     public void SetBitmap(int[,] map)
  160.     {
  161.         if(map == null)
  162.             GD.PushError("PlayerPlacement.cs: SetBitmap called with null map!");
  163.         GD.Print("SetBitmap from PlayerPlacement called!");
  164.         currentMap = map;
  165.     }
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement