From 9a10e87cb0a300c8b1128657c66ccc7739784418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=A8=E8=90=BD=E5=9F=BA=E5=9B=B4=E8=99=BE?= <3161880837@qq.com> Date: Tue, 26 Aug 2025 17:28:20 +0800 Subject: [PATCH] Add audio effect and implement FireScan bullet behavior - Added Rip.wav audio effect to the project. - Created FireScan bullet script with speed and damage properties. - Implemented basic AI movement for FireScan bullets. - Introduced Wave class for managing enemy waves with dynamic counts and spawning logic. --- components/Abstracts/EntityBase.tscn | 149 ++++++++++++++++++++----- components/Bullets/FireScan.tscn | 14 +++ components/Characters/Chick.tscn | 9 +- components/Characters/Hen.tscn | 2 +- components/Characters/Rooster.tscn | 17 +-- components/Effects/FirePot.tscn | 17 ++- components/Scenes/World.tscn | 22 +--- resources/sounds/effect/Rip.wav | Bin 0 -> 24428 bytes resources/sounds/effect/Rip.wav.import | 24 ++++ scripts/Contents/Bullets/FireScan.gd | 10 ++ scripts/Contents/Characters/Chick.gd | 16 ++- scripts/Contents/Characters/Rooster.gd | 4 + scripts/Contents/Wave.gd | 48 ++++++++ scripts/Statemachine/BulletBase.gd | 2 +- scripts/Statemachine/DamageLabel.gd | 2 +- scripts/Statemachine/EntityBase.gd | 14 +-- scripts/Tools/WorldTool.gd | 3 +- 17 files changed, 283 insertions(+), 70 deletions(-) create mode 100644 components/Bullets/FireScan.tscn create mode 100644 resources/sounds/effect/Rip.wav create mode 100644 resources/sounds/effect/Rip.wav.import create mode 100644 scripts/Contents/Bullets/FireScan.gd create mode 100644 scripts/Contents/Wave.gd diff --git a/components/Abstracts/EntityBase.tscn b/components/Abstracts/EntityBase.tscn index 9049fc5..17003d2 100644 --- a/components/Abstracts/EntityBase.tscn +++ b/components/Abstracts/EntityBase.tscn @@ -1,11 +1,15 @@ -[gd_scene load_steps=13 format=3 uid="uid://cvogxi7mktumf"] +[gd_scene load_steps=17 format=3 uid="uid://cvogxi7mktumf"] [ext_resource type="Script" path="res://scripts/Statemachine/EntityBase.gd" id="1_mvol6"] +[ext_resource type="Texture2D" uid="uid://dwwpkn4q07ja2" path="res://icon.svg" id="2_7lpu0"] [ext_resource type="PackedScene" uid="uid://dcjqjqere8ets" path="res://components/UI/EntityStateBar.tscn" id="2_uje1g"] [sub_resource type="SpriteFrames" id="SpriteFrames_wcqpm"] animations = [{ -"frames": [], +"frames": [{ +"duration": 1.0, +"texture": ExtResource("2_7lpu0") +}], "loop": true, "name": &"idle", "speed": 5.0 @@ -19,22 +23,7 @@ animations = [{ [sub_resource type="CircleShape2D" id="CircleShape2D_buhm1"] radius = 40.0 -[sub_resource type="Animation" id="Animation_3wcjn"] -length = 0.001 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath(".:scale") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector2(1, 1)] -} - -[sub_resource type="Animation" id="Animation_4veur"] +[sub_resource type="Animation" id="Animation_vxanw"] resource_name = "left" tracks/0/type = "value" tracks/0/imported = false @@ -49,7 +38,7 @@ tracks/0/keys = { "values": [Vector2(-1, 1)] } -[sub_resource type="Animation" id="Animation_fgeas"] +[sub_resource type="Animation" id="Animation_nuh11"] resource_name = "left" tracks/0/type = "value" tracks/0/imported = false @@ -64,11 +53,26 @@ tracks/0/keys = { "values": [Vector2(1, 1)] } -[sub_resource type="AnimationLibrary" id="AnimationLibrary_kbmff"] +[sub_resource type="Animation" id="Animation_sxh2u"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:scale") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-1, 1)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_daot2"] _data = { -"RESET": SubResource("Animation_3wcjn"), -"left": SubResource("Animation_4veur"), -"right": SubResource("Animation_fgeas") +"RESET": SubResource("Animation_sxh2u"), +"left": SubResource("Animation_vxanw"), +"right": SubResource("Animation_nuh11") } [sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ao5k4"] @@ -84,6 +88,86 @@ blend_point_1/node = SubResource("AnimationNodeAnimation_611yr") blend_point_1/pos = 1.0 snap = 1.0 +[sub_resource type="Animation" id="Animation_3wcjn"] +length = 0.001 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:modulate:r") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".:modulate:g") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath(".:modulate:b") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(1, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_wl2we"] +resource_name = "hurt" +length = 0.4 +step = 0.1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:modulate:r") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(1, -0.2, 0, 0.2, 0, 10, -0.2, 0, 0.2, 0, 1, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0, 0.2, 0.4) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".:modulate:g") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(1, -0.2, 0, 0.2, 0, 10, -0.2, 0, 0.2, 0, 1, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0, 0.2, 0.4) +} +tracks/2/type = "bezier" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath(".:modulate:b") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(1, -0.2, 0, 0.2, 0, 10, -0.2, 0, 0.2, 0, 1, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0, 0.2, 0.4) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_kbmff"] +_data = { +"RESET": SubResource("Animation_3wcjn"), +"hurt": SubResource("Animation_wl2we") +} + [sub_resource type="CircleShape2D" id="CircleShape2D_34h7q"] [node name="EntityBase" type="CharacterBody2D"] @@ -92,17 +176,18 @@ script = ExtResource("1_mvol6") [node name="sounds" type="Node2D" parent="."] unique_name_in_owner = true -[node name="attack" type="AudioStreamPlayer2D" parent="sounds"] - [node name="sprint" type="AudioStreamPlayer2D" parent="sounds"] [node name="miss" type="AudioStreamPlayer2D" parent="sounds"] [node name="hurt" type="AudioStreamPlayer2D" parent="sounds"] +[node name="attack0" type="AudioStreamPlayer2D" parent="sounds"] + [node name="texture" type="AnimatedSprite2D" parent="."] unique_name_in_owner = true position = Vector2(0, -50) +scale = Vector2(-1, 1) sprite_frames = SubResource("SpriteFrames_wcqpm") animation = &"idle" @@ -113,16 +198,23 @@ unique_name_in_owner = true shape = SubResource("CircleShape2D_buhm1") [node name="animator" type="AnimationPlayer" parent="texture"] +unique_name_in_owner = true libraries = { -"": SubResource("AnimationLibrary_kbmff") +"": SubResource("AnimationLibrary_daot2") } [node name="animatree" type="AnimationTree" parent="texture/animator"] unique_name_in_owner = true -root_node = NodePath("%animatree/../..") +root_node = NodePath("%animator/..") tree_root = SubResource("AnimationNodeBlendSpace1D_51ube") anim_player = NodePath("..") -parameters/blend_position = 1.0 +parameters/blend_position = 1.36 + +[node name="hurtAnimator" type="AnimationPlayer" parent="texture"] +unique_name_in_owner = true +libraries = { +"": SubResource("AnimationLibrary_kbmff") +} [node name="weapons" type="Node2D" parent="texture"] unique_name_in_owner = true @@ -137,4 +229,3 @@ position = Vector2(0, -20) [node name="movebox" type="CollisionShape2D" parent="."] shape = SubResource("CircleShape2D_34h7q") -disabled = true diff --git a/components/Bullets/FireScan.tscn b/components/Bullets/FireScan.tscn new file mode 100644 index 0000000..4f0e5b6 --- /dev/null +++ b/components/Bullets/FireScan.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=4 format=3 uid="uid://db2cbgyyjpydp"] + +[ext_resource type="PackedScene" uid="uid://crtdkysmnkith" path="res://components/Abstracts/BulletBase.tscn" id="1_cqre5"] +[ext_resource type="Script" path="res://scripts/Contents/Bullets/FireScan.gd" id="2_qprdp"] + +[sub_resource type="SegmentShape2D" id="SegmentShape2D_omahd"] +a = Vector2(0, -10) + +[node name="FireScan" instance=ExtResource("1_cqre5")] +script = ExtResource("2_qprdp") +lifeDistance = 200.0 + +[node name="hitbox" parent="." index="1"] +shape = SubResource("SegmentShape2D_omahd") diff --git a/components/Characters/Chick.tscn b/components/Characters/Chick.tscn index b3ade38..1397972 100644 --- a/components/Characters/Chick.tscn +++ b/components/Characters/Chick.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=8 format=3 uid="uid://b0ncrvm8u4pox"] +[gd_scene load_steps=9 format=3 uid="uid://b0ncrvm8u4pox"] [ext_resource type="PackedScene" uid="uid://cvogxi7mktumf" path="res://components/Abstracts/EntityBase.tscn" id="1_goqmy"] [ext_resource type="Script" path="res://scripts/Contents/Characters/Chick.gd" id="2_r6bub"] [ext_resource type="Texture2D" uid="uid://7pkplcqqxvnp" path="res://resources/characters/chick/chick-a.svg" id="2_syddq"] [ext_resource type="Texture2D" uid="uid://dj5dvqb8gsedr" path="res://resources/characters/chick/chick-b.svg" id="3_064jv"] [ext_resource type="AudioStream" uid="uid://b7pxuov1id0ho" path="res://resources/sounds/effect/Pew.mp3" id="3_ik1xf"] +[ext_resource type="AudioStream" uid="uid://bx3n11awokuyd" path="res://resources/sounds/effect/Rip.wav" id="4_oyq2p"] [ext_resource type="PackedScene" uid="uid://dny25qkcvtaa2" path="res://components/Effects/FirePot.tscn" id="6_kvx3n"] [sub_resource type="SpriteFrames" id="SpriteFrames_xji3d"] @@ -34,9 +35,12 @@ script = ExtResource("2_r6bub") cooldownUnit = 200.0 displayName = "小鸡" -[node name="hurt" parent="sounds" index="3"] +[node name="hurt" parent="sounds" index="2"] stream = ExtResource("3_ik1xf") +[node name="attack1" type="AudioStreamPlayer2D" parent="sounds" index="4"] +stream = ExtResource("4_oyq2p") + [node name="texture" parent="." index="1"] position = Vector2(0, -37) sprite_frames = SubResource("SpriteFrames_xji3d") @@ -46,6 +50,7 @@ animation = &"walk" position = Vector2(30, -12) [node name="firepot" parent="texture/weapons/normal" index="0" instance=ExtResource("6_kvx3n")] +unique_name_in_owner = true [node name="statebar" parent="." index="2" node_paths=PackedStringArray("entity")] position = Vector2(0, -82) diff --git a/components/Characters/Hen.tscn b/components/Characters/Hen.tscn index 66ec900..1c7a93a 100644 --- a/components/Characters/Hen.tscn +++ b/components/Characters/Hen.tscn @@ -35,7 +35,7 @@ radius = 40.0 script = ExtResource("2_8u5a0") cooldownUnit = 500.0 -[node name="hurt" parent="sounds" index="3"] +[node name="hurt" parent="sounds" index="2"] stream = ExtResource("3_ojyt7") [node name="texture" parent="." index="1"] diff --git a/components/Characters/Rooster.tscn b/components/Characters/Rooster.tscn index 3f1b563..689dc19 100644 --- a/components/Characters/Rooster.tscn +++ b/components/Characters/Rooster.tscn @@ -38,25 +38,25 @@ radius = 41.0122 script = ExtResource("2_oqdqd") cooldownUnit = 200.0 -[node name="attack" parent="sounds" index="0"] -stream = ExtResource("3_4syso") - -[node name="sprint" parent="sounds" index="1"] +[node name="sprint" parent="sounds" index="0"] stream = ExtResource("4_66s6c") -[node name="miss" parent="sounds" index="2"] +[node name="miss" parent="sounds" index="1"] stream = ExtResource("5_xnbhq") -[node name="hurt" parent="sounds" index="3"] +[node name="hurt" parent="sounds" index="2"] stream = ExtResource("6_nmmw2") +[node name="attack0" parent="sounds" index="3"] +stream = ExtResource("3_4syso") + [node name="texture" parent="." index="1"] position = Vector2(0, -70) sprite_frames = SubResource("SpriteFrames_4v2ol") animation = &"walk" [node name="hitbox" parent="texture/hurtbox" index="0"] -position = Vector2(12, 16) +position = Vector2(0, 30) shape = SubResource("CircleShape2D_h1v0q") [node name="normal" type="Node2D" parent="texture/weapons" index="0"] @@ -65,3 +65,6 @@ position = Vector2(54, -45) [node name="statebar" parent="." index="2" node_paths=PackedStringArray("entity")] position = Vector2(0, -151) entity = NodePath("..") + +[node name="movebox" parent="." index="3"] +disabled = true diff --git a/components/Effects/FirePot.tscn b/components/Effects/FirePot.tscn index 741fa47..31171ca 100644 --- a/components/Effects/FirePot.tscn +++ b/components/Effects/FirePot.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://dny25qkcvtaa2"] +[gd_scene load_steps=13 format=3 uid="uid://dny25qkcvtaa2"] [ext_resource type="PackedScene" uid="uid://bcvuuy2m0pke0" path="res://components/Abstracts/EffectBase.tscn" id="1_k7ukc"] @@ -22,6 +22,15 @@ colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1) [sub_resource type="GradientTexture1D" id="GradientTexture1D_miml8"] gradient = SubResource("Gradient_g8be5") +[sub_resource type="Curve" id="Curve_iaern"] +min_value = -200.0 +max_value = 200.0 +_data = [Vector2(0, -200), 0.0, 0.0, 0, 0, Vector2(1, 200), 0.0, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="CurveTexture" id="CurveTexture_1flsn"] +curve = SubResource("Curve_iaern") + [sub_resource type="Curve" id="Curve_qy5ym"] _data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0] point_count = 2 @@ -33,11 +42,13 @@ curve = SubResource("Curve_qy5ym") particle_flag_disable_z = true angle_min = 1.07288e-05 angle_max = 360.0 -direction = Vector3(0, -1, 0) spread = 15.0 initial_velocity_min = 10.0 -initial_velocity_max = 300.0 +initial_velocity_max = 500.0 gravity = Vector3(0, 0, 0) +linear_accel_min = -2.23517e-06 +linear_accel_max = -2.23517e-06 +linear_accel_curve = SubResource("CurveTexture_1flsn") scale_min = 2.0 scale_max = 12.0 scale_over_velocity_curve = SubResource("CurveTexture_wcx7i") diff --git a/components/Scenes/World.tscn b/components/Scenes/World.tscn index 6e7adcd..5581788 100644 --- a/components/Scenes/World.tscn +++ b/components/Scenes/World.tscn @@ -1,10 +1,8 @@ -[gd_scene load_steps=7 format=3 uid="uid://dmxi1ikn6avig"] +[gd_scene load_steps=5 format=3 uid="uid://dmxi1ikn6avig"] [ext_resource type="Script" path="res://scripts/Tools/WorldTool.gd" id="1_t2xvy"] [ext_resource type="PackedScene" uid="uid://dfwg750a47ggx" path="res://components/Scenes/UI.tscn" id="2_04cdd"] [ext_resource type="PackedScene" uid="uid://bm7ymrri6pykb" path="res://components/Characters/Rooster.tscn" id="3_5ui6q"] -[ext_resource type="PackedScene" uid="uid://b0ncrvm8u4pox" path="res://components/Characters/Chick.tscn" id="4_tnil0"] -[ext_resource type="PackedScene" uid="uid://c8h1abpbe6cww" path="res://components/Characters/Hen.tscn" id="5_i6i4p"] [ext_resource type="Texture2D" uid="uid://ckk8kahhof06u" path="res://resources/maps/Castle 2.png" id="6_p0nkj"] [node name="world" type="Node2D"] @@ -13,6 +11,11 @@ script = ExtResource("1_t2xvy") [node name="UI" parent="." instance=ExtResource("2_04cdd")] +[node name="background" type="Sprite2D" parent="."] +z_index = -1 +position = Vector2(468, 320) +texture = ExtResource("6_p0nkj") + [node name="rooster" parent="." groups=["players"] instance=ExtResource("3_5ui6q")] position = Vector2(394, 274) @@ -20,16 +23,3 @@ position = Vector2(394, 274) position = Vector2(0, -100) process_callback = 0 position_smoothing_enabled = true - -[node name="hen" parent="." groups=["mobs"] instance=ExtResource("5_i6i4p")] -position = Vector2(210, 455) -displayName = "母鸡" - -[node name="Chick" parent="." instance=ExtResource("4_tnil0")] -position = Vector2(788, 513) -isBoss = true - -[node name="Castle2" type="Sprite2D" parent="."] -z_index = -1 -position = Vector2(468, 320) -texture = ExtResource("6_p0nkj") diff --git a/resources/sounds/effect/Rip.wav b/resources/sounds/effect/Rip.wav new file mode 100644 index 0000000000000000000000000000000000000000..ae1e3d0d30a0127c9061b2188db45a3dfd356ec3 GIT binary patch literal 24428 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 Wave: + var wave = Wave.new() + wave.entity = entity_ + wave.minCount = minCount_ + wave.maxCount = maxCount_ + wave.isBoss = isBoss_ + wave.from = from_ + wave.to = to_ + wave.per = per_ + return wave +static func entityCountOf(wave: Wave) -> int: + if wave.from <= current and wave.to >= current and int(current - wave.from) % wave.per == 0: + print("abc") + return randi_range(int(wave.minCount), int(wave.maxCount * ((1 + countBoost) ** current))) + return 0 +static func spawn(): + for i in range(len(data)): + var wave = data[i] + for j in range(entityCountOf(wave)): + EntityBase.generate(wave.entity, MathTool.randv2_range(500), true, wave.isBoss) +static func next(): + spawn() + current += 1 diff --git a/scripts/Statemachine/BulletBase.gd b/scripts/Statemachine/BulletBase.gd index b7d5178..1c98407 100644 --- a/scripts/Statemachine/BulletBase.gd +++ b/scripts/Statemachine/BulletBase.gd @@ -58,5 +58,5 @@ static func generate( instance.position = spawnPosition instance.rotation = spawnRotation if addToWorld: - WorldTool.rootNode.add_child(instance) + WorldManager.rootNode.add_child(instance) return instance diff --git a/scripts/Statemachine/DamageLabel.gd b/scripts/Statemachine/DamageLabel.gd index 6ad40f3..fe3e2c0 100644 --- a/scripts/Statemachine/DamageLabel.gd +++ b/scripts/Statemachine/DamageLabel.gd @@ -22,5 +22,5 @@ static func create(spawnDamage: float, spawnCrit: bool, spawnPosition: Vector2, instance.crit = spawnCrit instance.position = spawnPosition if addToWorld: - WorldTool.rootNode.add_child(instance) + WorldManager.rootNode.add_child(instance) return instance diff --git a/scripts/Statemachine/EntityBase.gd b/scripts/Statemachine/EntityBase.gd index 492888a..61851e5 100644 --- a/scripts/Statemachine/EntityBase.gd +++ b/scripts/Statemachine/EntityBase.gd @@ -21,6 +21,7 @@ var fields = { @onready var hurtbox: Area2D = $"%hurtbox" @onready var statebar: EntityStateBar = $"%statebar" @onready var sounds: Node2D = $"%sounds" +@onready var hurtAnimator: AnimationPlayer = $"%hurtAnimator" var health: float = 0 @@ -57,6 +58,7 @@ func move(direction: Vector2, isSprinting: bool = false): if currentDirection != 0: lastDirection = currentDirection func takeDamage(bullet: BulletBase, crit: bool): + hurtAnimator.play("hurt") var baseDamage: float = bullet.fields.get(FieldStore.Bullet.DAMAGE) * randf_range(1 - GameRule.damageOffset, 1 + GameRule.damageOffset) var damage = baseDamage + baseDamage * int(crit) * fields.get(FieldStore.Entity.CRIT_DAMAGE) if sprinting: @@ -82,7 +84,7 @@ func startCooldown(): func tryAttack(type: int): var state = startCooldown() if state: - playSound("attack") + playSound("attack" + str(type)) attack(type) return state func trySprint(): @@ -125,17 +127,15 @@ func sprint(): static func generate( entity: PackedScene, spawnPosition: Vector2, - spawnRotation: float, isMob: bool = true, spawnAsBoss: bool = false, - addtoWorld: bool = true + addToWorld: bool = true ): - var instance: EntityBase = entity.instance() + var instance: EntityBase = entity.instantiate() instance.position = spawnPosition - instance.rotation = spawnRotation instance.isBoss = spawnAsBoss if isMob: instance.add_to_group("mobs") - if addtoWorld: - WorldTool.rootNode.add_child(instance) + if addToWorld: + WorldManager.rootNode.add_child(instance) return instance diff --git a/scripts/Tools/WorldTool.gd b/scripts/Tools/WorldTool.gd index ee69dc3..42ae300 100644 --- a/scripts/Tools/WorldTool.gd +++ b/scripts/Tools/WorldTool.gd @@ -1,5 +1,5 @@ extends Node2D -class_name WorldTool +class_name WorldManager static var rootNode: Node2D static var tree: SceneTree @@ -7,3 +7,4 @@ static var tree: SceneTree func _ready(): tree = get_tree() rootNode = self + Wave.next()