- Edited
Hi all,
I am new to Godot and game development more generally, though I have some background in statistical coding. I am attempting to create a game where resources will spawn in within a map, and a player will go around and collect them. I have a tilemaplayer with collisions set up with my player so that he can't run through walls, and I am not trying to instantiate the resource into a scene at a random location without overlapping the player or any walls.
I found some questions that suggested using an Area2D and checking has_overlapping_bodies() or areas, others that suggest using PhysicsShapQueryParameters2D, and more but haven't been able to get one to work.
Some background on the current organization of the game:
I have the Main scene, with a UserInterface that extends control and contains the main gameplay area in its own scene surrounded by HBoxContainers on each side. playarea is the main gameplay scene residing within UserInterface that is a center container, followed by a SubviewportContainer, SubViewport, and the Map TileMapLayer (which currently also houses the player scene in these early stages of building).
In the image below, you can see that the food item is spawning over the top of a wall that has a collision set up. The food collider is on layer 3, player on 2, tilemap on 1. Food masks 1 and 2, Player 1 and 3, and tilemap 2 and 3 so that shouldn't be the issue.
The GDscript on the SubViewport is below:
extends SubViewport
var FoodScene : PackedScene = preload("res://food.tscn")
var _food_collision : CollisionShape2D
var _food : Node
@onready var map : Node = $Map
func _ready() -> void:
ev.spawn_food.connect(_on_spawn_food)
func _on_spawn_food() -> void:
var _food : Node = FoodScene.instantiate()
map.add_child(_food)
_food_collision = _food.get_child(0)
var _food_val : int = 1
_food.position = Vector2(500,500)
print(_food.has_overlapping_bodies(),"bodies?")
print(_food.has_overlapping_areas(),"areas?")
_food.body_entered.connect(_on_food_body_entered.bind(_food_val,_food))
func _on_food_body_entered(body : Node, _food_val : int, _food : Node) -> void :
if body.name == "Player":
gv.food_resource += _food_val
ev.food_updated.emit()
ev.food_consumed.emit()
map.remove_child.call_deferred(_food)
func _physics_process(delta: float) -> void:
if _food:
print(_food.has_overlapping_bodies(),"bodies?")
print(_food.has_overlapping_areas(),"areas?")
Here is the playarea scene to show you how things are setup:
I tried testing has_overlapping in both _physics_process and outside it, but they all return false. Is this because the position is being hardcoded rather than using move and slide or something? Eventually, once I have this working, I will want to be using a blank Area2D to run the check before actually spawning any food.