conways-life

Conways game of life
git clone git://bsandro.tech/conways-life
Log | Files | Refs

commit dcd005ec26a7f16b181c19b0eabbffd5d1fb9b35
parent 6442cac73e8275c3073e5eb81f05bbbbc79354cb
Author: bsandro <email@bsandro.tech>
Date:   Fri, 23 Aug 2024 01:25:27 +0300

Working solution

Diffstat:
Mproject.godot | 2++
Mscenes/Cell.tscn | 5++++-
Mscenes/main.tscn | 8+++++++-
Ascripts/Cell.gd | 11+++++++++++
Mscripts/main.gd | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
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()