![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | SawmillTurtle |
I’m currently trying my hand at procedural generation, which is something I’ve never really attempted before. I have a basic scene with a Node as root and a script attached to it. In the script, there is a Room class that (at the present time) is little more than a glorified Rect2. I intend to add more as time goes on, but right now I’m in a bit of a pickle.
I start in the _ready function of my Node script by calling my Room class and generating ten random rooms. I tested this before adding anything else and, indeed, all the rooms appeared in random sizes and at random positions. Once I had this working, I added some code to delete any overlapping rooms. This all goes according to plan, but when I run the game I now see nothing. No rooms. Just a gray background.
I added a dummy function where I call the _draw function on each of my Room objects, which I already know is unnecessary. I did this just so I could do some debugging. When this function is called, it throws an error because it says it’s trying to call previously removed instance:
Attempt to call function ‘_draw’ in base ‘previously freed instance’
on a null instance.
Setting up a breakpoint at the end of the _ready function shows the rooms array with all the instances intact. Their Instance IDs are present and clicking on each one shows me information about them.
Setting up a separate breakpoint at the start of the _process function, however, reveals the root of the problem: the array still has ten rooms, but they all have a value of NULL. Somewhere between _ready and _process, all the instances are being removed. I even made sure to add each instance as a child of the root node to see if that would help, but it did not. Here’s my script for reference:
extends Node
export var minimumSize := Vector2(0,0);
export var maximumSize := Vector2(0,0);
export var minimumPosition := Vector2(0,0);
export var maximumPosition := Vector2(0,0);
var rooms = [];
func _ready():
var instance_count = 0;
while instance_count < 10:
var r : Room = Room.new();
randomize();
var x = floor(rand_range(minimumPosition.x,maximumPosition.x));
var y = floor(rand_range(minimumPosition.y,maximumPosition.y));
var sx = floor(rand_range(minimumSize.x, maximumSize.x));
var sy = floor(rand_range(minimumSize.y, maximumSize.y));
r.pos = Vector2(x,y);
r.size = Vector2(sx,sy);
r.setRect();
if rooms.size() == 0:
rooms.append(r);
instance_count += 1;
for room in rooms:
if not room.checkIntersect(r.rect):
rooms.append(r);
add_child(r); #add to root node in attempt to preserve
instance_count += 1;
else:
r.queue_free();
pass; #added for the purposes of setting up a breakpoint here
func _process(delta):
for room in rooms: #second breakpoint is here
room._draw();
class Room:
extends Node2D
var rect : Rect2;
var pos := Vector2(0,0);
var size := Vector2(0,0);
func generateRoom():
pass;
func setRect():
rect = Rect2(pos, size);
func checkIntersect(var r: Rect2) -> bool:
if rect.intersects(r):
return true;
return false;
func _draw():
draw_rect(rect, Color.white);
Why are all of my instances being deleted? I don’t want them to be deleted! I never ask the engine to delete them. I do, in fact, store them in an array for the sole purpose of preserving them. What am I doing wrong here? Can someone out there lend a helping hand? Please?
I don’t know how you managed to hit those breakpoints as i’m getting into an infinite loop. That’s because you’re appending to an array while iterating over it.
for room in rooms:
rooms.append(r);
That’s a bad practice in programming.
hilfazer | 2020-03-08 20:17
You’re right about that. I hadn’t noticed that I’d done that. I’ll change it, but I’m not hitting an infinite loop. Not sure why. Best to fix it, though. Thanks.
SawmillTurtle | 2020-03-08 20:24