✨ Placement check with collision
This commit is contained in:
		| @@ -24,13 +24,29 @@ public partial class PlacementManager : Node2D | ||||
|             AddChild(_ghostBuilding); | ||||
|         } | ||||
|  | ||||
|         _ghostBuilding.Position = GridUtils.GridToWorld(_hoveredCell); | ||||
|         _ghostBuilding.SetGhostMode(true); | ||||
|         var placementPos = GridUtils.GridToWorld(_hoveredCell); | ||||
|         var spaceState = GetWorld2D().DirectSpaceState; | ||||
|         var centerPos = placementPos + new Vector2(GridUtils.TileSize / 2f, GridUtils.TileSize / 2f); | ||||
|  | ||||
|         var query = new PhysicsPointQueryParameters2D | ||||
|         { | ||||
|             Position = centerPos, | ||||
|             CollideWithBodies = true, | ||||
|             CollideWithAreas = true, | ||||
|             CollisionMask = uint.MaxValue // check against all layers/masks | ||||
|             // Exclude = new Godot.Collections.Array<Rid>() // optional, see below | ||||
|         }; | ||||
|  | ||||
|         var collision = spaceState.IntersectPoint(query, 8); | ||||
|         var canPlace = Grid.IsCellFree(_hoveredCell) && collision.Count == 0; | ||||
|  | ||||
|         _ghostBuilding.Position = placementPos; | ||||
|         _ghostBuilding.SetGhostMode(canPlace); | ||||
|  | ||||
|         // Left click to place | ||||
|         if (!Input.IsActionPressed("build_tile") || !Grid.IsCellFree(_hoveredCell)) return; | ||||
|         if (!Input.IsActionPressed("build_tile") || !canPlace) return; | ||||
|  | ||||
|         _ghostBuilding.SetGhostMode(false); | ||||
|         _ghostBuilding.FinalizePlacement(); | ||||
|         Grid.OccupyCell(_hoveredCell, _ghostBuilding); | ||||
|  | ||||
|         _ghostBuilding = (BaseTile)BuildingScene.Instantiate(); | ||||
|   | ||||
| @@ -1,30 +1,45 @@ | ||||
| using Godot; | ||||
|  | ||||
| namespace AceFieldNewHorizon.Scripts.Tiles; | ||||
|  | ||||
| public partial class BaseTile : Node2D | ||||
| namespace AceFieldNewHorizon.Scripts.Tiles | ||||
| { | ||||
|     protected CollisionShape2D CollisionShape; | ||||
|     protected Sprite2D Sprite; | ||||
|  | ||||
|     public override void _Ready() | ||||
|     public partial class BaseTile : Node2D | ||||
|     { | ||||
|         // Get references (optional: you can also Export and assign in editor) | ||||
|         CollisionShape = GetNode<CollisionShape2D>("CollisionShape2D"); | ||||
|         Sprite = GetNode<Sprite2D>("Sprite2D"); | ||||
|     } | ||||
|         private CollisionShape2D _collisionShape; | ||||
|         private Sprite2D _sprite; | ||||
|  | ||||
|     public void SetGhostMode(bool ghost) | ||||
|     { | ||||
|         if (CollisionShape != null) | ||||
|             CollisionShape.Disabled = ghost; | ||||
|  | ||||
|         if (Sprite != null) | ||||
|         public override void _Ready() | ||||
|         { | ||||
|             if (ghost) | ||||
|                 Sprite.Modulate = new Color(1, 1, 1, 0.5f); // semi-transparent | ||||
|             else | ||||
|                 Sprite.Modulate = Colors.White; | ||||
|             _collisionShape = GetNodeOrNull<CollisionShape2D>("CollisionShape2D"); | ||||
|             _sprite = GetNodeOrNull<Sprite2D>("Sprite2D"); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Switch between ghost and placed mode. | ||||
|         /// </summary> | ||||
|         /// <param name="canPlace">If in ghost mode, true = green, false = red. If placed, always white.</param> | ||||
|         public void SetGhostMode(bool canPlace) | ||||
|         { | ||||
|             if (_collisionShape != null) | ||||
|                 _collisionShape.Disabled = true; // always disabled in ghost mode | ||||
|  | ||||
|             if (_sprite != null) | ||||
|             { | ||||
|                 // Ghost preview coloring | ||||
|                 _sprite.Modulate = canPlace ? new Color(1, 1, 1, 0.2f) : // white semi-transparent | ||||
|                     new Color(1, 0, 0, 0.2f); // red semi-transparent | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Call when placement is finalized. | ||||
|         /// </summary> | ||||
|         public void FinalizePlacement() | ||||
|         { | ||||
|             if (_collisionShape != null) | ||||
|                 _collisionShape.Disabled = false; | ||||
|  | ||||
|             if (_sprite != null) | ||||
|                 _sprite.Modulate = Colors.White; // reset to normal | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user