1
1
mirror of https://github.com/Rundll86/Dog-Lynx-And-HCN.git synced 2026-05-28 15:01:53 +08:00

Compare commits

...

23 Commits

Author SHA1 Message Date
fallingshrimp 52a6f6b3c5 refactor(EntityBase): 移除发布模式下武器子节点的释放逻辑
由于武器子节点在发布模式下隐藏而非释放,移除了冗余的queue_free调用以简化代码
2026-05-05 14:46:55 +08:00
fallingshrimp 75adfed454 feat(角色): 为角色添加默认武器并调整死亡逻辑
为HCN、Lynx和MuyangDog角色添加默认武器
移除发布模式下自动添加紫色水晶武器的逻辑
调整死亡逻辑,使召唤物也能被正确释放
2026-05-05 14:46:27 +08:00
fallingshrimp 0d3c1790af feat(相机): 添加鼠标位置对相机偏移的影响
实现鼠标位置影响相机偏移的功能,使相机能够根据鼠标在屏幕上的位置进行轻微偏移,提升游戏交互体验
2026-05-05 12:37:06 +08:00
fallingshrimp 15e5bcb5bc refactor(EntityBase): 移除调试用的print语句
清理调试代码,提升代码整洁度
2026-05-05 12:25:16 +08:00
fallingshrimp 11a293378c refactor(UI): 优化字段显示逻辑并添加平滑相机移动
将字段显示和隐藏逻辑提取为独立方法
为相机添加位置平滑效果
在游戏重启时重置初始饲料选择状态
2026-05-05 12:24:45 +08:00
fallingshrimp 7e48372902 1 2026-05-05 12:19:12 +08:00
fallingshrimp d039e252f6 feat(android): 添加Android导出配置并启用ETC2/ASTC纹理压缩
- 在project.godot中启用ETC2/ASTC纹理压缩
- 为角色纹理添加ETC2格式支持
- 新增完整的Android平台导出配置预设
2026-05-05 11:29:00 +08:00
fallingshrimp f12a5ee43a chore: 在.gitignore中添加android目录
忽略android构建目录以避免不必要的版本控制
2026-05-05 10:57:20 +08:00
fallingshrimp 2f3912da34 fix(Feed): 修复countOf函数中乘数应用的逻辑错误
当基础值为正数时使用乘法,为负数时使用除法,确保计算结果的正确性
2026-05-05 07:31:35 +08:00
fallingshrimp 75fbef8895 fix(EntityBase): 修复玩家角色死亡时被立即移除的问题
修改tryDie方法,仅当非玩家角色时才调用queue_free
同时更新牧羊犬角色的标语和配置
2026-05-05 07:14:41 +08:00
fallingshrimp 14deb2de71 feat: 添加暂停面板类名并优化字段显示逻辑
修复TipBox销毁时的动画冲突问题
重构游戏重启逻辑以包含库存保存
移除GameOver面板中的重复库存保存代码
优化UIState中的字段显示控制和提示清除功能
2026-05-05 07:04:32 +08:00
fallingshrimp cc103f274b fix: 调整MuyangDog的子弹检测范围并修复UIState字段显示问题
修复MuyangDog角色子弹检测范围从400减少到300以平衡游戏难度
在UIState中添加字段动画播放状态检查,防止动画冲突
2026-05-05 06:54:09 +08:00
fallingshrimp 30527a18a8 feat: 添加游戏控制和管理功能
- 新增GameControl节点用于统一处理游戏重启和退出
- 添加GameBusManager管理游戏重启时的资源清理
- 修改Pause和GameOver面板使用新的GameControl
- 为EffectController和ItemDropped添加分组管理
- 统一使用WorldManager管理游戏时间
2026-05-05 06:51:48 +08:00
fallingshrimp f6e71507ce chore: 清理无用文件和更新游戏规则脚本
删除不再需要的图片、批处理文件和日志文件
更新todo.md移除已完成的任务项
在GameRule.gd中添加helpText静态变量
2026-05-05 06:24:55 +08:00
fallingshrimp edc31d876e fix(MuyangDog): 修复格挡计数器逻辑错误
将parryCounter.start()判断改为parryCounter.isCooldowned(),并在成功格挡后启动计数器
2026-05-04 22:07:03 +08:00
fallingshrimp b5c2152d4c fix(EntityBase): 限制能量值不超过最大值
style(Starter): 更新游戏模式选项文本描述
2026-05-04 21:56:37 +08:00
fallingshrimp 8137b398a9 fix(Feed): 修复字段应用逻辑并确保数值范围正确
调整字段值应用顺序,先增加值再检查applier回调。如果applier存在且返回true,则减去之前增加的值。最后确保所有字段值在有效范围内。
2026-05-04 21:52:04 +08:00
fallingshrimp 5c85b4c10c refactor(角色): 修改HCN技能效果为储能并随机选择初始角色
将HCN的召唤物死亡效果从恢复生命值改为储能10点
修改初始角色选择逻辑为随机选择
更新角色卡牌描述以匹配新技能效果
2026-05-04 21:45:21 +08:00
fallingshrimp fac8d82157 fix(角色平衡): 调整牧羊犬格挡冷却时间和治疗量
将牧羊犬的格挡冷却时间从5秒减少到3秒
将HCN的治疗量从3点提升到5点
移除牧羊犬卡片的clickToRebuild属性
2026-05-04 21:39:56 +08:00
fallingshrimp dc4b080a09 feat: 新增角色系统及基础功能实现
新增HCN、Lynx和MuyangDog三个可玩角色及其相关资源
实现角色选择界面和角色属性系统
重构玩家生成逻辑以支持角色选择
优化角色卡片UI显示效果
2026-05-04 21:34:57 +08:00
fallingshrimp 4d1f68cac1 feat(角色卡片): 添加新角色卡片资源并优化显示逻辑
添加猞猁、牧羊犬和氰化氢的角色卡片资源
优化卡片选中状态的动画显示逻辑
调整卡片样式和主题配置
移除冗余的panel节点引用
2026-05-04 20:32:07 +08:00
fallingshrimp 492373a48e feat: 添加角色选择系统及相关功能
新增角色卡片组件和角色选择逻辑
实现角色卡片动画效果和交互功能
添加初始角色数据配置
修改启动面板以支持角色选择
更新主题样式和UI布局
2026-05-04 19:52:04 +08:00
fallingshrimp e8ee2932bb feat(游戏机制): 调整掉落物品数量和添加错误提示
增加boss和非boss敌人死亡时掉落水晶的数量范围
为武器镶嵌/移除灵魂操作添加错误提示
移除Starter场景中不必要的属性设置
新增CharacterCardBase基础组件
2026-05-04 18:14:21 +08:00
66 changed files with 1311 additions and 170 deletions
+2 -1
View File
@@ -2,4 +2,5 @@
.codebuddy
build/*
!build/.gitkeep
*.zip
*.zip
android
+250
View File
@@ -0,0 +1,250 @@
[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_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_color = Color(1, 1, 1, 1)
border_blend = true
corner_radius_top_left = 15
corner_radius_bottom_right = 15
corner_detail = 1
[sub_resource type="LabelSettings" id="LabelSettings_dt83t"]
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
[sub_resource type="Animation" id="Animation_dt83t"]
length = 0.001
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:scale:x")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0.85, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
tracks/1/type = "bezier"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:scale:y")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0.85, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:modulate")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 0.5)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath(".:borderOpacity")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
[sub_resource type="Animation" id="Animation_myhk0"]
resource_name = "hide"
length = 0.5
step = 0.1
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:scale:x")
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.85, 0, 0, 0, 0),
"times": PackedFloat32Array(0, 0.5)
}
tracks/1/type = "bezier"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:scale:y")
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.85, 0, 0, 0, 0),
"times": PackedFloat32Array(0, 0.5)
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:modulate")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0.5)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath(".:borderOpacity")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 0.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [1.0, 0.0]
}
[sub_resource type="Animation" id="Animation_fnmic"]
resource_name = "hide"
length = 0.5
step = 0.1
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:scale:x")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(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"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:scale:y")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(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"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:modulate")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0.5), Color(1, 1, 1, 1)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath(".:borderOpacity")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 0.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0.0, 1.0]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_xuke2"]
_data = {
&"RESET": SubResource("Animation_dt83t"),
&"hide": SubResource("Animation_myhk0"),
&"show": SubResource("Animation_fnmic")
}
[node name="panel" type="PanelContainer" unique_id=1046363300]
modulate = Color(1, 1, 1, 0.5)
offset_right = 226.0
offset_bottom = 212.0
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
theme_override_constants/separation = 10
[node name="avatarTexture" type="TextureRect" parent="wrapper" unique_id=1334645594]
unique_name_in_owner = true
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="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]
unique_name_in_owner = true
layout_mode = 2
[node name="animator" type="AnimationPlayer" parent="." unique_id=1012843997]
unique_name_in_owner = true
libraries/ = SubResource("AnimationLibrary_xuke2")
+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("..")
+38
View File
@@ -0,0 +1,38 @@
[gd_scene format=3 uid="uid://dfww6e0mpyjk4"]
[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_1yfsg"]
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_color = Color(1, 1, 1, 1)
border_blend = true
corner_radius_top_left = 15
corner_radius_bottom_right = 15
corner_detail = 1
[node name="HCN" unique_id=1046363300 instance=ExtResource("1_robpf")]
theme_override_styles/panel = SubResource("StyleBoxFlat_1yfsg")
displayName = "氰化氢"
slogan = "微量便可颠覆生机"
avatar = ExtResource("2_1yfsg")
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/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 = "召唤物死亡时为自身恢复生命值。"
+38
View File
@@ -0,0 +1,38 @@
[gd_scene format=3 uid="uid://cygvim0mv4ssa"]
[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_1s675"]
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.70000005)
border_color = Color(1, 1, 1, 1)
border_blend = true
corner_radius_top_left = 15
corner_radius_bottom_right = 15
corner_detail = 1
[node name="Lynx" unique_id=1046363300 instance=ExtResource("1_xa4jc")]
theme_override_styles/panel = SubResource("StyleBoxFlat_1s675")
displayName = "猞猁"
slogan = "栖于寒域密林,孤影独行世间"
avatar = ExtResource("2_1s675")
description = "拥有更大的冲刺速度。"
fields = Array[int]([3, 4, 10])
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/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 = "拥有更大的冲刺速度。"
+37
View File
@@ -0,0 +1,37 @@
[gd_scene format=3 uid="uid://bglwhggnbxxax"]
[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_fi2nw"]
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.70000005)
border_blend = true
corner_radius_top_left = 15
corner_radius_bottom_right = 15
corner_detail = 1
[node name="MuyangDog" unique_id=1046363300 instance=ExtResource("1_wq25g")]
theme_override_styles/panel = SubResource("StyleBoxFlat_fi2nw")
displayName = "牧羊犬"
slogan = "恪守使命不离不弃"
avatar = ExtResource("2_fi2nw")
description = "每3秒发动格挡,弹反一切子弹。"
fields = Array[int]([0, 8, 3])
fieldValues = Array[float]([50.0, 0.15, -0.2])
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/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 = "每3秒发动格挡,弹反一切子弹。"
+11
View File
@@ -0,0 +1,11 @@
[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"]
[ext_resource type="PackedScene" uid="uid://wl8u5m52708w" path="res://components/Weapons/LGBT.tscn" id="3_2fpmn"]
[node name="HCN" unique_id=1711205167 instance=ExtResource("1_eeneu")]
script = ExtResource("2_f7uj3")
displayName = "氰化氢"
[node name="LGBT" parent="weaponStore" index="0" unique_id=1938660022 instance=ExtResource("3_2fpmn")]
+11
View File
@@ -0,0 +1,11 @@
[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"]
[ext_resource type="PackedScene" uid="uid://frwt0fgrpskb" path="res://components/Weapons/Meowmere.tscn" id="3_nitbu"]
[node name="Lynx" unique_id=1711205167 instance=ExtResource("1_ns0m5")]
script = ExtResource("2_d6nve")
displayName = "猞猁"
[node name="Meowmere" parent="weaponStore" index="0" unique_id=1965287972 instance=ExtResource("3_nitbu")]
+11
View File
@@ -0,0 +1,11 @@
[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"]
[ext_resource type="PackedScene" uid="uid://u0djqwuuysp8" path="res://components/Weapons/Volcano.tscn" id="3_e236u"]
[node name="MuyangDog" unique_id=1711205167 instance=ExtResource("1_y3l4w")]
script = ExtResource("2_mr6nm")
displayName = "牧羊犬"
[node name="Volcano" parent="weaponStore" index="0" unique_id=204992396 instance=ExtResource("3_e236u")]
-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")
@@ -1,9 +1,10 @@
[gd_scene format=3 uid="uid://beo6s1kudbbve"]
[gd_scene format=3 uid="uid://b14x2fai2bagp"]
[ext_resource type="PackedScene" uid="uid://d3qojeqa3difn" path="res://components/Abstracts/FullscreenPanelBase.tscn" id="1_u2ynr"]
[ext_resource type="Script" uid="uid://bub7ku5qf2tpo" path="res://scripts/Contents/Panels/GameOver.gd" id="2_6cd45"]
[ext_resource type="FontFile" uid="uid://v3frxpuvtj5o" path="res://resources/fonts/syht-bold.ttf" id="3_2arur"]
[ext_resource type="AudioStream" uid="uid://dbso1w8hvgilg" path="res://resources/sounds/effect/Lose.wav" id="3_n4aax"]
[ext_resource type="PackedScene" uid="uid://braggv3vafd83" path="res://components/UI/GameControl.tscn" id="4_idc4g"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7gbuu"]
bg_color = Color(1, 0, 0, 0.3)
@@ -48,21 +49,9 @@ text = "[color=gray]死亡原因[/color]"
fit_content = true
autowrap_mode = 0
[node name="gameControl" type="HBoxContainer" parent="content/wrapper/container/wrapper" index="1" unique_id=2129714003]
layout_mode = 2
alignment = 1
[node name="returnBtn" type="Button" parent="content/wrapper/container/wrapper/gameControl" index="0" unique_id=1955688444]
[node name="gameControl" parent="content/wrapper/container/wrapper/death" index="2" unique_id=1187018703 instance=ExtResource("4_idc4g")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
text = "重新开始游戏"
[node name="exitBtn" type="Button" parent="content/wrapper/container/wrapper/gameControl" index="1" unique_id=1303303813]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
text = "退出游戏"
[node name="audio" type="AudioStreamPlayer2D" parent="." index="2" unique_id=2020590816]
unique_name_in_owner = true
@@ -1,14 +1,15 @@
[gd_scene load_steps=5 format=3 uid="uid://cksonrrx38k36"]
[gd_scene format=3 uid="uid://cksonrrx38k36"]
[ext_resource type="PackedScene" uid="uid://d3qojeqa3difn" path="res://components/Abstracts/FullscreenPanelBase.tscn" id="1_q0gd0"]
[ext_resource type="Script" path="res://scripts/Contents/Panels/Pause.gd" id="2_lg6qs"]
[ext_resource type="Script" uid="uid://ba0tgtpjp34k8" path="res://scripts/Contents/Panels/Pause.gd" id="2_lg6qs"]
[ext_resource type="FontFile" uid="uid://v3frxpuvtj5o" path="res://resources/fonts/syht-bold.ttf" id="3_jxeor"]
[ext_resource type="PackedScene" uid="uid://braggv3vafd83" path="res://components/UI/GameControl.tscn" id="4_tij4f"]
[sub_resource type="LabelSettings" id="LabelSettings_hsvpc"]
font = ExtResource("3_jxeor")
font_size = 50
[node name="Pause" instance=ExtResource("1_q0gd0")]
[node name="Pause" unique_id=518412591 instance=ExtResource("1_q0gd0")]
offset_top = 0.0
offset_bottom = 0.0
script = ExtResource("2_lg6qs")
@@ -16,14 +17,12 @@ script = ExtResource("2_lg6qs")
[node name="wrapper" parent="content" index="1"]
theme_override_constants/separation = 10
[node name="text" type="Label" parent="content/wrapper" index="0"]
[node name="text" type="Label" parent="content/wrapper" index="0" unique_id=884780519]
layout_mode = 2
size_flags_horizontal = 4
text = "已暂停"
label_settings = SubResource("LabelSettings_hsvpc")
[node name="aboutBtn" type="Button" parent="content/wrapper" index="1"]
[node name="gameControl" parent="content/wrapper" index="1" unique_id=1187018703 instance=ExtResource("4_tij4f")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
text = "关于↗"
+53 -30
View File
@@ -16,6 +16,22 @@ shader_parameter/prog = 0.5000000074506
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_4ekdw"]
content_margin_left = 60.0
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_4ekdw"]
content_margin_left = 30.0
content_margin_top = 30.0
content_margin_right = 30.0
content_margin_bottom = 30.0
bg_color = Color(0, 0, 0, 0.70000005)
border_width_left = 10
border_width_right = 10
border_color = Color(1, 1, 1, 1)
border_blend = true
corner_radius_top_left = 15
corner_radius_top_right = 15
corner_radius_bottom_right = 15
corner_radius_bottom_left = 15
corner_detail = 1
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_sdsu8"]
content_margin_right = 60.0
@@ -181,15 +197,23 @@ theme_override_constants/separation = 30
[node name="character" type="PanelContainer" parent="content/wrapper/layout/outGameWrapper/layout" index="0" unique_id=1828402109]
layout_mode = 2
theme_override_styles/panel = ExtResource("7_kl3ko")
theme_override_styles/panel = SubResource("StyleBoxFlat_4ekdw")
[node name="container" type="VBoxContainer" parent="content/wrapper/layout/outGameWrapper/layout/character" index="0" unique_id=1167478166]
layout_mode = 2
theme_override_constants/separation = 20
[node name="title" type="Label" parent="content/wrapper/layout/outGameWrapper/layout/character/container" index="0" unique_id=1287813603]
layout_mode = 2
text = "选择角色"
[node name="characters" type="HBoxContainer" parent="content/wrapper/layout/outGameWrapper/layout/character/container" index="1" unique_id=1098596848]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/separation = 10
alignment = 1
[node name="outGame" type="PanelContainer" parent="content/wrapper/layout/outGameWrapper/layout" index="1" unique_id=1923951688]
layout_mode = 2
theme_override_styles/panel = ExtResource("7_kl3ko")
@@ -243,7 +267,6 @@ theme_override_constants/separation = 6
[node name="diffs" type="HBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter/singleplayer/playConfig" index="0" unique_id=526058063]
layout_mode = 2
alignment = 1
[node name="tip" type="Label" parent="content/wrapper/layout/startGameWrapper/start/starter/singleplayer/playConfig/diffs" index="0" unique_id=1507689450]
layout_mode = 2
@@ -276,34 +299,14 @@ theme = ExtResource("4_lfxcn")
selected = 0
allow_reselect = true
item_count = 3
popup/item_0/text = "无尽波次"
popup/item_0/text = "无尽波次·标准游戏体验"
popup/item_0/id = 0
popup/item_1/text = "Boss Rush"
popup/item_1/id = 1
popup/item_2/text = "割草"
popup/item_2/text = "割草·高难度⚠️"
popup/item_2/id = 2
[node name="player" type="HBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter/singleplayer/playConfig" index="2" unique_id=656225175]
layout_mode = 2
[node name="tip" type="Label" parent="content/wrapper/layout/startGameWrapper/start/starter/singleplayer/playConfig/player" index="0" unique_id=1899542373]
layout_mode = 2
text = "角色名:"
[node name="playerNameInput" type="LineEdit" parent="content/wrapper/layout/startGameWrapper/start/starter/singleplayer/playConfig/player" index="1" unique_id=1401004968]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
theme = ExtResource("4_lfxcn")
text = "公鸡"
placeholder_text = "角色名"
alignment = 1
expand_to_text_length = true
select_all_on_focus = true
virtual_keyboard_type = 7
[node name="useTutorial" type="HBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter/singleplayer/playConfig" index="3" unique_id=2079979053]
[node name="useTutorial" type="HBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter/singleplayer/playConfig" index="2" unique_id=2079979053]
layout_mode = 2
[node name="tip" type="Label" parent="content/wrapper/layout/startGameWrapper/start/starter/singleplayer/playConfig/useTutorial" index="0" unique_id=20976924]
@@ -338,7 +341,6 @@ theme = ExtResource("4_lfxcn")
text = "多人游戏"
[node name="multiplayer" type="VBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter" index="1" unique_id=2010516457]
visible = false
layout_mode = 2
theme_override_constants/separation = 15
alignment = 1
@@ -360,24 +362,45 @@ size_flags_horizontal = 4
text = "状态:未连接到服务器。"
label_settings = SubResource("LabelSettings_kl3ko")
[node name="host" type="HBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter/multiplayer/main" index="2" unique_id=105458555]
[node name="player" type="HBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter/multiplayer/main" index="2" unique_id=656225175]
layout_mode = 2
[node name="tip" type="Label" parent="content/wrapper/layout/startGameWrapper/start/starter/multiplayer/main/player" index="0" unique_id=1899542373]
layout_mode = 2
text = "角色名:"
label_settings = SubResource("LabelSettings_sdsu8")
[node name="playerNameInput" type="LineEdit" parent="content/wrapper/layout/startGameWrapper/start/starter/multiplayer/main/player" index="1" unique_id=1401004968]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
theme = ExtResource("4_lfxcn")
text = "你"
placeholder_text = "角色名"
alignment = 1
expand_to_text_length = true
select_all_on_focus = true
virtual_keyboard_type = 7
[node name="host" type="HBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter/multiplayer/main" index="3" unique_id=105458555]
layout_mode = 2
[node name="tip" type="Label" parent="content/wrapper/layout/startGameWrapper/start/starter/multiplayer/main/host" index="0" unique_id=871253279]
layout_mode = 2
text = "地址"
text = "服务器地址"
label_settings = SubResource("LabelSettings_sdsu8")
[node name="hostInput" type="LineEdit" parent="content/wrapper/layout/startGameWrapper/start/starter/multiplayer/main/host" index="1" unique_id=1534443919]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("4_lfxcn")
text = "127.0.0.1"
placeholder_text = "主机"
alignment = 2
expand_to_text_length = true
emoji_menu_enabled = false
clear_button_enabled = true
select_all_on_focus = true
virtual_keyboard_type = 7
@@ -396,7 +419,7 @@ emoji_menu_enabled = false
select_all_on_focus = true
virtual_keyboard_type = 2
[node name="operation" type="HBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter/multiplayer/main" index="3" unique_id=720531196]
[node name="operation" type="HBoxContainer" parent="content/wrapper/layout/startGameWrapper/start/starter/multiplayer/main" index="4" unique_id=720531196]
layout_mode = 2
alignment = 1
+20 -15
View File
@@ -1,4 +1,4 @@
[gd_scene load_steps=9 format=3 uid="uid://dmxi1ikn6avig"]
[gd_scene format=3 uid="uid://dmxi1ikn6avig"]
[ext_resource type="Script" uid="uid://d2oyyyg0b4qqd" path="res://scripts/Tools/Managers/WorldManager.gd" id="1_lxsxj"]
[ext_resource type="PackedScene" uid="uid://dfwg750a47ggx" path="res://components/Scenes/UI.tscn" id="2_04cdd"]
@@ -66,57 +66,62 @@ _data = {
[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_lu72f"]
normal = Vector2(0, 1)
[node name="world" type="Node2D"]
[node name="world" type="Node2D" unique_id=1992792389]
y_sort_enabled = true
texture_filter = 1
script = ExtResource("1_lxsxj")
metadata/_edit_vertical_guides_ = [-1.0, 57.0]
[node name="spawner" type="MultiplayerSpawner" parent="."]
[node name="spawner" type="MultiplayerSpawner" parent="." unique_id=1891214291]
unique_name_in_owner = true
spawn_path = NodePath("..")
[node name="UI" parent="." instance=ExtResource("2_04cdd")]
[node name="UI" parent="." unique_id=1312059514 instance=ExtResource("2_04cdd")]
[node name="camera" type="Camera2D" parent="."]
[node name="camera" type="Camera2D" parent="." unique_id=996511427]
process_mode = 3
process_callback = 0
limit_left = -2400
limit_top = -1800
limit_right = 2400
limit_bottom = 1800
position_smoothing_enabled = true
drag_horizontal_enabled = true
drag_vertical_enabled = true
editor_draw_limits = true
script = ExtResource("5_mk7bv")
constantOffset = Vector2(0, -80)
[node name="animator" type="AnimationPlayer" parent="camera"]
[node name="animator" type="AnimationPlayer" parent="camera" unique_id=619200978]
unique_name_in_owner = true
libraries = {
&"": SubResource("AnimationLibrary_44ixa")
}
libraries/ = SubResource("AnimationLibrary_44ixa")
[node name="map" type="StaticBody2D" parent="." groups=["map"]]
[node name="map" type="StaticBody2D" parent="." unique_id=385091617 groups=["map"]]
collision_layer = 6
collision_mask = 6
metadata/_edit_lock_ = true
[node name="background" type="Sprite2D" parent="map"]
[node name="background" type="Sprite2D" parent="map" unique_id=792319336]
z_index = -100
scale = Vector2(5, 5)
texture = ExtResource("4_oy4jj")
metadata/_edit_lock_ = true
[node name="borderTop" type="CollisionShape2D" parent="map"]
[node name="borderTop" type="CollisionShape2D" parent="map" unique_id=320842136]
position = Vector2(0, -1800)
shape = SubResource("WorldBoundaryShape2D_lu72f")
[node name="borderTop2" type="CollisionShape2D" parent="map"]
[node name="borderTop2" type="CollisionShape2D" parent="map" unique_id=1208131017]
position = Vector2(0, 1800)
rotation = 3.1415927
shape = SubResource("WorldBoundaryShape2D_lu72f")
[node name="borderTop3" type="CollisionShape2D" parent="map"]
[node name="borderTop3" type="CollisionShape2D" parent="map" unique_id=585247179]
position = Vector2(2400, 0)
rotation = 1.5707964
shape = SubResource("WorldBoundaryShape2D_lu72f")
[node name="borderTop4" type="CollisionShape2D" parent="map"]
[node name="borderTop4" type="CollisionShape2D" parent="map" unique_id=320391894]
position = Vector2(-2400, 0)
rotation = -1.5707964
shape = SubResource("WorldBoundaryShape2D_lu72f")
+19
View File
@@ -0,0 +1,19 @@
[gd_scene format=3 uid="uid://braggv3vafd83"]
[ext_resource type="Script" uid="uid://b63fkg0waovo" path="res://scripts/Statemachine/GameControl.gd" id="1_t5a04"]
[node name="GameControl" type="HBoxContainer" unique_id=1187018703]
size_flags_horizontal = 4
script = ExtResource("1_t5a04")
[node name="returnBtn" type="Button" parent="." unique_id=2089710932]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
text = "重新开始游戏"
[node name="exitBtn" type="Button" parent="." unique_id=100260653]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
text = "退出游戏"
+226
View File
@@ -166,3 +166,229 @@ progressive_web_app/icon_512x512=""
progressive_web_app/background_color=Color(0, 0, 0, 1)
threads/emscripten_pool_size=8
threads/godot_pool_size=4
[preset.3]
name="Android"
platform="Android"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="build/android/DLH.apk"
patches=PackedStringArray()
patch_delta_encoding=false
patch_delta_compression_level_zstd=19
patch_delta_min_reduction=0.1
patch_delta_include_filters="*"
patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.3.options]
custom_template/debug=""
custom_template/release=""
gradle_build/use_gradle_build=false
gradle_build/gradle_build_directory=""
gradle_build/android_source_template=""
gradle_build/compress_native_libraries=false
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk=""
gradle_build/custom_theme_attributes={}
architectures/armeabi-v7a=false
architectures/arm64-v8a=true
architectures/x86=false
architectures/x86_64=false
version/code=1
version/name=""
package/unique_name="top.fshrimp.doglynxhcn"
package/name="犬,猞猁,与氰化氢"
package/signed=true
package/app_category=2
package/retain_data_on_uninstall=false
package/exclude_from_recents=false
package/show_in_android_tv=false
package/show_in_app_library=true
package/show_as_launcher_app=false
launcher_icons/main_192x192=""
launcher_icons/adaptive_foreground_432x432=""
launcher_icons/adaptive_background_432x432=""
launcher_icons/adaptive_monochrome_432x432=""
graphics/opengl_debug=false
shader_baker/enabled=false
xr_features/xr_mode=0
gesture/swipe_to_dismiss=false
screen/immersive_mode=true
screen/edge_to_edge=true
screen/support_small=true
screen/support_normal=true
screen/support_large=true
screen/support_xlarge=true
screen/background_color=Color(0, 0, 0, 1)
user_data_backup/allow=true
command_line/extra_args=""
apk_expansion/enable=false
apk_expansion/SALT=""
apk_expansion/public_key=""
permissions/custom_permissions=PackedStringArray()
permissions/access_checkin_properties=false
permissions/access_coarse_location=false
permissions/access_fine_location=false
permissions/access_location_extra_commands=false
permissions/access_media_location=false
permissions/access_mock_location=false
permissions/access_network_state=false
permissions/access_surface_flinger=false
permissions/access_wifi_state=false
permissions/account_manager=false
permissions/add_voicemail=false
permissions/authenticate_accounts=false
permissions/battery_stats=false
permissions/bind_accessibility_service=false
permissions/bind_appwidget=false
permissions/bind_device_admin=false
permissions/bind_input_method=false
permissions/bind_nfc_service=false
permissions/bind_notification_listener_service=false
permissions/bind_print_service=false
permissions/bind_remoteviews=false
permissions/bind_text_service=false
permissions/bind_vpn_service=false
permissions/bind_wallpaper=false
permissions/bluetooth=false
permissions/bluetooth_admin=false
permissions/bluetooth_privileged=false
permissions/brick=false
permissions/broadcast_package_removed=false
permissions/broadcast_sms=false
permissions/broadcast_sticky=false
permissions/broadcast_wap_push=false
permissions/call_phone=false
permissions/call_privileged=false
permissions/camera=false
permissions/capture_audio_output=false
permissions/capture_secure_video_output=false
permissions/capture_video_output=false
permissions/change_component_enabled_state=false
permissions/change_configuration=false
permissions/change_network_state=false
permissions/change_wifi_multicast_state=false
permissions/change_wifi_state=false
permissions/clear_app_cache=false
permissions/clear_app_user_data=false
permissions/control_location_updates=false
permissions/delete_cache_files=false
permissions/delete_packages=false
permissions/device_power=false
permissions/diagnostic=false
permissions/disable_keyguard=false
permissions/dump=false
permissions/expand_status_bar=false
permissions/factory_test=false
permissions/flashlight=false
permissions/force_back=false
permissions/get_accounts=false
permissions/get_package_size=false
permissions/get_tasks=false
permissions/get_top_activity_info=false
permissions/global_search=false
permissions/hardware_test=false
permissions/inject_events=false
permissions/install_location_provider=false
permissions/install_packages=false
permissions/install_shortcut=false
permissions/internal_system_window=false
permissions/internet=false
permissions/kill_background_processes=false
permissions/location_hardware=false
permissions/manage_accounts=false
permissions/manage_app_tokens=false
permissions/manage_documents=false
permissions/manage_external_storage=false
permissions/manage_media=false
permissions/master_clear=false
permissions/media_content_control=false
permissions/modify_audio_settings=false
permissions/modify_phone_state=false
permissions/mount_format_filesystems=false
permissions/mount_unmount_filesystems=false
permissions/nfc=false
permissions/persistent_activity=false
permissions/post_notifications=false
permissions/process_outgoing_calls=false
permissions/read_calendar=false
permissions/read_call_log=false
permissions/read_contacts=false
permissions/read_external_storage=false
permissions/read_frame_buffer=false
permissions/read_history_bookmarks=false
permissions/read_input_state=false
permissions/read_logs=false
permissions/read_media_audio=false
permissions/read_media_images=false
permissions/read_media_video=false
permissions/read_media_visual_user_selected=false
permissions/read_phone_state=false
permissions/read_profile=false
permissions/read_sms=false
permissions/read_social_stream=false
permissions/read_sync_settings=false
permissions/read_sync_stats=false
permissions/read_user_dictionary=false
permissions/reboot=false
permissions/receive_boot_completed=false
permissions/receive_mms=false
permissions/receive_sms=false
permissions/receive_wap_push=false
permissions/record_audio=false
permissions/reorder_tasks=false
permissions/restart_packages=false
permissions/send_respond_via_message=false
permissions/send_sms=false
permissions/set_activity_watcher=false
permissions/set_alarm=false
permissions/set_always_finish=false
permissions/set_animation_scale=false
permissions/set_debug_app=false
permissions/set_orientation=false
permissions/set_pointer_speed=false
permissions/set_preferred_applications=false
permissions/set_process_limit=false
permissions/set_time=false
permissions/set_time_zone=false
permissions/set_wallpaper=false
permissions/set_wallpaper_hints=false
permissions/signal_persistent_processes=false
permissions/status_bar=false
permissions/subscribed_feeds_read=false
permissions/subscribed_feeds_write=false
permissions/system_alert_window=false
permissions/transmit_ir=false
permissions/uninstall_shortcut=false
permissions/update_device_stats=false
permissions/use_credentials=false
permissions/use_sip=false
permissions/vibrate=false
permissions/wake_lock=false
permissions/write_apn_settings=false
permissions/write_calendar=false
permissions/write_call_log=false
permissions/write_contacts=false
permissions/write_external_storage=false
permissions/write_gservices=false
permissions/write_history_bookmarks=false
permissions/write_profile=false
permissions/write_secure_settings=false
permissions/write_settings=false
permissions/write_sms=false
permissions/write_social_stream=false
permissions/write_sync_settings=false
permissions/write_user_dictionary=false
-5
View File
@@ -1,5 +0,0 @@
# Playlog
## 2025/9/30
平衡性已调整,可3个boss同窗无伤打完。
-4
View File
@@ -1,4 +0,0 @@
@echo off
cd build/web
python -m http.server 8080
+1
View File
@@ -135,3 +135,4 @@ locale/locale_filter_mode=0
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"
textures/vram_compression/import_etc2_astc=true
Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

@@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dkawfjwj80sqj"
path="res://.godot/imported/sjt.png-1b93f593cde723b537a6010a0c0d0d60.ctex"
uid="uid://2xmrkvyrcqq1"
path="res://.godot/imported/hcn.png-c27fe878ce57f16ec0714a09f8662903.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://sjt.png"
dest_files=["res://.godot/imported/sjt.png-1b93f593cde723b537a6010a0c0d0d60.ctex"]
source_file="res://resources/characterCards/hcn.png"
dest_files=["res://.godot/imported/hcn.png-c27fe878ce57f16ec0714a09f8662903.ctex"]
[params]
Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b1ogllqvamcun"
path="res://.godot/imported/lynx.png-0ad864fef53fe9b6c7e72f50bca44f0a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resources/characterCards/lynx.png"
dest_files=["res://.godot/imported/lynx.png-0ad864fef53fe9b6c7e72f50bca44f0a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dhu4i24hfhxvn"
path="res://.godot/imported/muyang-dog.png-faa1da78f374818f4f65cd75128b936f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resources/characterCards/muyang-dog.png"
dest_files=["res://.godot/imported/muyang-dog.png-faa1da78f374818f4f65cd75128b936f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
@@ -4,15 +4,16 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://b1aq0k7tf1p1"
path.s3tc="res://.godot/imported/kernyr.jpg-d82cf548a25a07dbd282dd92971a45c3.s3tc.ctex"
path.etc2="res://.godot/imported/kernyr.jpg-d82cf548a25a07dbd282dd92971a45c3.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://resources/characters/kernyr/kernyr.jpg"
dest_files=["res://.godot/imported/kernyr.jpg-d82cf548a25a07dbd282dd92971a45c3.s3tc.ctex"]
dest_files=["res://.godot/imported/kernyr.jpg-d82cf548a25a07dbd282dd92971a45c3.s3tc.ctex", "res://.godot/imported/kernyr.jpg-d82cf548a25a07dbd282dd92971a45c3.etc2.ctex"]
[params]
View File
+4
View File
@@ -0,0 +1,4 @@
extends PlayerBase
func summoned(entity: SummonBase):
entity.died.connect(func(): storeEnergy(10))
+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
+12
View File
@@ -0,0 +1,12 @@
extends PlayerBase
var parryCounter: CooldownTimer = CooldownTimer.new(3000)
func ai():
super.ai()
if parryCounter.isCooldowned():
var track = getTrackingAnchor()
var bullet = BulletTool.findClosetBulletCanDamage(track, get_tree(), self , 300)
if is_instance_valid(bullet):
BulletBase.generate(ComponentManager.getBullet("Parrier"), self , track, track.angle_to_point(bullet.position))
parryCounter.start()
@@ -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] = WorldManager.getTime()
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 = WorldManager.getTime()
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
+2 -2
View File
@@ -52,7 +52,7 @@ func tryLaunch(action: String, weaponIndex: int):
var weapon = weapons[weaponIndex]
if weapon.emitType == Weapon.EmitType.CHARGE:
if weapon.canAttackBy(self ):
chargeStartTime[weaponIndex] = Time.get_ticks_msec()
chargeStartTime[weaponIndex] = WorldManager.getTime()
chargeParticle.emitting = true
chargeParticle.speed_scale = 1
elif weapon.emitType == Weapon.EmitType.CLICK_SHOOT || weapon.emitType == Weapon.EmitType.HOLD_LOOP:
@@ -70,7 +70,7 @@ func tryLaunch(action: String, weaponIndex: int):
if weapon.emitType == Weapon.EmitType.CHARGE:
if chargeStartTime.has(weaponIndex):
var startTime = chargeStartTime[weaponIndex]
var endTime = Time.get_ticks_msec()
var endTime = WorldManager.getTime()
var chargedTime = endTime - startTime
chargeStartTime.erase(weaponIndex)
weapon.chargedTime = chargedTime * self.fields.get(FieldStore.Entity.CHARGE_SPEED)
+2 -21
View File
@@ -3,30 +3,11 @@ extends FullscreenPanelBase
@onready var audio: AudioStreamPlayer2D = $%audio
@onready var deadreason: RichTextLabel = $%deadreason
@onready var returnBtn: Button = $%returnBtn
@onready var exitBtn: Button = $%exitBtn
func _ready():
returnBtn.pressed.connect(
func():
returnBtn.disabled = true
for bullet in get_tree().get_nodes_in_group("bullets"):
bullet.queue_free()
for entity in get_tree().get_nodes_in_group("entities"):
entity.queue_free()
UIState.setPanel("Starter")
)
exitBtn.pressed.connect(
func():
get_tree().quit()
)
@onready var gameControl: GameControl = $%gameControl
func beforeOpen(args: Array = []):
audio.play()
var reasonTemplate = MathTool.randomChoiceFrom(GameRule.deadReasons)
deadreason.text = ("[color=gray]" + reasonTemplate + "凶手是[b]%s[/b]的[b]%s[/b]。[/color]") % args
for item in OutGameStorage.inventory:
OutGameStorage.inventory[item] += UIState.player.inventory[item]
func afterOpen(_args: Array = []):
returnBtn.disabled = false
exitBtn.disabled = false
gameControl.enable()
+4 -6
View File
@@ -1,10 +1,8 @@
@tool
extends FullscreenPanelBase
class_name PausePanel
@onready var aboutBtn: Button = $"%aboutBtn"
@onready var gameControl: GameControl = $%gameControl
func _ready():
aboutBtn.pressed.connect(
func():
UIState.setPanel("Thanks")
)
func afterOpen(_args: Array = []):
gameControl.enable()
+34 -4
View File
@@ -11,6 +11,8 @@ class_name StarterPanel
@onready var crystalShow: ItemShow = $%crystal
@onready var diamondShow: ItemShow = $%diamond
@onready var charactersBox: Control = $%characters
@onready var startSingleplayerBtn: Button = $%startSingleplayerBtn
@onready var startMultiplayerBtn: Button = $%startMultiplayerBtn
@onready var levelShow: Label = $%levelShow
@@ -27,9 +29,11 @@ class_name StarterPanel
var historyStack
static var GAMEMODE_MAP_WAVE = [Wave.WAVE_NORMAL, Wave.WAVE_BOSSRUSH, Wave.WAVE_MOWING]
static var START_CHARACTERS = ["MuyangDog", "Lynx", "HCN"]
static var buildingShader: bool = true
static var selectingFeed: bool = true
static var GAMEMODE_MAP_WAVE = [Wave.WAVE_NORMAL, Wave.WAVE_BOSSRUSH, Wave.WAVE_MOWING]
static var selectedCharacter: String = MathTool.randomChoiceFrom(START_CHARACTERS)
@rpc("any_peer")
func mutexPlayer(player: String):
@@ -72,16 +76,23 @@ 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")
if buildingShader:
UIState.setPanel("CompilingTip")
else:
UIState.setPanel("SelectInitialFeed")
func _ready():
historyStack = Composables.useHistoryStack(playerNameInput)
@@ -159,6 +170,9 @@ func getPlayerNames() -> Array[String]:
result.append(i.text)
return result
func getCurrentSelectedCharacter() -> CharacterCard:
return charactersBox.get_node(selectedCharacter as NodePath)
func beforeOpen(_args: Array = []):
diffEdit.min_value = GameRule.difficultyRange.x
diffEdit.max_value = GameRule.difficultyRange.y
@@ -191,3 +205,19 @@ func rebuildInfo():
rebuildInfo()
)
upgradeFieldsBox.add_child(fieldShow)
for child in charactersBox.get_children():
charactersBox.remove_child(child)
for character in START_CHARACTERS:
var card = ComponentManager.getCharacterCard(character).instantiate() as CharacterCard
card.select.connect(
func():
if card.name == selectedCharacter: return
getCurrentSelectedCharacter().animator.play("hide")
selectedCharacter = card.name
getCurrentSelectedCharacter().animator.play("show")
)
charactersBox.add_child(card)
if selectedCharacter == card.name:
card.animator.play("show")
else:
card.animator.play("hide")
+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()
+2 -2
View File
@@ -8,10 +8,10 @@ var distance: float = 200
var bullets: Array[BulletBase] = []
func start():
startTime = Time.get_ticks_msec()
startTime = WorldManager.getTime()
running = true
func lifetime():
return Time.get_ticks_msec() - startTime
return WorldManager.getTime() - startTime
func getStateAngle(index: int):
return lifetime() / period * deg_to_rad(360) - deg_to_rad(360.0 * index / len(bullets))
func forceFilter():
+1
View File
@@ -59,4 +59,5 @@ static func create(scene: PackedScene, spawnPosition: Vector2, parent: Node = nu
parent.add_child(cloned)
else:
WorldManager.rootNode.add_child(cloned)
cloned.add_to_group("effects")
return cloned
+15 -12
View File
@@ -136,10 +136,6 @@ func _ready():
if isPlayer():
if displayName == MultiplayerState.playerName:
UIState.player = self
if WorldManager.isRelease():
for i in weaponStore.get_children():
i.free()
weaponStore.add_child(ComponentManager.getWeapon("PurpleCrystal").instantiate())
for i in weaponStore.get_children():
i.hide()
weapons.append(i)
@@ -322,6 +318,7 @@ func collectItem(itemType: ItemStore.ItemType, amount: int):
UIState.showTip("[b]%s[/b]已自动强化!" % weapon.displayName)
func storeEnergy(value: float, dontChangeDirection: bool = false):
energy += value * fields.get(FieldStore.Entity.ENERGY_MULTIPILER)
energy = clamp(energy, 0, fields[FieldStore.Entity.MAX_ENERGY])
energyChanged.emit(energy, dontChangeDirection)
func finalEnergy(base: float):
return base / fields.get(FieldStore.Entity.SAVE_ENERGY)
@@ -419,7 +416,7 @@ func tryDie(by: BulletBase = null):
fields[FieldStore.Entity.MAX_HEALTH] * randf_range(1 - GameRule.beachballOffset, 1 + GameRule.beachballOffset),
position + MathTool.sampleInCircle(GameRule.itemDroppedSpawnOffset)
)
for i in randi_range(0, 10 if isBoss else 3):
for i in randi_range(0, 20 if isBoss else 5):
ItemDropped.generate(
ItemStore.ItemType.CRYSTAL,
5 if isBoss else 1,
@@ -447,7 +444,8 @@ func tryDie(by: BulletBase = null):
UIState.showTip("[b]%s[/b] 已被打败!" % displayName, TipBox.MessageType.CONGRATULATION)
elif isPlayer():
UIState.showTip("[b]%s[/b] 似了😭。" % displayName, TipBox.MessageType.ERROR)
queue_free()
if !isPlayer() || isSummon():
queue_free()
func tryHeal(count: float):
playSound("heal")
healed.emit(heal(count * fields.get(FieldStore.Entity.HEAL_ABILITY)))
@@ -505,6 +503,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 +549,21 @@ 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
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 +572,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:
+25
View File
@@ -0,0 +1,25 @@
extends Control
class_name GameControl
@onready var returnBtn: Button = $%returnBtn
@onready var exitBtn: Button = $%exitBtn
func _ready():
returnBtn.pressed.connect(
func():
disable()
GameBusManager.restart(get_tree())
)
exitBtn.pressed.connect(
func():
disable()
get_tree().quit()
)
enable()
func enable():
returnBtn.disabled = false
exitBtn.disabled = false
func disable():
returnBtn.disabled = true
exitBtn.disabled = true
+1
View File
@@ -0,0 +1 @@
uid://b63fkg0waovo
+1
View File
@@ -64,6 +64,7 @@ static func generate(
WorldManager.rootNode.call_deferred("add_child", instance)
instance.add_to_group("drops")
instance.refindPlayer(WorldManager.tree)
instance.add_to_group("items")
return instance
static func getDrops() -> Array[ItemDropped]:
var result: Array[ItemDropped] = []
+1
View File
@@ -31,6 +31,7 @@ func _process(_delta):
label.text = text
func destroy():
if animator.is_playing(): return
animator.play("hide")
await animator.animation_finished
queue_free()
+30 -11
View File
@@ -15,6 +15,8 @@ static var tips: VBoxContainer
static var itemsContainer: Control
static var energyContainer: Control
static var showingFields: bool = false
func _ready():
bossbar = $%bossbar
panels = $%panels
@@ -43,17 +45,14 @@ func _physics_process(_delta):
bossbar.visible = true
itemsContainer.visible = true
energyContainer.visible = true
if Input.is_action_just_pressed("showFields"):
for i in fields.get_children():
fields.remove_child(i)
for i in player.fields:
if player.fields[i] == EntityBase.TITLE_FLAG:
fields.add_child(QuickUI.graySmallText(i))
else:
fields.add_child(FieldShow.create(i, player.fields[i], false, player, true))
fieldsAnimator.play("show")
if Input.is_action_just_released("showFields"):
fieldsAnimator.play("hide")
if !fieldsAnimator.is_playing():
if showingFields:
if Input.is_action_just_released("showFields") || !(currentPanel is PausePanel):
hideFields()
else:
if Input.is_action_just_pressed("showFields") || currentPanel is PausePanel:
showFields()
if Input.is_action_just_pressed("pause"):
if currentPanel:
if currentPanel is MakeFeedPanel:
@@ -92,8 +91,28 @@ static func setPanel(targetName: String = "", args: Array = []):
panel.hidePanel()
static func closeCurrentPanel():
setPanel()
static func showTip(text: String, messageType: TipBox.MessageType = TipBox.MessageType.INFO):
var box = TipBox.create(text, messageType)
tips.add_child(box)
await box.animator.animation_finished
await TickTool.millseconds(500 * len(text))
box.destroy()
static func clearTips():
for child in tips.get_children():
if child is TipBox:
child.destroy()
static func showFields():
showingFields = true
for i in fields.get_children():
fields.remove_child(i)
for i in player.fields:
if player.fields[i] == EntityBase.TITLE_FLAG:
fields.add_child(QuickUI.graySmallText(i))
else:
fields.add_child(FieldShow.create(i, player.fields[i], false, player, true))
fieldsAnimator.play("show")
static func hideFields():
showingFields = false
fieldsAnimator.play("hide")
+13
View File
@@ -0,0 +1,13 @@
class_name Watcher
signal changed()
var currentState = null
func _init(initialState):
currentState = initialState
func setState(newState):
if newState != currentState:
currentState = newState
changed.emit()
+1
View File
@@ -0,0 +1 @@
uid://7uhyhrta5ld1
+56
View File
@@ -0,0 +1,56 @@
@tool
extends Control
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] = []
@export var fieldValues: Array[float] = []
@export var clickToRebuild: bool = false
@export var borderOpacity: float = 0
@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
var watcher: Watcher = Watcher.new(false)
@onready var panelStyleBox: StyleBoxFlat = get_theme_stylebox("panel").duplicate()
func _ready():
add_theme_stylebox_override("panel", panelStyleBox)
watcher.changed.connect(rebuildInfo)
gui_input.connect(
func(event):
if event is InputEventMouseButton:
if !(event.pressed && event.button_index == MouseButton.MOUSE_BUTTON_LEFT): return
if animator.is_playing(): return
select.emit()
)
rebuildInfo()
func _process(_delta):
watcher.setState(clickToRebuild)
panelStyleBox.border_width_top = int(10 * borderOpacity)
panelStyleBox.border_width_bottom = int(10 * borderOpacity)
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)
for index in len(fields):
var field = fields[index]
var value = fieldValues[index]
var fieldShow = ComponentManager.getUIComponent("FieldShow").instantiate() as FieldShow
fieldShow.field = field
fieldShow.showAdvantage = true
fieldShow.value = value
fieldsBox.add_child(fieldShow)
+1
View File
@@ -0,0 +1 @@
uid://cd1xb8m6rvoph
+6 -4
View File
@@ -49,10 +49,11 @@ func apply(entity: EntityBase):
for i in range(min(fields.size(), fieldValues.size())):
var field = fields[i]
var value = fieldValues[i]
entity.fields[field] += value
var applier = FieldStore.entityApplier.get(field)
if !applier or applier.call(entity, value):
entity.fields[field] += value
entity.fields[field] = clamp(entity.fields[field], FieldStore.entityMinValueMap.get(field, 0), FieldStore.entityMaxValueMap.get(field, INF))
if applier and applier.call(entity, value):
entity.fields[field] -= value
entity.fields[field] = clamp(entity.fields[field], FieldStore.entityMinValueMap.get(field, 0), FieldStore.entityMaxValueMap.get(field, INF))
for i in weapons:
var instance = i.instantiate() as Weapon
if UIState.player.weaponBag.has(instance.displayName):
@@ -71,7 +72,8 @@ func apply(entity: EntityBase):
selected.emit(allHave)
return allHave
func countOf(index: int) -> int:
return ceil(costCounts[index] * multipiler())
var base = costCounts[index]
return ceil(base * multipiler()) if base > 0 else floor(base / multipiler())
func multipiler() -> float:
if is_instance_valid(UIState.player):
return 1 - UIState.player.fields.get(FieldStore.Entity.PRICE_REDUCTION)
+6
View File
@@ -87,6 +87,8 @@ func _ready():
soulLevel -= 1
updateStore(level, UIState.player)
rebuildInfo()
else:
UIState.showTip("[b]%s[/b]还未镶嵌任何灵魂!" % displayName, TipBox.MessageType.ERROR)
)
inlayBtn.pressed.connect(
func():
@@ -97,6 +99,10 @@ func _ready():
soulLevel += 1
updateStore(level, UIState.player)
rebuildInfo()
else:
UIState.showTip("持有的灵魂数量不足!", TipBox.MessageType.ERROR)
else:
UIState.showTip("[b]%s[/b]的灵魂槽位已满!" % displayName, TipBox.MessageType.ERROR)
)
moveLeftBtn.pressed.connect(
func():
+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
+1
View File
@@ -1,6 +1,7 @@
class_name GameRule
static var deadReasons: Array = JsonTool.parseJson("res://resources/constants/deadReasons.json")
static var helpText: String
static var difficultyRange: Vector2 = Vector2(-20, 50) # 难度倍数范围,包括最小值和最大值,负数则降低难度
static var difficulty: float = 1 # 难度倍数,可以写小数
static var allowFriendlyFire: bool = false # 是否允许友军伤害
+6 -2
View File
@@ -7,6 +7,7 @@ class_name CameraManager
@onready var animator: AnimationPlayer = $"%animator"
var shakeIntensity: float = 0
var shaking: bool = false
static var instance: CameraManager = null
@@ -16,7 +17,7 @@ func _physics_process(_delta):
if is_instance_valid(UIState.player):
position = UIState.player.position + constantOffset
position += MathTool.sampleInCircle(shakeIntensity)
offset += ((get_global_mouse_position() - UIState.player.position).clampf(-100, 100) - offset) * 0.15
position += MouseTool.getPositionByScreen(Vector2.ONE * 0.5, self ) / 2
static func shake(millseconds: float, intensity: float = 10, steper: Callable = func(currentValue, _totalValue, _restPercent): return currentValue):
if StarterPanel.buildingShader: return
@@ -25,8 +26,11 @@ static func shake(millseconds: float, intensity: float = 10, steper: Callable =
await TickTool.until(
func():
instance.shakeIntensity = steper.call(instance.shakeIntensity, intensity, 1 - (WorldManager.getTime() - startTime) / millseconds)
return WorldManager.getTime() - startTime >= millseconds
return WorldManager.getTime() - startTime >= millseconds || !instance.shaking
)
instance.shakeIntensity = 0
static func shakeStop():
instance.shaking = false
instance.shakeIntensity = 0
static func playAnimation(animation: String):
instance.animator.play(animation)
@@ -4,6 +4,7 @@ class_name ComponentManager
static var abstracts = {}
static var bullets = {}
static var characterCards = {}
static var characters = {}
static var weapons = {}
static var summons = {}
@@ -21,6 +22,8 @@ static func init():
abstracts[DirTool.getBasenameWithoutExtension(i)] = load(i)
for i in DirTool.listdir("res://components/Bullets"):
bullets[DirTool.getBasenameWithoutExtension(i)] = load(i)
for i in DirTool.listdir("res://components/CharacterCards"):
characterCards[DirTool.getBasenameWithoutExtension(i)] = load(i)
for i in DirTool.listdir("res://components/Characters"):
characters[DirTool.getBasenameWithoutExtension(i)] = load(i)
for i in DirTool.listdir("res://components/Weapons"):
@@ -48,6 +51,8 @@ static func getAbstract(t: String) -> PackedScene:
return MathTool.priority(abstracts.get(t, false), load("res://components/Abstracts/%s.tscn" % t))
static func getBullet(t: String) -> PackedScene:
return MathTool.priority(bullets.get(t, false), load("res://components/Bullets/%s.tscn" % t))
static func getCharacterCard(t: String) -> PackedScene:
return MathTool.priority(characterCards.get(t, false), load("res://components/CharacterCards/%s.tscn" % t))
static func getCharacter(t: String) -> PackedScene:
return MathTool.priority(characters.get(t, false), load("res://components/Characters/%s.tscn" % t))
static func getWeapon(t: String) -> PackedScene:
+19
View File
@@ -0,0 +1,19 @@
class_name GameBusManager
static func restart(tree: SceneTree):
for bullet in tree.get_nodes_in_group("bullets"):
bullet.queue_free()
for entity in tree.get_nodes_in_group("entities"):
entity.queue_free()
for effect in tree.get_nodes_in_group("effects"):
effect.queue_free()
for item in tree.get_nodes_in_group("items"):
item.queue_free()
UIState.hideFields()
OutGameStorage.saveInventory()
CameraManager.shakeStop()
WorldManager.timeRestart()
StarterPanel.selectingFeed = true
UIState.setPanel("Starter")
@@ -0,0 +1 @@
uid://cf1agt55tt4pu
+2
View File
@@ -38,6 +38,8 @@ func spawn(node: Node):
func justReturn(data):
return ArrayTool.parseEncodedObject(data)[0]
static func timeRestart():
runningTime = 0
static func getTime():
return runningTime
static func spawnNode(node: Node):
+5
View File
@@ -0,0 +1,5 @@
class_name MouseTool
static func getPositionByScreen(anchor: Vector2, by: Node):
var viewport = by.get_viewport()
return viewport.get_mouse_position() - viewport.get_visible_rect().size * anchor
+1
View File
@@ -0,0 +1 @@
uid://yf2h5ni3gobm
+4
View File
@@ -19,3 +19,7 @@ static var upgradableFieldsLevel = ArrayTool.fill(upgradableFieldsAdvance, func(
static var maxInitialFeedCount: int = 3
static var maxInitialWeaponCount: int = 3
static var inventory = ArrayTool.fill(upgradableFieldsCost, func(_k): return 0)
static func saveInventory():
for item in OutGameStorage.inventory:
OutGameStorage.inventory[item] += UIState.player.inventory[item]
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 KiB

-15
View File
@@ -1,18 +1,3 @@
# Todo
1. 完成Godockly UGC框架。
2. 设计新boss
## 新boss
主题:强大的防御能力+近战攻击。
### 招式
1. 使用**扫帚**进行4段挥舞攻击,上挑-下批-短戳-突刺(cooldown=6s
2. **扫帚**蓄力0.5s,向玩家冲刺,**距离足够近或冲刺结束**后挥出武器(蓄力+攻击互斥)
3. 召唤3把**扫帚炮**,每0.2s释放发射一柱**灰尘射线**cooldown=10s
4. 召唤**自旋扫帚**,每1秒旋转1圈,此时boss移速+100%cooldown=8s,蓄力)
5. 发射**扫帚回旋镖**,可飞行1秒后回旋(攻击互斥)
6. 发动**格挡**,抵挡玩家的近战或射弹伤害(cooldown=2s
7. 发动**闪避**,侧向冲刺躲避离自身最近的玩家子弹(cooldown=5s