commit c26b1c6d2c40136f51b915ddf5ca8145735f7e82
parent 9588dffe0351aadcd4243be74114cca2b95c922d
Author: bsandro <email@bsandro.tech>
Date: Mon, 26 Aug 2024 00:07:38 +0300
obvious optimizations - only add cells once, then flip their visibility on demand
Diffstat:
6 files changed, 141 insertions(+), 27 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,2 +1,3 @@
# Godot 4+ specific ignores
.godot/
+out/
diff --git a/export_presets.cfg b/export_presets.cfg
@@ -0,0 +1,102 @@
+[preset.0]
+
+name="Windows Desktop"
+platform="Windows Desktop"
+runnable=true
+dedicated_server=false
+custom_features=""
+export_filter="all_resources"
+include_filter=""
+exclude_filter=""
+export_path="out/conways-life.exe"
+encryption_include_filters=""
+encryption_exclude_filters=""
+encrypt_pck=false
+encrypt_directory=false
+
+[preset.0.options]
+
+custom_template/debug=""
+custom_template/release=""
+debug/export_console_wrapper=1
+binary_format/embed_pck=false
+texture_format/bptc=true
+texture_format/s3tc=true
+texture_format/etc=false
+texture_format/etc2=false
+binary_format/architecture="x86_64"
+codesign/enable=false
+codesign/timestamp=true
+codesign/timestamp_server_url=""
+codesign/digest_algorithm=1
+codesign/description=""
+codesign/custom_options=PackedStringArray()
+application/modify_resources=false
+application/icon=""
+application/console_wrapper_icon=""
+application/icon_interpolation=4
+application/file_version=""
+application/product_version=""
+application/company_name=""
+application/product_name=""
+application/file_description=""
+application/copyright=""
+application/trademarks=""
+application/export_angle=0
+ssh_remote_deploy/enabled=false
+ssh_remote_deploy/host="user@host_ip"
+ssh_remote_deploy/port="22"
+ssh_remote_deploy/extra_args_ssh=""
+ssh_remote_deploy/extra_args_scp=""
+ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
+$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
+$trigger = New-ScheduledTaskTrigger -Once -At 00:00
+$settings = New-ScheduledTaskSettingsSet
+$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
+Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
+Start-ScheduledTask -TaskName godot_remote_debug
+while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
+Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
+ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
+Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
+Remove-Item -Recurse -Force '{temp_dir}'"
+
+[preset.1]
+
+name="Linux/X11"
+platform="Linux/X11"
+runnable=true
+dedicated_server=false
+custom_features=""
+export_filter="all_resources"
+include_filter=""
+exclude_filter=""
+export_path="out/conways-life"
+encryption_include_filters=""
+encryption_exclude_filters=""
+encrypt_pck=false
+encrypt_directory=false
+
+[preset.1.options]
+
+custom_template/debug=""
+custom_template/release=""
+debug/export_console_wrapper=1
+binary_format/embed_pck=true
+texture_format/bptc=true
+texture_format/s3tc=true
+texture_format/etc=false
+texture_format/etc2=false
+binary_format/architecture="x86_64"
+ssh_remote_deploy/enabled=false
+ssh_remote_deploy/host="user@host_ip"
+ssh_remote_deploy/port="22"
+ssh_remote_deploy/extra_args_ssh=""
+ssh_remote_deploy/extra_args_scp=""
+ssh_remote_deploy/run_script="#!/usr/bin/env bash
+export DISPLAY=:0
+unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
+\"{temp_dir}/{exe_name}\" {cmd_args}"
+ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
+kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
+rm -rf \"{temp_dir}\""
diff --git a/project.godot b/project.godot
@@ -20,6 +20,8 @@ config/icon="res://icon.svg"
window/size/viewport_width=1280
window/size/viewport_height=720
+window/size/mode=2
+window/size/resizable=false
window/stretch/mode="canvas_items"
[rendering]
diff --git a/scenes/main.tscn b/scenes/main.tscn
@@ -9,6 +9,6 @@ cell_scene = ExtResource("2_tjoxl")
tick_timer = NodePath("TickTimer")
[node name="TickTimer" type="Timer" parent="."]
-wait_time = 0.1
+wait_time = 0.3
[connection signal="timeout" from="TickTimer" to="." method="_on_tick"]
diff --git a/scripts/Cell.gd b/scripts/Cell.gd
@@ -2,10 +2,20 @@ class_name Cell
extends Sprite2D
+var is_alive:bool = false
+var is_alive_next:bool = false
+
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
-func _process(delta):
+func _process(_delta):
pass
+
+func val():
+ return 1 if is_alive else 0
+
+func update():
+ is_alive = is_alive_next
+ is_alive_next = false
diff --git a/scripts/main.gd b/scripts/main.gd
@@ -1,12 +1,11 @@
extends Node
-# calculated for 1280x720 window
-
var field_w:int
var field_h:int
var cell_w:int
var cell_h:int
var field:Array[Array]
+
@export var cell_scene:PackedScene
@export var tick_timer:Timer
@@ -18,6 +17,7 @@ func _ready():
var cell = cell_scene.instantiate()
cell.position = Vector2(0, 0)
add_child(cell)
+ print("cell is alive:", cell.is_alive)
cell_w = cell.texture.get_width() * cell.transform.get_scale().x
cell_h = cell.texture.get_height() * cell.transform.get_scale().y
@@ -28,10 +28,15 @@ func _ready():
print("field size: ", field_w, "x", field_h)
- field.resize(field_w)
+ field.resize(field_h)
for y in range(field_h):
field[y].resize(field_w)
- field[y].fill(0)
+ for x in range(field_w):
+ field[y][x] = cell_scene.instantiate()
+ field[y][x].position = Vector2(x*cell_w, y*cell_h)
+ add_child(field[y][x])
+
+ remove_child(cell)
randomize_field()
tick_timer.start()
@@ -43,51 +48,45 @@ func _process(_delta):
func randomize_field():
for y in range(field_h):
for x in range(field_w):
- field[y][x] = randi_range(0, 1)
+ field[y][x].is_alive_next = randi_range(0, 1)
-func clear_cells():
- var children = get_children()
- for child in children:
- if child is Cell:
- remove_child(child)
+func update_field():
+ for y in range(field_h):
+ for x in range(field_w):
+ field[y][x].update()
func render_field():
for y in range(field_h):
for x in range(field_w):
- if field[y][x] == 1:
- var cell = cell_scene.instantiate()
- cell.position = Vector2(x*cell_w, y*cell_h)
- add_child(cell)
+ field[y][x].visible = field[y][x].is_alive
func tick_field():
- var field_new:Array[Array] = field.duplicate(true)
for y in range(field_h):
for x in range(field_w):
- field_new[y][x] = tick_cell(x, y)
- field = field_new
+ field[y][x].is_alive_next = tick_cell(x, y)
func tick_cell(x:int, y:int):
var sum:int = sum_area(x, y)
- if field[y][x] == 1: # alive cell
+ if field[y][x].is_alive: # alive cell
if sum < 3 || sum > 4: # cell dies
- return 0
+ return false
else: # cell lives
- return 1
+ return true
else: # dead cell
if sum == 3: # cell comes alive
- return 1
+ return true
else: # cell stays dead
- return 0
+ return false
-func sum_area(x:int, y:int):
+func sum_area(x:int, y:int): # sum 3x3 area all around the cell
var cnt:int = 0;
for xx in range(x-1, x+2):
for yy in range(y-1, y+2):
if xx>=0 && yy>=0 && xx<field_w && yy<field_h:
- cnt += field[yy][xx];
+ cnt += field[yy][xx].val();
return cnt
func _on_tick():
- clear_cells()
+ update_field()
render_field()
tick_field()