From b97ebd793eb17032f3929f307dfe644b17714619 Mon Sep 17 00:00:00 2001 From: altaf-creator Date: Sat, 13 Apr 2024 21:50:12 +0700 Subject: bare bones ai, softlock issues --- Levels/game.tscn | 75 +++++++++++++++++++++++++++++++++++++--- Reusable Scenes/number_node.tscn | 44 +++++++++++------------ Scripts/AI.gd | 37 ++++++++++++++++++++ Scripts/GameLoop.gd | 11 +++++- Scripts/Generator.gd | 43 ++++++++++++++++------- Scripts/GlobalVariables.gd | 1 + Scripts/ModifierLabel.gd | 9 +++++ Scripts/NumberArea.gd | 2 +- Scripts/NumberNode.gd | 39 ++++++++++++++------- Scripts/Player.gd | 6 +++- 10 files changed, 211 insertions(+), 56 deletions(-) create mode 100644 Scripts/AI.gd create mode 100644 Scripts/ModifierLabel.gd diff --git a/Levels/game.tscn b/Levels/game.tscn index e624884..248bdab 100644 --- a/Levels/game.tscn +++ b/Levels/game.tscn @@ -1,33 +1,43 @@ -[gd_scene load_steps=6 format=3 uid="uid://rd1m2fu22g1s"] +[gd_scene load_steps=10 format=3 uid="uid://rd1m2fu22g1s"] [ext_resource type="PackedScene" uid="uid://ccvoi0qmvlxmj" path="res://Reusable Scenes/number_node.tscn" id="1_j877y"] [ext_resource type="Script" path="res://Scripts/Generator.gd" id="1_uaslf"] [ext_resource type="Script" path="res://Scripts/Player.gd" id="3_j3fp5"] [ext_resource type="Script" path="res://Scripts/GameLoop.gd" id="3_u7xnc"] +[ext_resource type="Script" path="res://Scripts/ModifierLabel.gd" id="5_lj1b3"] +[ext_resource type="Script" path="res://Scripts/AI.gd" id="6_ncui2"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_ludyn"] size = Vector2(38, 38) +[sub_resource type="CircleShape2D" id="CircleShape2D_ml6nm"] +radius = 260.83 + +[sub_resource type="CircleShape2D" id="CircleShape2D_4p6y7"] +radius = 120.0 + [node name="MainNode2D" type="Node2D"] [node name="Generator" type="Node" parent="."] script = ExtResource("1_uaslf") numbernode = ExtResource("1_j877y") -min_nodes = 100 +min_nodes = 50 max_nodes = 100 -[node name="GameLoop" type="Node" parent="."] +[node name="GameLoop" type="Node" parent="." node_paths=PackedStringArray("label")] script = ExtResource("3_u7xnc") +turns = 100 +label = NodePath("../Label") [node name="Player" parent="." instance=ExtResource("1_j877y")] z_index = 4096 -position = Vector2(63, 658) +position = Vector2(68, 661) do_scanning = false color = Color(0, 0.329412, 0, 1) [node name="Player" type="Node" parent="Player" node_paths=PackedStringArray("line")] script = ExtResource("3_j3fp5") -max_distance = 300.0 +max_distance = 160.0 line = NodePath("../Line2D") [node name="Line2D" type="Line2D" parent="Player"] @@ -46,4 +56,59 @@ collision_priority = 9999.0 [node name="CollisionShape2D" type="CollisionShape2D" parent="Player/PlayerArea2D"] shape = SubResource("RectangleShape2D_ludyn") +[node name="ModifierLabel" type="Label" parent="Player"] +visible = false +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -31.0 +offset_top = -59.0 +offset_right = 31.0 +offset_bottom = -36.0 +grow_horizontal = 2 +grow_vertical = 0 +text = "+ X" +horizontal_alignment = 1 +vertical_alignment = 1 +script = ExtResource("5_lj1b3") + +[node name="Timer" type="Timer" parent="Player/ModifierLabel"] +wait_time = 2.0 + +[node name="AI" parent="." instance=ExtResource("1_j877y")] +position = Vector2(1207, 52) +do_scanning = false +color = Color(0.917647, 0, 0, 1) + +[node name="AI" type="Node" parent="AI" node_paths=PackedStringArray("shape_cast_original", "shape_cast_skill_issue")] +script = ExtResource("6_ncui2") +shape_cast_original = NodePath("../AIShapeCast2D") +shape_cast_skill_issue = NodePath("../ThisAIHasSkillIssue") + +[node name="ThisAIHasSkillIssue" type="ShapeCast2D" parent="AI"] +modulate = Color(1, 0, 0, 1) +shape = SubResource("CircleShape2D_ml6nm") +target_position = Vector2(0, 0) +collide_with_areas = true + +[node name="AIShapeCast2D" type="ShapeCast2D" parent="AI"] +modulate = Color(1, 0, 1, 1) +shape = SubResource("CircleShape2D_4p6y7") +target_position = Vector2(0, 0) +collide_with_areas = true + +[node name="NumberNode" parent="." instance=ExtResource("1_j877y")] +position = Vector2(95, 551) + +[node name="NumberNode2" parent="." instance=ExtResource("1_j877y")] +position = Vector2(1214, 127) + +[node name="Label" type="Label" parent="."] +offset_right = 40.0 +offset_bottom = 23.0 +text = "Turns Left: X" + [connection signal="input_event" from="Player/PlayerArea2D" to="Player/Player" method="_on_player_area_2d_input_event"] +[connection signal="timeout" from="Player/ModifierLabel/Timer" to="Player/ModifierLabel" method="_on_timer_timeout"] diff --git a/Reusable Scenes/number_node.tscn b/Reusable Scenes/number_node.tscn index 9564505..a10429b 100644 --- a/Reusable Scenes/number_node.tscn +++ b/Reusable Scenes/number_node.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=7 format=3 uid="uid://ccvoi0qmvlxmj"] +[gd_scene load_steps=8 format=3 uid="uid://ccvoi0qmvlxmj"] [ext_resource type="Script" path="res://Scripts/NumberNode.gd" id="1_7p1bu"] [ext_resource type="Texture2D" uid="uid://cckv0u0uvmp6p" path="res://icon.svg" id="2_d46p4"] @@ -11,29 +11,39 @@ size = Vector2(66, 66) radius = 29.41 [sub_resource type="CircleShape2D" id="CircleShape2D_y33cg"] -radius = 130.8 +radius = 100.38 -[node name="NumberNode" type="Node2D" node_paths=PackedStringArray("label", "label_modifier", "sprite", "sprite_modifier")] +[sub_resource type="CircleShape2D" id="CircleShape2D_vk134"] +radius = 120.0 + +[node name="NumberNode" type="Node2D" node_paths=PackedStringArray("label", "sprite", "sprite_modifier")] script = ExtResource("1_7p1bu") label = NodePath("Label") -label_modifier = NodePath("Label2") sprite = NodePath("Sprite2D") sprite_modifier = NodePath("Sprite2D2") -[node name="Area2D" type="Area2D" parent="."] +[node name="NumberArea2D" type="Area2D" parent="."] script = ExtResource("3_2viuw") -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="NumberArea2D"] shape = SubResource("RectangleShape2D_ld6aj") [node name="ShapeCast2D" type="ShapeCast2D" parent="."] shape = SubResource("CircleShape2D_mh4p4") target_position = Vector2(0, 0) +collision_mask = 5 collide_with_areas = true [node name="ShapeCast2D2" type="ShapeCast2D" parent="."] shape = SubResource("CircleShape2D_y33cg") target_position = Vector2(0, 0) +collision_mask = 4 +collide_with_areas = true + +[node name="ShapeCast2D3" type="ShapeCast2D" parent="."] +modulate = Color(1, 0, 1, 1) +shape = SubResource("CircleShape2D_vk134") +target_position = Vector2(0, 0) collide_with_areas = true [node name="Sprite2D" type="Sprite2D" parent="."] @@ -43,8 +53,8 @@ texture = ExtResource("2_d46p4") [node name="Sprite2D2" type="Sprite2D" parent="."] modulate = Color(1, 0, 0, 1) -position = Vector2(19, -17) -scale = Vector2(0.26, 0.11) +position = Vector2(16, -17) +scale = Vector2(0.109375, 0.11) texture = ExtResource("2_d46p4") [node name="Label" type="Label" parent="."] @@ -63,19 +73,5 @@ text = "X" horizontal_alignment = 1 vertical_alignment = 1 -[node name="Label2" type="Label" parent="."] -anchors_preset = 2 -anchor_top = 1.0 -anchor_bottom = 1.0 -offset_left = 3.0 -offset_top = -24.0 -offset_right = 35.0 -offset_bottom = -10.0 -grow_vertical = 0 -theme_override_font_sizes/font_size = 10 -text = "X" -horizontal_alignment = 1 -vertical_alignment = 1 - -[connection signal="mouse_entered" from="Area2D" to="Area2D" method="_on_mouse_entered"] -[connection signal="mouse_exited" from="Area2D" to="Area2D" method="_on_mouse_exited"] +[connection signal="mouse_entered" from="NumberArea2D" to="NumberArea2D" method="_on_mouse_entered"] +[connection signal="mouse_exited" from="NumberArea2D" to="NumberArea2D" method="_on_mouse_exited"] diff --git a/Scripts/AI.gd b/Scripts/AI.gd new file mode 100644 index 0000000..d5cbcbe --- /dev/null +++ b/Scripts/AI.gd @@ -0,0 +1,37 @@ +extends Node +class_name AI + +@export_group("Values") + +@export_group("Scenes") +@export var shape_cast_original : ShapeCast2D +@export var shape_cast_skill_issue: ShapeCast2D + +func _ready(): + GlobalVariables.ai = self + +func step(alternative : bool = false): + var shape_cast : ShapeCast2D + + if !alternative: + shape_cast = shape_cast_original + else: + shape_cast = shape_cast_skill_issue + + shape_cast.force_shapecast_update() + + var nodes : Array[NumberNode] = [] + + print(shape_cast.collision_result) + + for collision in shape_cast.collision_result: + if collision.collider.get_node("..") is NumberNode: + if collision.collider.get_node("..").do_scanning: + nodes.append(collision.collider.get_node("..")) + + nodes.sort_custom(func(a, b): return a.value > b.value) + + if nodes.size() > 0: + nodes[0].join_from($"..") + else: + step(true) diff --git a/Scripts/GameLoop.gd b/Scripts/GameLoop.gd index ea5e157..04cd370 100644 --- a/Scripts/GameLoop.gd +++ b/Scripts/GameLoop.gd @@ -2,10 +2,19 @@ extends Node class_name GameLoop @export var turns : int +@export var label : Label +var current_turns : int = 0 +var prev_turn : int = -1 # Called when the node enters the scene tree for the first time. func _ready(): GlobalVariables.gameloop = self func _process(_delta): - pass + if current_turns >= turns: + label.text = "FINISHED!" + + if prev_turn != current_turns: + prev_turn = current_turns + label.text = "Turns Left: " + str(turns - current_turns) + GlobalVariables.ai.step() diff --git a/Scripts/Generator.gd b/Scripts/Generator.gd index c236f7c..834e07b 100644 --- a/Scripts/Generator.gd +++ b/Scripts/Generator.gd @@ -23,36 +23,54 @@ func generate(): var count : int = randi_range(min_nodes, max_nodes) print(count) + var new_nodes : Array[NumberNode] + for i in count: var is_big : bool = false - if randf() < 0.1: + if randf() < 0.06: is_big = true var new : NumberNode = numbernode.instantiate() if is_big: - new.position = Vector2(randf_range(30, 1250), randf_range(30, 690)) + new.position = Vector2(randf_range(400, 900), randf_range(200, 400)) # disgusting hardcoded values, or not really? else: - new.position = Vector2(randf_range(30, 1250), randf_range(30, 690)) # disgusting hardcoded values, or not really? - + new.position = Vector2(randf_range(30, 1250), randf_range(30, 690)) + get_node(GlobalVariables.NODE).add_child(new) - var shape_cast : ShapeCast2D = new.get_node("ShapeCast2D") - - if !is_big: check_position_and_retry(new, shape_cast, 0) + var shape_cast : ShapeCast2D + + if !is_big: + shape_cast = new.get_node("ShapeCast2D") + else: + new.get_node("NumberArea2D").set_collision_layer_value(1, false) + new.get_node("NumberArea2D").set_collision_layer_value(3, true) + shape_cast = new.get_node("ShapeCast2D2") + + check_position_and_retry(new, shape_cast, 0) new.value = randi_range(0, 10) if is_big: - new.value *= 20 + new.value = new.value + 10 * 5 new.modifier_operation = clamp(abs(roundi(randfn(0, 10))) - 7, 0, 4) - + if new.modifier_operation == NumberNode.Operations.DIVISION: new.modifier = randi_range(1, 3) else: new.modifier = snapped(randf_range(-3, 3), 0.1) - + + if is_big: + new.scale = Vector2(1.4, 1.4) + new.get_node("NumberArea2D").set_collision_layer_value(1, true) + new.get_node("NumberArea2D").set_collision_layer_value(3, true) + new.update_visuals() + #new_nodes.append(new) + + #for n in new_nodes: + # n.softlock_check() func check_position_and_retry(node : NumberNode, shape_cast : ShapeCast2D, tries : int = 0): shape_cast.force_shapecast_update() @@ -60,9 +78,10 @@ func check_position_and_retry(node : NumberNode, shape_cast : ShapeCast2D, tries var collision_count = shape_cast.get_collision_count() print(node.name + " " + str(collision_count)) if collision_count > 1: - node.queue_free() # TODO: failed? screw you! DIE!!!! + node.queue_free() # TODO: failed? screw you! DIE!!!! NO RETRIES FOR YOU, FAILURE #tries += 1 - + tries = tries # compiler won't complain + #node.position = Vector2(randf_range(0, 1280), randf_range(0, 720)) # disgusting hardcoded values, or not really? #shape_cast.position = Vector2.ZERO #shape_cast.global_position = node.global_position diff --git a/Scripts/GlobalVariables.gd b/Scripts/GlobalVariables.gd index 7f8a305..fd7ce6c 100644 --- a/Scripts/GlobalVariables.gd +++ b/Scripts/GlobalVariables.gd @@ -6,4 +6,5 @@ const NODE = "/root/MainNode2D/" var is_snapping : bool = false ## Player, please assign yourself here at _ready(): var player : Player +var ai : AI var gameloop : GameLoop diff --git a/Scripts/ModifierLabel.gd b/Scripts/ModifierLabel.gd new file mode 100644 index 0000000..1a2ed2e --- /dev/null +++ b/Scripts/ModifierLabel.gd @@ -0,0 +1,9 @@ +extends Label + +func pop(txt : String): + visible = true + text = txt + $"Timer".start() + +func _on_timer_timeout(): + visible = false diff --git a/Scripts/NumberArea.gd b/Scripts/NumberArea.gd index 443fada..78fc53f 100644 --- a/Scripts/NumberArea.gd +++ b/Scripts/NumberArea.gd @@ -9,7 +9,7 @@ func _on_mouse_entered(): if !parent.do_scanning: return - if GlobalVariables.is_snapping && GlobalVariables.player.legal: + if GlobalVariables.is_snapping && GlobalVariables.player.legal && GlobalVariables.gameloop.current_turns < GlobalVariables.gameloop.turns: GlobalVariables.player.target = parent func _on_mouse_exited(): diff --git a/Scripts/NumberNode.gd b/Scripts/NumberNode.gd index 41c5d4a..b566781 100644 --- a/Scripts/NumberNode.gd +++ b/Scripts/NumberNode.gd @@ -18,7 +18,6 @@ enum Operations { @export_group("Visuals") @export_subgroup("Visual Nodes") @export var label : Label -@export var label_modifier : Label @export var sprite : Sprite2D @export var sprite_modifier : Sprite2D @export_subgroup("Visual Values") @@ -34,16 +33,22 @@ func _process(_delta): func join_from(node : NumberNode): node.value += self.value - + + var modifier_label = node.get_node_or_null("ModifierLabel") + if self.modifier_operation == Operations.ADDITION: node.value += roundi(self.modifier) + if modifier_label: modifier_label.pop("+ " + str(self.modifier)) if self.modifier_operation == Operations.SUBTRACTION: node.value -= roundi(self.modifier) + if modifier_label: modifier_label.pop("- " + str(self.modifier)) if self.modifier_operation == Operations.MULTIPLICATION: node.value = roundi(float(node.value) * self.modifier) + if modifier_label: modifier_label.pop("* " + str(self.modifier)) if self.modifier_operation == Operations.DIVISION: node.value = roundi(float(node.value) / float(self.modifier)) - + if modifier_label: modifier_label.pop("/ " + str(self.modifier)) + node.position = self.position node.update_visuals() @@ -54,21 +59,31 @@ func update_visuals(): sprite.modulate = color if self.modifier_operation == Operations.ADDITION: - label_modifier.text = "+ " + str(self.modifier) sprite_modifier.visible = true - label_modifier.visible = true if self.modifier_operation == Operations.SUBTRACTION: - label_modifier.text = "- " + str(self.modifier) sprite_modifier.visible = true - label_modifier.visible = true if self.modifier_operation == Operations.MULTIPLICATION: - label_modifier.text = "× " + str(self.modifier) sprite_modifier.visible = true - label_modifier.visible = true if self.modifier_operation == Operations.DIVISION: - label_modifier.text = "÷ " + str(self.modifier) sprite_modifier.visible = true - label_modifier.visible = true if self.modifier_operation == Operations.NONE: sprite_modifier.visible = false - label_modifier.visible = false + +## @deprecated +func softlock_check(): + var shape_cast : ShapeCast2D = $"ShapeCast2D3" # sorry, too lazy to change names! + + shape_cast.force_shapecast_update() + + if shape_cast.get_collision_count() < 2: + print("softlock may happen, " + str(shape_cast.collision_result)) + var pos = Vector2(randf_range(global_position.x - 80, global_position.x + 80), randf_range(global_position.y - 80, global_position.y + 80)) + + var scene : PackedScene = load("res://Reusable Scenes/number_node.tscn") + + var new = scene.instantiate() + new.global_position = pos + new.value = value + + get_node(GlobalVariables.NODE).add_child(new) + new.softlock_check() diff --git a/Scripts/Player.gd b/Scripts/Player.gd index e422ba8..f3b9667 100644 --- a/Scripts/Player.gd +++ b/Scripts/Player.gd @@ -6,8 +6,11 @@ class_name Player var target : NumberNode var legal : bool +var gameloop : GameLoop + func _ready(): GlobalVariables.player = self + gameloop = GlobalVariables.gameloop func _input(event): if GlobalVariables.is_snapping: @@ -25,8 +28,9 @@ func _input(event): if event is InputEventMouseButton && !event.pressed: GlobalVariables.is_snapping = false - if target != null: + if target != null && gameloop.current_turns < gameloop.turns: target.join_from($"..") + gameloop.current_turns += 1 line.points[1] = Vector2.ZERO -- cgit v1.2.3