commit dcd005ec26a7f16b181c19b0eabbffd5d1fb9b35
parent 6442cac73e8275c3073e5eb81f05bbbbc79354cb
Author: bsandro <email@bsandro.tech>
Date: Fri, 23 Aug 2024 01:25:27 +0300
Working solution
Diffstat:
5 files changed, 99 insertions(+), 18 deletions(-)
diff --git a/project.godot b/project.godot
@@ -18,6 +18,8 @@ config/icon="res://icon.svg"
[display]
+window/size/viewport_width=1280
+window/size/viewport_height=720
window/stretch/mode="canvas_items"
[rendering]
diff --git a/scenes/Cell.tscn b/scenes/Cell.tscn
@@ -1,6 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://68b4ti6s884b"]
+[gd_scene load_steps=3 format=3 uid="uid://68b4ti6s884b"]
[ext_resource type="Texture2D" uid="uid://dmrfry0b4kavp" path="res://cell_green.png" id="1_k1vbj"]
+[ext_resource type="Script" path="res://scripts/Cell.gd" id="2_uvr0w"]
[node name="Cell" type="Sprite2D"]
texture = ExtResource("1_k1vbj")
+centered = false
+script = ExtResource("2_uvr0w")
diff --git a/scenes/main.tscn b/scenes/main.tscn
@@ -3,6 +3,12 @@
[ext_resource type="Script" path="res://scripts/main.gd" id="1_jly7k"]
[ext_resource type="PackedScene" uid="uid://68b4ti6s884b" path="res://scenes/Cell.tscn" id="2_tjoxl"]
-[node name="Node" type="Node"]
+[node name="Main" type="Node" node_paths=PackedStringArray("tick_timer")]
script = ExtResource("1_jly7k")
cell_scene = ExtResource("2_tjoxl")
+tick_timer = NodePath("TickTimer")
+
+[node name="TickTimer" type="Timer" parent="."]
+wait_time = 0.2
+
+[connection signal="timeout" from="TickTimer" to="." method="_on_tick"]
diff --git a/scripts/Cell.gd b/scripts/Cell.gd
@@ -0,0 +1,11 @@
+class_name Cell
+
+extends Sprite2D
+
+# 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):
+ pass
diff --git a/scripts/main.gd b/scripts/main.gd
@@ -1,27 +1,86 @@
extends Node
+# calculated for 1280x720 window
+const FIELD_W = 25
+const FIELD_H = 14
+
+var cell_w:int
+var cell_h:int
+var field:Array[Array]
@export var cell_scene:PackedScene
-var cell:Node
-var cell_w: int
-var cell_h: int
-var x_mul:int = 1
-var y_mul:int = 1
+@export var tick_timer:Timer
+
+func _init():
+ field.resize(FIELD_H)
+ for y in range(FIELD_H):
+ field[y].resize(FIELD_W)
+ field[y].fill(0)
# Called when the node enters the scene tree for the first time.
func _ready():
- print("ehlo")
- cell = cell_scene.instantiate()
- cell.position = Vector2(randi_range(50, 100), randi_range(50, 100))
+ randomize_field()
+
+ var cell = cell_scene.instantiate()
+ cell.position = Vector2(0, 0)
add_child(cell)
+
cell_w = cell.texture.get_width()
cell_h = cell.texture.get_height()
- print("cell size:", cell_w, cell_h)
+ print("cell size: ", cell_w, "x", cell_h)
+ tick_timer.start()
# Called every frame. 'delta' is the elapsed time since the previous frame.
-func _process(delta):
- cell.position.x += randi_range(1, 2) * x_mul
- cell.position.y += randi_range(1, 2) * y_mul
- if cell.position.x > get_window().size.x-cell_w/2 || cell.position.x < cell_w/2:
- x_mul *= -1
- if cell.position.y > get_window().size.y-cell_h/2 || cell.position.y < cell_h/2:
- y_mul *= -1
+func _process(_delta):
+ pass
+
+func randomize_field():
+ for y in range(FIELD_H):
+ for x in range(FIELD_W):
+ field[y][x] = randi_range(0, 1)
+
+func clear_cells():
+ var children = get_children()
+ for child in children:
+ if child is Cell:
+ remove_child(child)
+
+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)
+
+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
+
+func tick_cell(x:int, y:int):
+ var sum:int = sum_area(x, y)
+ if field[y][x] == 1: # alive cell
+ if sum < 3 || sum > 4: # cell dies
+ return 0
+ else: # cell lives
+ return 1
+ else: # dead cell
+ if sum == 3: # cell comes alive
+ return 1
+ else: # cell stays dead
+ return 0
+
+func sum_area(x:int, y:int):
+ 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];
+ return cnt
+
+func _on_tick():
+ clear_cells()
+ render_field()
+ tick_field()