diff --git a/HUD.gd b/HUD.gd index cc41bfb..6ae13a8 100644 --- a/HUD.gd +++ b/HUD.gd @@ -16,7 +16,9 @@ func _on_PopupMenu_id_pressed(id): 2: $"../SaveDialog".popup_centered() 4: - $"../SettingsWindow".popup_centered() + $"../SettingsWindow".popup() + 5: + $"../StatsWindow".popup() func _process(delta): elapsed_time += delta # Increment the elapsed time by the frame's delta time @@ -35,3 +37,8 @@ func _on_settings_window_close_requested(): func _on_control_stop_button_pressed(): %Map.controlling=null + +func _on_kill_all_pressed(): + for node in %Map.get_children(): + if node is Player: + node.queue_free() diff --git a/LoadDialog.gd b/LoadDialog.gd index 8194bb6..a9efe79 100644 --- a/LoadDialog.gd +++ b/LoadDialog.gd @@ -29,5 +29,5 @@ func _on_confirmed(): $"../SaveDialog/LineEdit".text=$ItemList.get_item_text(item) var filename = "user://saves/" + $ItemList.get_item_text(item) print("load:", filename) - get_tree().root.get_node("Sim/Map").load_map(filename) + %Map.load_map(filename) break diff --git a/Player.gd b/Player.gd index eea80f5..ba0b0ed 100644 --- a/Player.gd +++ b/Player.gd @@ -2,6 +2,7 @@ class_name Player extends RigidBody2D var health=60 +var can_pickup=true func _integrate_forces(state: PhysicsDirectBodyState2D): var contact_count = state.get_contact_count() @@ -13,6 +14,8 @@ func _integrate_forces(state: PhysicsDirectBodyState2D): handle_pool_collision(collider_object) func handle_player_collision(player: Player): + if not get_tree().root.get_node("Sim/ScreenOverlay/SettingsWindow/VBoxContainer/DropOnColl").is_pressed(): + return if is_carrying() and player.is_carrying(): doubledrop(player) drop() @@ -62,10 +65,11 @@ func drop(): new_pool.mana_r=carrying_r new_pool.mana_g=carrying_g new_pool.mana_b=carrying_b - new_pool.get_node("CollisionShape2D2").disabled=true; + #new_pool.get_node("CollisionShape2D2").disabled=true; carrying_r=0 carrying_g=0 carrying_b=0 + $PickupTimer.start() get_tree().root.get_node("Sim/Map").call_deferred("add_child",new_pool) update() @@ -84,11 +88,24 @@ func doubledrop(player: Player): player.carrying_r=0 player.carrying_g=0 player.carrying_b=0 + can_pickup=false + $PickupTimer.start() + player.can_pickup=false + player.getNode("PickupTimer").start() get_tree().root.get_node("Sim/Map").call_deferred("add_child",new_pool) update() player.update() +func _on_Timer_timeout(): + # This function will be called after 5 seconds + print("Timer finished!") + + + func exchange_with(pool: Pool): + if ! can_pickup: + return + if is_carrying(): pool.mana_r+=carrying_r pool.mana_g+=carrying_g @@ -107,8 +124,10 @@ func exchange_with(pool: Pool): elif pool.mana_b>0: pool.mana_b -= 1 carrying_b=1 + can_pickup=false + $PickupTimer.start() update() - + func update(): var max_value = max(carrying_r, carrying_g, carrying_b) if max_value==0: @@ -143,6 +162,7 @@ func load_data(data): carrying_r=data["r"] carrying_g=data["g"] carrying_b=data["b"] + update() func _on_health_timer_timeout(): if not get_tree().root.get_node("Sim/ScreenOverlay/SettingsWindow/VBoxContainer/Health").is_pressed(): @@ -155,3 +175,7 @@ func _on_health_timer_timeout(): if(health<1): self.queue_free() + + +func _on_pickup_timer_timeout(): + can_pickup=true diff --git a/Pool.gd b/Pool.gd index a6d4470..79954f4 100644 --- a/Pool.gd +++ b/Pool.gd @@ -29,6 +29,59 @@ func _process(_delta): $CollisionShape2D2.disabled=false update() +func pool_coll_check(): + var query_parameters = PhysicsShapeQueryParameters2D.new() + var collision_shape = $CollisionShape2D2.shape + query_parameters.set_shape(collision_shape) + query_parameters.set_transform(Transform2D(0, scale, 0, position)) + query_parameters.set_collision_mask(2) #2=pools + + # Get the Physics2DDirectSpaceState for collision checking + var space_state = get_world_2d().direct_space_state + + # Check for collision + var collision_results = space_state.intersect_shape(query_parameters) + for result in collision_results: + if result.collider is Pool and result.collider != self: + if is_fully_overlapping(self, result.collider): + merge_with(result.collider) + +func is_fully_overlapping(pool1, pool2): + var radius1 = pool1.scale[0]*pool1.get_node("CollisionShape2D2").scale[0]*pool1.get_node("CollisionShape2D2").shape.radius + var radius2 = pool2.scale[0]*pool2.get_node("CollisionShape2D2").scale[0]*pool1.get_node("CollisionShape2D2").shape.radius + var center_distance = pool1.position.distance_to(pool2.position) + + # Check if one circle is completely inside the other + return center_distance <= abs(radius1 - radius2) + +func merge_with(p: Pool): + # Calculate RGB sums for both pools + var sum_rgb_self = mana_r + mana_g + mana_b + var sum_rgb_other = p.mana_r + p.mana_g + p.mana_b + + # Avoid division by zero + var total_sum = sum_rgb_self + sum_rgb_other + if total_sum == 0: + return + + # Calculate weighted positions + var weighted_position_self = position * sum_rgb_self + var weighted_position_other = p.position * sum_rgb_other + + # Compute new position as weighted average + position = (weighted_position_self + weighted_position_other) / total_sum + + # Merge mana values + mana_r += p.mana_r + mana_g += p.mana_g + mana_b += p.mana_b + p.mana_r = 0 + p.mana_g = 0 + p.mana_b = 0 + + #update() + #p.update() + func update(): var max_value: float = max(mana_r, mana_g, mana_b) if max_value==0: @@ -42,6 +95,7 @@ func update(): var s=sqrt((mana_r+mana_g+mana_b)/1000.0) self.scale=Vector2(s,s) self.queue_redraw() # Request to redraw the node + pool_coll_check() func decay(): var new_player = load("res://player.tscn").instantiate() diff --git a/StatsWindow.gd b/StatsWindow.gd new file mode 100644 index 0000000..5966e98 --- /dev/null +++ b/StatsWindow.gd @@ -0,0 +1,43 @@ +extends Window + + +# 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 + + +func _on_timer_timeout(): + var pl=0 + var po=0 + var rpl=0 + var gpl=0 + var bpl=0 + var rpo=0 + var gpo=0 + var bpo=0 + + for node in %Map.get_children(): + if node is Player: + pl+=1 + rpl+=node.carrying_r + gpl+=node.carrying_g + bpl+=node.carrying_b + if node is Pool: + po+=1 + rpo+=node.mana_r + gpo+=node.mana_g + bpo+=node.mana_b + $Label.text=\ + "Players: "+str(pl)+"\n"+ \ + "Pools: "+str(po)+"\n"+ \ + "R: "+str(rpo+rpl)+" ("+str(rpo)+"+"+str(rpl)+")\n"+\ + "G: "+str(gpo+gpl)+" ("+str(gpo)+"+"+str(gpl)+")\n"+\ + "B: "+str(bpo+bpl)+" ("+str(bpo)+"+"+str(bpl)+")\n" + +func _on_close_requested(): + hide() diff --git a/hud.tscn b/hud.tscn index 9a9a0c4..cf799cb 100644 --- a/hud.tscn +++ b/hud.tscn @@ -120,7 +120,7 @@ text = "Radius:" [node name="Radius" type="LineEdit" parent="HBoxContainer/ToolSelect/VBoxContainer/Create Player Circle"] layout_mode = 2 -text = "200" +text = "50" placeholder_text = "0" max_length = 5 @@ -147,6 +147,13 @@ layout_mode = 2 layout_mode = 2 text = "Stop" +[node name="GOD" type="VBoxContainer" parent="HBoxContainer/ToolSelect/VBoxContainer"] +layout_mode = 2 + +[node name="kill all" type="Button" parent="HBoxContainer/ToolSelect/VBoxContainer/GOD"] +layout_mode = 2 +text = "Kill All" + [node name="Debug" type="Label" parent="HBoxContainer"] layout_mode = 2 size_flags_horizontal = 6 @@ -159,7 +166,7 @@ size_flags_horizontal = 10 [node name="File" type="MenuButton" parent="HBoxContainer/Right"] layout_mode = 2 text = "File..." -item_count = 5 +item_count = 6 popup/item_0/text = "New..." popup/item_0/id = 0 popup/item_1/text = "Load..." @@ -171,6 +178,9 @@ popup/item_3/id = 3 popup/item_3/separator = true popup/item_4/text = "Settings..." popup/item_4/id = 4 +popup/item_5/text = "Stats..." +popup/item_5/id = 5 [connection signal="item_selected" from="HBoxContainer/ToolSelect/VBoxContainer/OptionButton" to="HBoxContainer/ToolSelect" method="_on_option_button_item_selected"] [connection signal="pressed" from="HBoxContainer/ToolSelect/VBoxContainer/Control Player/Button" to="." method="_on_control_stop_button_pressed"] +[connection signal="pressed" from="HBoxContainer/ToolSelect/VBoxContainer/GOD/kill all" to="." method="_on_kill_all_pressed"] diff --git a/player.tscn b/player.tscn index 6783eec..0ac25c7 100644 --- a/player.tscn +++ b/player.tscn @@ -24,4 +24,9 @@ shape = SubResource("CircleShape2D_yt706") [node name="HealthTimer" type="Timer" parent="."] autostart = true +[node name="PickupTimer" type="Timer" parent="."] +wait_time = 0.25 +one_shot = true + [connection signal="timeout" from="HealthTimer" to="." method="_on_health_timer_timeout"] +[connection signal="timeout" from="PickupTimer" to="." method="_on_pickup_timer_timeout"] diff --git a/project.godot b/project.godot index c98478c..3497658 100644 --- a/project.godot +++ b/project.godot @@ -67,4 +67,5 @@ escape={ [rendering] +renderer/rendering_method="gl_compatibility" textures/vram_compression/import_etc2_astc=true diff --git a/sim.tscn b/sim.tscn index de1a466..513ecd1 100644 --- a/sim.tscn +++ b/sim.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=8 format=3 uid="uid://bpy475nyq5ea1"] +[gd_scene load_steps=9 format=3 uid="uid://bpy475nyq5ea1"] [ext_resource type="Script" path="res://Map.gd" id="2_rolej"] [ext_resource type="Script" path="res://ScreenShots.gd" id="3_7b3mn"] @@ -7,6 +7,7 @@ [ext_resource type="PackedScene" uid="uid://i5hw0qow332a" path="res://hud.tscn" id="4_u63sk"] [ext_resource type="Script" path="res://LoadDialog.gd" id="6_0mayr"] [ext_resource type="Script" path="res://SaveDialog.gd" id="6_v2wl8"] +[ext_resource type="Script" path="res://StatsWindow.gd" id="7_8peal"] [node name="Sim" type="Node2D"] @@ -54,11 +55,23 @@ placeholder_text = "Filename" [node name="NewDialog" type="ConfirmationDialog" parent="ScreenOverlay"] dialog_text = "Clear current map?" +[node name="StatsWindow" type="Window" parent="ScreenOverlay"] +title = "Stats" +position = Vector2i(15, 320) +size = Vector2i(200, 200) +script = ExtResource("7_8peal") + +[node name="Timer" type="Timer" parent="ScreenOverlay/StatsWindow"] +autostart = true + +[node name="Label" type="Label" parent="ScreenOverlay/StatsWindow"] +offset_right = 40.0 +offset_bottom = 23.0 + [node name="SettingsWindow" type="Window" parent="ScreenOverlay"] title = "Settings" -position = Vector2i(18, 50) -size = Vector2i(300, 200) -visible = false +position = Vector2i(18, 75) +size = Vector2i(250, 200) [node name="VBoxContainer" type="VBoxContainer" parent="ScreenOverlay/SettingsWindow"] offset_right = 123.0 @@ -72,6 +85,10 @@ text = "Decay" layout_mode = 2 text = "Health" +[node name="DropOnColl" type="CheckBox" parent="ScreenOverlay/SettingsWindow/VBoxContainer"] +layout_mode = 2 +text = "Drop on Coll" + [node name="HBoxContainer" type="HBoxContainer" parent="ScreenOverlay/SettingsWindow/VBoxContainer"] layout_mode = 2 @@ -96,6 +113,8 @@ script = ExtResource("3_7b3mn") [connection signal="about_to_popup" from="ScreenOverlay/SaveDialog" to="ScreenOverlay/SaveDialog" method="_on_about_to_popup"] [connection signal="confirmed" from="ScreenOverlay/SaveDialog" to="ScreenOverlay/SaveDialog" method="_on_confirmed"] [connection signal="confirmed" from="ScreenOverlay/NewDialog" to="Map" method="_on_new_dialog_confirmed"] +[connection signal="close_requested" from="ScreenOverlay/StatsWindow" to="ScreenOverlay/StatsWindow" method="_on_close_requested"] +[connection signal="timeout" from="ScreenOverlay/StatsWindow/Timer" to="ScreenOverlay/StatsWindow" method="_on_timer_timeout"] [connection signal="close_requested" from="ScreenOverlay/SettingsWindow" to="ScreenOverlay/HUD" method="_on_settings_window_close_requested"] [connection signal="toggled" from="ScreenOverlay/SettingsWindow/VBoxContainer/HBoxContainer/Screenshots" to="ScreenShots" method="_on_screenshots_toggled"] [connection signal="text_changed" from="ScreenOverlay/SettingsWindow/VBoxContainer/HBoxContainer/Interval" to="ScreenShots" method="_on_interval_text_changed"]