1
1
mirror of https://github.com/Rundll86/Dog-Lynx-And-HCN.git synced 2026-05-28 06:51:54 +08:00

feat: 新增角色系统及基础功能实现

新增HCN、Lynx和MuyangDog三个可玩角色及其相关资源
实现角色选择界面和角色属性系统
重构玩家生成逻辑以支持角色选择
优化角色卡片UI显示效果
This commit is contained in:
2026-05-04 21:34:57 +08:00
parent 4d1f68cac1
commit dc4b080a09
23 changed files with 362 additions and 48 deletions
+34 -13
View File
@@ -1,15 +1,14 @@
[gd_scene format=3 uid="uid://m8a4nay1pmmg"]
[ext_resource type="Script" uid="uid://cd1xb8m6rvoph" path="res://scripts/Structs/Character.gd" id="1_dt83t"]
[ext_resource type="Texture2D" uid="uid://dwwpkn4q07ja2" path="res://icon.svg" id="2_dt83t"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5td0u"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dt83t"]
content_margin_left = 20.0
content_margin_top = 20.0
content_margin_right = 20.0
content_margin_bottom = 20.0
bg_color = Color(0, 0, 0, 0.8)
border_width_top = 10
border_width_bottom = 10
border_color = Color(1, 1, 1, 1)
border_blend = true
corner_radius_top_left = 15
@@ -20,9 +19,12 @@ corner_detail = 1
font_size = 20
outline_size = 1
[sub_resource type="LabelSettings" id="LabelSettings_fnmic"]
font_size = 12
font_color = Color(1, 1, 1, 0.39215687)
[sub_resource type="LabelSettings" id="LabelSettings_myhk0"]
font_size = 12
font_color = Color(0.5, 0.5, 0.5, 1)
[sub_resource type="Animation" id="Animation_dt83t"]
length = 0.001
@@ -34,7 +36,7 @@ tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0.7, -0.25, 0, 0.25, 0),
"points": PackedFloat32Array(0.85, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
tracks/1/type = "bezier"
@@ -45,7 +47,7 @@ tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0.7, -0.25, 0, 0.25, 0),
"points": PackedFloat32Array(0.85, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
tracks/2/type = "value"
@@ -85,7 +87,7 @@ tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0, 0),
"points": PackedFloat32Array(1, 0, 0, 0, -0.3, 0.7, 0, 0, 0, 0),
"points": PackedFloat32Array(1, 0, 0, 0, -0.3, 0.85, 0, 0, 0, 0),
"times": PackedFloat32Array(0, 0.5)
}
tracks/1/type = "bezier"
@@ -96,7 +98,7 @@ tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(2, 0),
"points": PackedFloat32Array(1, 0, 0, 0, -0.3, 0.7, 0, 0, 0, 0),
"points": PackedFloat32Array(1, 0, 0, 0, -0.3, 0.85, 0, 0, 0, 0),
"times": PackedFloat32Array(0, 0.5)
}
tracks/2/type = "value"
@@ -136,7 +138,7 @@ tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0, 0),
"points": PackedFloat32Array(0.7, 0, 0, 0, 0.3, 1, 0, 0, 0, 0),
"points": PackedFloat32Array(0.85, 0, 0, 0, 0.3, 1, 0, 0, 0, 0),
"times": PackedFloat32Array(0, 0.5)
}
tracks/1/type = "bezier"
@@ -147,7 +149,7 @@ tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(0, 0),
"points": PackedFloat32Array(0.7, 0, 0, 0, 0.3, 1, 0, 0, 0, 0),
"points": PackedFloat32Array(0.85, 0, 0, 0, 0.3, 1, 0, 0, 0, 0),
"times": PackedFloat32Array(0, 0.5)
}
tracks/2/type = "value"
@@ -186,9 +188,13 @@ _data = {
modulate = Color(1, 1, 1, 0.5)
offset_right = 226.0
offset_bottom = 212.0
scale = Vector2(0.7, 0.7)
theme_override_styles/panel = SubResource("StyleBoxFlat_5td0u")
scale = Vector2(0.85, 0.85)
theme_override_styles/panel = SubResource("StyleBoxFlat_dt83t")
script = ExtResource("1_dt83t")
avatar = ExtResource("2_dt83t")
description = "这是一个描述,"
fields = Array[int]([0])
fieldValues = Array[float]([0.0])
[node name="wrapper" type="VBoxContainer" parent="." unique_id=2023039659]
layout_mode = 2
@@ -200,24 +206,39 @@ custom_minimum_size = Vector2(100, 100)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
texture = ExtResource("2_dt83t")
expand_mode = 1
stretch_mode = 5
[node name="infoContainer" type="VBoxContainer" parent="wrapper" unique_id=143242635]
layout_mode = 2
theme_override_constants/separation = 10
[node name="nameLabel" type="Label" parent="wrapper/infoContainer" unique_id=516147781]
[node name="VBoxContainer" type="VBoxContainer" parent="wrapper/infoContainer" unique_id=533915880]
layout_mode = 2
theme_override_constants/separation = 0
[node name="nameLabel" type="Label" parent="wrapper/infoContainer/VBoxContainer" unique_id=516147781]
unique_name_in_owner = true
layout_mode = 2
text = "Unknown Character"
label_settings = SubResource("LabelSettings_dt83t")
horizontal_alignment = 1
[node name="sloganLabel" type="Label" parent="wrapper/infoContainer/VBoxContainer" unique_id=280562204]
unique_name_in_owner = true
layout_mode = 2
text = "“Slogan”"
label_settings = SubResource("LabelSettings_fnmic")
horizontal_alignment = 1
[node name="descriptionLabel" type="Label" parent="wrapper/infoContainer" unique_id=808054282]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 10)
layout_mode = 2
text = "这是一个描述,"
label_settings = SubResource("LabelSettings_myhk0")
horizontal_alignment = 1
autowrap_mode = 3
[node name="fields" type="VBoxContainer" parent="wrapper" unique_id=437152370]
+129
View File
@@ -0,0 +1,129 @@
[gd_scene format=3 uid="uid://bs863g2s8r770"]
[ext_resource type="PackedScene" uid="uid://cvogxi7mktumf" path="res://components/Abstracts/EntityBase.tscn" id="1_6i3xq"]
[ext_resource type="Script" uid="uid://r5gm7rcya35p" path="res://scripts/Contents/Characters/PlayerBase.gd" id="2_t2kq6"]
[ext_resource type="AudioStream" uid="uid://cdrevrq7n6yqa" path="res://resources/sounds/effect/Boing.mp3" id="3_lv2jw"]
[ext_resource type="AudioStream" uid="uid://benyec5bqni0b" path="res://resources/sounds/effect/Chomp.wav" id="4_7bgj3"]
[ext_resource type="AudioStream" uid="uid://dmxh3bpk8vyy5" path="res://resources/sounds/effect/Coin.mp3" id="5_na3ea"]
[ext_resource type="AudioStream" uid="uid://4wuuf1osk0yv" path="res://resources/sounds/effect/Low Boing.wav" id="6_0o8ke"]
[ext_resource type="Texture2D" uid="uid://dwwpkn4q07ja2" path="res://icon.svg" id="7_kwh6m"]
[sub_resource type="Curve" id="Curve_da2ca"]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveTexture" id="CurveTexture_0omr3"]
curve = SubResource("Curve_da2ca")
[sub_resource type="Curve" id="Curve_joj4g"]
_limits = [-360.0, 1.0, 0.0, 1.0]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, -360), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveTexture" id="CurveTexture_jluqw"]
curve = SubResource("Curve_joj4g")
[sub_resource type="Curve" id="Curve_0omr3"]
_data = [Vector2(0.5, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveTexture" id="CurveTexture_joj4g"]
curve = SubResource("Curve_0omr3")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_joj4g"]
particle_flag_disable_z = true
emission_shape = 1
emission_sphere_radius = 300.0
angle_min = 1.0728835e-05
angle_max = 360.00003
angle_curve = SubResource("CurveTexture_jluqw")
gravity = Vector3(0, 0, 0)
radial_accel_min = -200.0
radial_accel_max = -200.0
scale_min = 5.0
scale_max = 10.0
scale_curve = SubResource("CurveTexture_joj4g")
alpha_curve = SubResource("CurveTexture_0omr3")
[sub_resource type="SpriteFrames" id="SpriteFrames_4v2ol"]
animations = [{
"frames": [],
"loop": true,
"name": &"idle",
"speed": 1.0
}, {
"frames": [],
"loop": true,
"name": &"walk",
"speed": 3.0
}]
[sub_resource type="SpriteFrames" id="SpriteFrames_jluqw"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": ExtResource("7_kwh6m")
}],
"loop": true,
"name": &"idle",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": ExtResource("7_kwh6m")
}],
"loop": true,
"name": &"walk",
"speed": 5.0
}]
[sub_resource type="CircleShape2D" id="CircleShape2D_h1v0q"]
radius = 61.204575
[node name="PlayerBase" unique_id=1711205167 instance=ExtResource("1_6i3xq")]
script = ExtResource("2_t2kq6")
displayName = "玩家实体"
metadata/_edit_horizontal_guides_ = [-188.0]
metadata/_edit_vertical_guides_ = [71.0]
[node name="chargeParticle" type="GPUParticles2D" parent="." index="0" unique_id=1592717470]
unique_name_in_owner = true
position = Vector2(0, -54)
amount = 100
process_material = SubResource("ParticleProcessMaterial_joj4g")
[node name="weaponStore" parent="." index="2"]
process_mode = 4
[node name="sprint" parent="sounds" index="0"]
stream = ExtResource("3_lv2jw")
[node name="heal" parent="sounds" index="1"]
stream = ExtResource("4_7bgj3")
[node name="miss" parent="sounds" index="2"]
stream = ExtResource("5_na3ea")
[node name="hurt" parent="sounds" index="3"]
stream = ExtResource("6_0o8ke")
[node name="texture" parent="." index="4"]
position = Vector2(0, -47)
sprite_frames = SubResource("SpriteFrames_4v2ol")
animation = &"walk"
[node name="staticAnimation" parent="texture" index="1"]
position = Vector2(0, -17)
sprite_frames = SubResource("SpriteFrames_jluqw")
animation = &"walk"
[node name="hitbox" parent="texture/hurtbox" index="0"]
position = Vector2(-2, -18)
shape = SubResource("CircleShape2D_h1v0q")
[node name="normal" type="Node2D" parent="texture/weapons" index="0" unique_id=1939030218]
position = Vector2(1, -13)
[node name="statebar" parent="." index="5" node_paths=PackedStringArray("entity")]
position = Vector2(0, -150)
entity = NodePath("..")
+10 -5
View File
@@ -3,7 +3,7 @@
[ext_resource type="PackedScene" uid="uid://m8a4nay1pmmg" path="res://components/Abstracts/CharacterCardBase.tscn" id="1_robpf"]
[ext_resource type="Texture2D" uid="uid://2xmrkvyrcqq1" path="res://resources/characterCards/hcn.png" id="2_1yfsg"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_82b7n"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1yfsg"]
content_margin_left = 20.0
content_margin_top = 20.0
content_margin_right = 20.0
@@ -16,18 +16,23 @@ corner_radius_bottom_right = 15
corner_detail = 1
[node name="HCN" unique_id=1046363300 instance=ExtResource("1_robpf")]
theme_override_styles/panel = SubResource("StyleBoxFlat_82b7n")
theme_override_styles/panel = SubResource("StyleBoxFlat_1yfsg")
displayName = "氰化氢"
slogan = "微量便可颠覆生机"
avatar = ExtResource("2_1yfsg")
description = "苦杏仁气息的致命剧毒物质,暗藏致命威能。触碰即引凶险,微量便可颠覆生机,是隐忍又致命的诡秘造物。"
description = "召唤物死亡时为自身恢复生命值。"
fields = Array[int]([18, 27])
fieldValues = Array[float]([5.0, 1.0])
clickToRebuild = true
[node name="avatarTexture" parent="wrapper" parent_id_path=PackedInt32Array(2023039659) index="0" unique_id=1334645594]
texture = ExtResource("2_1yfsg")
[node name="nameLabel" parent="wrapper/infoContainer" parent_id_path=PackedInt32Array(143242635) index="0" unique_id=516147781]
[node name="nameLabel" parent="wrapper/infoContainer/VBoxContainer" parent_id_path=PackedInt32Array(533915880) index="0" unique_id=516147781]
text = "氰化氢"
[node name="sloganLabel" parent="wrapper/infoContainer/VBoxContainer" parent_id_path=PackedInt32Array(533915880) index="1" unique_id=280562204]
text = "“微量便可颠覆生机”"
[node name="descriptionLabel" parent="wrapper/infoContainer" parent_id_path=PackedInt32Array(143242635) index="1" unique_id=808054282]
text = "苦杏仁气息的致命剧毒物质,暗藏致命威能。触碰即引凶险,微量便可颠覆生机,是隐忍又致命的诡秘造物。"
text = "召唤物死亡时为自身恢复生命值。"
+10 -6
View File
@@ -3,7 +3,7 @@
[ext_resource type="PackedScene" uid="uid://m8a4nay1pmmg" path="res://components/Abstracts/CharacterCardBase.tscn" id="1_xa4jc"]
[ext_resource type="Texture2D" uid="uid://b1ogllqvamcun" path="res://resources/characterCards/lynx.png" id="2_1s675"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_wckn2"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1s675"]
content_margin_left = 20.0
content_margin_top = 20.0
content_margin_right = 20.0
@@ -16,19 +16,23 @@ corner_radius_bottom_right = 15
corner_detail = 1
[node name="Lynx" unique_id=1046363300 instance=ExtResource("1_xa4jc")]
theme_override_styles/panel = SubResource("StyleBoxFlat_wckn2")
theme_override_styles/panel = SubResource("StyleBoxFlat_1s675")
displayName = "猞猁"
slogan = "栖于寒域密林,孤影独行世间"
avatar = ExtResource("2_1s675")
description = "栖于寒域密林,生性冷傲孤高。诡秘警觉过人,向来独来独往。身负隐秘过往,不问世俗纷争,只以孤影独行世间。"
description = "拥有更大的冲刺速度。"
fields = Array[int]([3, 4, 10])
fieldValues = Array[float]([0.15, 0.06, -0.25])
fieldValues = Array[float]([0.15, 0.04, -0.3])
clickToRebuild = true
[node name="avatarTexture" parent="wrapper" parent_id_path=PackedInt32Array(2023039659) index="0" unique_id=1334645594]
texture = ExtResource("2_1s675")
[node name="nameLabel" parent="wrapper/infoContainer" parent_id_path=PackedInt32Array(143242635) index="0" unique_id=516147781]
[node name="nameLabel" parent="wrapper/infoContainer/VBoxContainer" parent_id_path=PackedInt32Array(533915880) index="0" unique_id=516147781]
text = "猞猁"
[node name="sloganLabel" parent="wrapper/infoContainer/VBoxContainer" parent_id_path=PackedInt32Array(533915880) index="1" unique_id=280562204]
text = "“栖于寒域密林,孤影独行世间”"
[node name="descriptionLabel" parent="wrapper/infoContainer" parent_id_path=PackedInt32Array(143242635) index="1" unique_id=808054282]
text = "栖于寒域密林,生性冷傲孤高。诡秘警觉过人,向来独来独往。身负隐秘过往,不问世俗纷争,只以孤影独行世间。"
text = "拥有更大的冲刺速度。"
+9 -5
View File
@@ -3,7 +3,7 @@
[ext_resource type="PackedScene" uid="uid://m8a4nay1pmmg" path="res://components/Abstracts/CharacterCardBase.tscn" id="1_wq25g"]
[ext_resource type="Texture2D" uid="uid://dhu4i24hfhxvn" path="res://resources/characterCards/muyang-dog.png" id="2_fi2nw"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_orlvy"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fi2nw"]
content_margin_left = 20.0
content_margin_top = 20.0
content_margin_right = 20.0
@@ -15,10 +15,11 @@ corner_radius_bottom_right = 15
corner_detail = 1
[node name="MuyangDog" unique_id=1046363300 instance=ExtResource("1_wq25g")]
theme_override_styles/panel = SubResource("StyleBoxFlat_orlvy")
theme_override_styles/panel = SubResource("StyleBoxFlat_fi2nw")
displayName = "牧羊犬"
slogan = "以身挡险,恪守使命不离不弃"
avatar = ExtResource("2_fi2nw")
description = "恪守守护之责,性情沉稳忠诚。常年驻守边境旷野,坚守一方安宁,甘愿以身挡险,永远守护同伴与故土,恪守使命不离不弃。"
description = "每5秒发动格挡,弹反一切子弹。"
fields = Array[int]([0, 8, 3])
fieldValues = Array[float]([50.0, 0.15, -0.2])
clickToRebuild = true
@@ -26,8 +27,11 @@ clickToRebuild = true
[node name="avatarTexture" parent="wrapper" parent_id_path=PackedInt32Array(2023039659) index="0" unique_id=1334645594]
texture = ExtResource("2_fi2nw")
[node name="nameLabel" parent="wrapper/infoContainer" parent_id_path=PackedInt32Array(143242635) index="0" unique_id=516147781]
[node name="nameLabel" parent="wrapper/infoContainer/VBoxContainer" parent_id_path=PackedInt32Array(533915880) index="0" unique_id=516147781]
text = "牧羊犬"
[node name="sloganLabel" parent="wrapper/infoContainer/VBoxContainer" parent_id_path=PackedInt32Array(533915880) index="1" unique_id=280562204]
text = "“以身挡险,恪守使命不离不弃”"
[node name="descriptionLabel" parent="wrapper/infoContainer" parent_id_path=PackedInt32Array(143242635) index="1" unique_id=808054282]
text = "恪守守护之责,性情沉稳忠诚。常年驻守边境旷野,坚守一方安宁,甘愿以身挡险,永远守护同伴与故土,恪守使命不离不弃。"
text = "每5秒发动格挡,弹反一切子弹。"
+8
View File
@@ -0,0 +1,8 @@
[gd_scene format=3 uid="uid://bes88ipm71b75"]
[ext_resource type="PackedScene" uid="uid://bs863g2s8r770" path="res://components/Abstracts/PlayerBase.tscn" id="1_eeneu"]
[ext_resource type="Script" uid="uid://bevc4f6apql4t" path="res://scripts/Contents/Characters/HCN.gd" id="2_f7uj3"]
[node name="HCN" unique_id=1711205167 instance=ExtResource("1_eeneu")]
script = ExtResource("2_f7uj3")
displayName = "氰化氢"
+8
View File
@@ -0,0 +1,8 @@
[gd_scene format=3 uid="uid://ben3wi047p3hj"]
[ext_resource type="PackedScene" uid="uid://bs863g2s8r770" path="res://components/Abstracts/PlayerBase.tscn" id="1_ns0m5"]
[ext_resource type="Script" uid="uid://b8g0hkqvyeptg" path="res://scripts/Contents/Characters/Lynx.gd" id="2_d6nve"]
[node name="Lynx" unique_id=1711205167 instance=ExtResource("1_ns0m5")]
script = ExtResource("2_d6nve")
displayName = "猞猁"
+8
View File
@@ -0,0 +1,8 @@
[gd_scene format=3 uid="uid://c7xe5swtkyhbg"]
[ext_resource type="PackedScene" uid="uid://bs863g2s8r770" path="res://components/Abstracts/PlayerBase.tscn" id="1_y3l4w"]
[ext_resource type="Script" uid="uid://bbmb572iba42l" path="res://scripts/Contents/Characters/MuyangDog.gd" id="2_mr6nm"]
[node name="MuyangDog" unique_id=1711205167 instance=ExtResource("1_y3l4w")]
script = ExtResource("2_mr6nm")
displayName = "牧羊犬"
-4
View File
@@ -2,7 +2,6 @@
[ext_resource type="PackedScene" uid="uid://cvogxi7mktumf" path="res://components/Abstracts/EntityBase.tscn" id="1_e5pl8"]
[ext_resource type="Script" uid="uid://cthtupc6dtbav" path="res://scripts/Contents/Characters/Rooster.gd" id="2_oqdqd"]
[ext_resource type="PackedScene" uid="uid://dlaks67h2osms" path="res://components/Weapons/ChainGun.tscn" id="3_s7kxe"]
[ext_resource type="AudioStream" uid="uid://cdrevrq7n6yqa" path="res://resources/sounds/effect/Boing.mp3" id="4_66s6c"]
[ext_resource type="AudioStream" uid="uid://benyec5bqni0b" path="res://resources/sounds/effect/Chomp.wav" id="4_k0yme"]
[ext_resource type="AudioStream" uid="uid://dmxh3bpk8vyy5" path="res://resources/sounds/effect/Coin.mp3" id="5_xnbhq"]
@@ -97,9 +96,6 @@ process_material = SubResource("ParticleProcessMaterial_joj4g")
[node name="weaponStore" parent="." index="2"]
process_mode = 4
[node name="ChainGun" parent="weaponStore" index="0" unique_id=1992324853 instance=ExtResource("3_s7kxe")]
debugRebuild = false
[node name="sprint" parent="sounds" index="0"]
stream = ExtResource("4_66s6c")
@@ -376,7 +376,7 @@ layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
theme = ExtResource("4_lfxcn")
text = "公鸡"
text = ""
placeholder_text = "角色名"
alignment = 1
expand_to_text_length = true
+4
View File
@@ -0,0 +1,4 @@
extends PlayerBase
func summoned(entity: SummonBase):
entity.died.connect(func(): tryHeal(3))
+1
View File
@@ -0,0 +1 @@
uid://bevc4f6apql4t
+5
View File
@@ -0,0 +1,5 @@
extends PlayerBase
func register():
super.register()
sprintMultiplier += 3
+1
View File
@@ -0,0 +1 @@
uid://b8g0hkqvyeptg
+11
View File
@@ -0,0 +1,11 @@
extends PlayerBase
var parryCounter: CooldownTimer = CooldownTimer.new(5000)
func ai():
super.ai()
if parryCounter.start():
var track = getTrackingAnchor()
var bullet = BulletTool.findClosetBulletCanDamage(track, get_tree(), self , 400)
if is_instance_valid(bullet):
BulletBase.generate(ComponentManager.getBullet("Parrier"), self , track, track.angle_to_point(bullet.position))
@@ -0,0 +1 @@
uid://bbmb572iba42l
+80
View File
@@ -0,0 +1,80 @@
extends EntityBase
class_name PlayerBase
var chargeStartTime = {}
@onready var chargeParticle: GPUParticles2D = $%chargeParticle
func register():
attackCooldownMap[0] = 200
attackCooldownMap[1] = 6000
hit.connect(
func(_damage: float, bullet: BulletBase, _crit: bool):
if bullet is DogCircle:
EffectController.create(ComponentManager.getEffect("FeatherFall"), texture.global_position).shot()
elif bullet is FoxZhua:
EffectController.create(ComponentManager.getEffect("BloodFall"), texture.global_position).shot()
)
chargeParticle.emitting = false
func ai():
currentFocusedPosition = get_global_mouse_position()
texture.play("walk")
var direction = Vector2(
Input.get_axis("m_left", "m_right"),
Input.get_axis("m_up", "m_down")
)
move(direction)
if direction.length() == 0:
texture.play("idle")
tryLaunch("attack", 0)
tryLaunch("attack2", 1)
tryLaunch("smallSkill", 2)
tryLaunch("superSkill", 3)
for i in range(3):
tryLaunch("cardSkill%d" % i, 4 + i)
if Input.is_action_just_pressed("sprint"):
trySprint()
if Input.is_action_just_pressed("heal"):
if health < fields.get(FieldStore.Entity.MAX_HEALTH):
if useItem({
ItemStore.ItemType.APPLE: 1
}):
tryHeal(20)
func sprint():
move(Vector2(
Input.get_axis("m_left", "m_right"),
Input.get_axis("m_up", "m_down")
) * sprintMultiplier, true)
func tryLaunch(action: String, weaponIndex: int):
if Input.is_action_just_pressed(action):
if len(weapons) > weaponIndex:
var weapon = weapons[weaponIndex]
if weapon.emitType == Weapon.EmitType.CHARGE:
if weapon.canAttackBy(self ):
chargeStartTime[weaponIndex] = Time.get_ticks_msec()
chargeParticle.emitting = true
chargeParticle.speed_scale = 1
elif weapon.emitType == Weapon.EmitType.CLICK_SHOOT || weapon.emitType == Weapon.EmitType.HOLD_LOOP:
tryAttack(weaponIndex)
if Input.is_action_pressed(action):
if len(weapons) > weaponIndex:
var weapon = weapons[weaponIndex]
if chargeStartTime.has(weaponIndex):
chargeParticle.speed_scale += 0.01 * self.fields.get(FieldStore.Entity.CHARGE_SPEED)
elif weapon.emitType == Weapon.EmitType.HOLD_SHOOT || weapon.emitType == Weapon.EmitType.HOLD_LOOP:
tryAttack(weaponIndex)
if Input.is_action_just_released(action):
if len(weapons) > weaponIndex:
var weapon = weapons[weaponIndex]
if weapon.emitType == Weapon.EmitType.CHARGE:
if chargeStartTime.has(weaponIndex):
var startTime = chargeStartTime[weaponIndex]
var endTime = Time.get_ticks_msec()
var chargedTime = endTime - startTime
chargeStartTime.erase(weaponIndex)
weapon.chargedTime = chargedTime * self.fields.get(FieldStore.Entity.CHARGE_SPEED)
tryAttack(weaponIndex)
chargeParticle.emitting = false
elif weapon.emitType == Weapon.EmitType.HOLD_LOOP:
weapon.exitLoop(self )
@@ -0,0 +1 @@
uid://r5gm7rcya35p
+6 -2
View File
@@ -76,14 +76,18 @@ func startMultiplayerGame():
MultiplayerState.connection = multiplayer.multiplayer_peer
WorldManager.rootNode.multiplayer.multiplayer_peer = multiplayer.multiplayer_peer
for i in getPlayerNames():
EntityBase.generatePlayer(i)
EntityBase.generatePlayer(i, selectedCharacter)
UIState.closeCurrentPanel()
func startSingleplayerGame():
startSingleplayerBtn.disabled = true
MultiplayerState.isMultiplayer = false
MultiplayerState.playerName = playerNameInput.text
Wave.usingWaveData = GAMEMODE_MAP_WAVE[gamemodeOption.selected]
UIState.player = EntityBase.generatePlayer(playerNameInput.text)
var extras = ArrayTool.mergeDictionary(ArrayTool.dictionaryFromEntries(
getCurrentSelectedCharacter().fields,
getCurrentSelectedCharacter().fieldValues
), OutGameStorage.upgradableFieldsValue)
UIState.player = EntityBase.generatePlayer(playerNameInput.text, selectedCharacter, extras)
WorldManager.rootNode.spawnWave(Vector2.ZERO)
UIState.setPanel("CompilingTip")
+5 -5
View File
@@ -7,16 +7,16 @@ var speedScale: float = 1
func _init(cd: float = 100):
cooldown = cd
func centralTime():
func centralTime() -> float:
return cooldown / speedScale
func isCooldowned():
func isCooldowned() -> bool:
return timeSinceLastStart() >= centralTime()
func start():
func start() -> bool:
var state = isCooldowned()
if state:
lastStart = WorldManager.getTime()
return state
func timeSinceLastStart():
func timeSinceLastStart() -> float:
return WorldManager.getTime() - lastStart
func percent():
func percent() -> float:
return timeSinceLastStart() / centralTime()
+13 -7
View File
@@ -138,7 +138,7 @@ func _ready():
UIState.player = self
if WorldManager.isRelease():
for i in weaponStore.get_children():
i.free()
i.queue_free()
weaponStore.add_child(ComponentManager.getWeapon("PurpleCrystal").instantiate())
for i in weaponStore.get_children():
i.hide()
@@ -505,6 +505,7 @@ func summon(who: PackedScene, syncFields: bool = true, lockValue: bool = true) -
var instance: SummonBase = who.instantiate()
instance.position = get_global_mouse_position()
instance.myMaster = self
summoned(instance)
if isPlayer(): instance.add_to_group("players")
if syncFields:
if lockValue:
@@ -550,20 +551,22 @@ func enterStage(_stage: int):
pass
func kill():
pass
func summoned(_entity: SummonBase):
pass
static func findPlayer(playerName: String) -> EntityBase:
for i in getPlayers():
if i.displayName == playerName:
return i
return null
static func generatePlayer(playerName: String) -> EntityBase:
var player = generate(ComponentManager.getCharacter("Rooster"), Vector2.ZERO, false)
player.displayName = playerName
static func generatePlayer(playerName: String, character: String, extraFields: Dictionary = {}) -> EntityBase:
var player = generate(ComponentManager.getCharacter(character), Vector2.ZERO, false, false, true, playerName)
player.name = "Player_%s" % playerName
print(extraFields)
var feed = ComponentManager.getAbstract("FeedCardBase").instantiate() as Feed
for field in OutGameStorage.upgradableFieldsValue:
for field in extraFields:
feed.fields.append(field)
feed.fieldValues.append(OutGameStorage.upgradableFieldsValue[field])
feed.fieldValues.append(extraFields[field])
feed.freeToBuy = true
feed.apply(player)
return player
@@ -572,12 +575,15 @@ static func generate(
spawnPosition: Vector2,
isMob: bool = true,
spawnAsBoss: bool = false,
addToWorld: bool = true
addToWorld: bool = true,
disName: String = ""
):
var instance: EntityBase = entity.instantiate()
instance.position = spawnPosition
instance.isBoss = spawnAsBoss
instance.level = clamp((round(Wave.current * (1 + GameRule.entityLevelOffsetByWave * randf_range(-1, 1)))), 1, INF)
if disName:
instance.displayName = disName
if isMob:
instance.add_to_group("mobs")
else:
+3
View File
@@ -5,6 +5,7 @@ class_name CharacterCard
signal select()
@export var displayName: String = "Unknown Character"
@export var slogan: String = "Slogan"
@export var avatar: Texture2D = null
@export_multiline var description: String = ""
@export var fields: Array[FieldStore.Entity] = []
@@ -14,6 +15,7 @@ signal select()
@onready var avatarTexture: TextureRect = $%avatarTexture
@onready var nameLebel: Label = $%nameLabel
@onready var sloganLabel: Label = $%sloganLabel
@onready var descriptionLabel: Label = $%descriptionLabel
@onready var fieldsBox: Control = $%fields
@onready var animator: AnimationPlayer = $%animator
@@ -40,6 +42,7 @@ func _process(_delta):
func rebuildInfo():
avatarTexture.texture = avatar
nameLebel.text = displayName
sloganLabel.text = "%s" % slogan
descriptionLabel.text = description
for child in fieldsBox.get_children():
fieldsBox.remove_child(child)
+14
View File
@@ -31,3 +31,17 @@ static func fill(origin: Dictionary, filler: Callable) -> Dictionary:
return accum,
{}
)
static func dictionaryFromEntries(keys: Array, values: Array) -> Dictionary:
var result = {}
for index in len(keys):
var key = keys[index]
var value = values[index]
result[key] = value
return result
static func mergeDictionary(a: Dictionary, b: Dictionary) -> Dictionary:
var result := {}
for key in a:
result[key] = a[key]
for key in b:
result[key] = result.get(key, 0.0) + b[key]
return result