From 533f3ad38bdbe77b6721abf01a3ee09881503d0d Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Sun, 13 Aug 2023 10:43:18 -0400 Subject: [PATCH] Hide cells instead of creating new instances on every generation --- world.gd | 60 +++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/world.gd b/world.gd index 0a84b76..126d194 100644 --- a/world.gd +++ b/world.gd @@ -39,7 +39,9 @@ var cell_instance var generation: int = 1 var is_paused: int = false var total_living: int = 0 -var world: Array = [] + +var cell_ids: Array = [] # Store cell RIDs +var cell_states: Array = [] func _ready() -> void: @@ -89,11 +91,11 @@ func start_conway() -> void: camera.position.y = world_size.y * cell_size.y / 2 -## Check a cell against the Conway rules and return True if cell shoudl be alive +## Check a cell against the Conway rules and return True if cell should be alive ## The logic in this could be cleaned up pretty easily. Only verbose for understanding. func cell_is_alive(pos: Vector2) -> bool: var neighbors := count_living_neighbors(pos) - var currently_alive = world[pos.x][pos.y] is RID + var currently_alive = cell_states[pos.x][pos.y] == CellStates.ALIVE # Rule 1 - Any live cell with fewer than two live neighbours dies (underpopulation) if currently_alive and neighbors < 2: @@ -124,36 +126,36 @@ func count_living_neighbors(pos: Vector2) -> int: for x in range(x_min, x_max): for y in range(y_min, y_max): if x == pos.x and y == pos.y: continue # Current cell - Don't count - if world[x][y] is RID: + if cell_states[x][y] == CellStates.ALIVE: count += 1 return count -## Loop through the world and create or kill cells depending on rules +## Loop through world to generate cell states, hide/show cells depending on state func process_generation() -> void: if is_paused: return generation += 1 total_living = 0 - var new_world: Array= [] + var rs := RenderingServer + + var new_states: Array= [] for x in range(world_size.x): - new_world.append([]) - new_world[x].resize(world_size.x) + new_states.append([]) + new_states[x].resize(world_size.x) for y in range(world_size.y): var pos = Vector2(x, y) - if cell_is_alive(pos): - total_living += 1 - new_world[x][y] = create_cell(pos) - else: - new_world[x][y] = kill_cell(pos) + var is_alive = cell_is_alive(pos) + total_living += int(is_alive) + new_states[x][y] = int(is_alive) + rs.canvas_item_set_visible(cell_ids[x][y], is_alive) - world = new_world + cell_states = new_states ## Create the cell using the rendering server -func create_cell(pos: Vector2) -> RID: - if world[pos.x][pos.y] is RID: return world[pos.x][pos.y] - +## This is only performed on initial world generation +func create_cell(pos: Vector2, visible_cell: bool = true) -> RID: var rs = RenderingServer cell_instance = rs.canvas_item_create() @@ -166,26 +168,22 @@ func create_cell(pos: Vector2) -> RID: var trans = Transform2D(0, pos_fixed) rs.canvas_item_set_transform(cell_instance, trans) - return cell_instance - -## Remove the cell from the RenderingServer, if it exists -func kill_cell(pos: Vector2) -> CellStates: - if world[pos.x][pos.y] is RID: - RenderingServer.free_rid(world[pos.x][pos.y]) - return CellStates.DEAD + rs.canvas_item_set_visible(cell_instance, visible_cell) + return cell_instance ## Generate the world with cells in random states (alive or dead) func generate_world() -> void: for x in range(world_size.x): - world.append([]) - world[x].resize(world_size.x) + cell_ids.append([]) + cell_ids[x].resize(world_size.x) + cell_states.append([]) + cell_states[x].resize(world_size.x) for y in range(world_size.y): - if randi_range(0, 1): - total_living += 1 - world[x][y] = create_cell(Vector2(x, y)) - else: - world[x][y] = CellStates.DEAD + var is_alive: int = randi_range(0, 1) + total_living += is_alive + cell_states[x][y] = is_alive + cell_ids[x][y] = create_cell(Vector2(x, y), bool(is_alive)) func _on_generation_timer_timeout() -> void: