Browse Source

Hide cells instead of creating new instances on every generation

pull/1/head
Ryan Reed 1 year ago
parent
commit
533f3ad38b
1 changed files with 29 additions and 31 deletions
  1. +29
    -31
      world.gd

+ 29
- 31
world.gd View File

@ -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:


Loading…
Cancel
Save