mirror of
https://github.com/Rundll86/Dog-Lynx-And-HCN.git
synced 2026-07-02 08:12:12 +08:00
feat(实体系统): 添加敌人等级系统并调整相关UI和游戏规则
为敌人实体添加等级属性,影响生命值和伤害 在状态栏和Boss血条中显示等级信息 调整游戏规则增加难度相关的属性成长系数 修改粒子效果角度和波次生成逻辑
This commit is contained in:
@@ -53,6 +53,22 @@ layout_mode = 2
|
|||||||
text = "BossName"
|
text = "BossName"
|
||||||
label_settings = SubResource("LabelSettings_esyuk")
|
label_settings = SubResource("LabelSettings_esyuk")
|
||||||
|
|
||||||
|
[node name="lv" type="Label" parent="health/panel/label"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Lv."
|
||||||
|
label_settings = SubResource("LabelSettings_esyuk")
|
||||||
|
|
||||||
|
[node name="level" type="Label" parent="health/panel/label"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "100"
|
||||||
|
label_settings = SubResource("LabelSettings_esyuk")
|
||||||
|
|
||||||
|
[node name="sep" type="Label" parent="health/panel/label"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = " - "
|
||||||
|
label_settings = SubResource("LabelSettings_esyuk")
|
||||||
|
|
||||||
[node name="value" type="Label" parent="health/panel/label"]
|
[node name="value" type="Label" parent="health/panel/label"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
[gd_scene load_steps=3 format=3 uid="uid://dcjqjqere8ets"]
|
[gd_scene load_steps=4 format=3 uid="uid://dcjqjqere8ets"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://d1ulrvupa76ap" path="res://components/UI/ColorBar.tscn" id="1_0ngbn"]
|
[ext_resource type="PackedScene" uid="uid://d1ulrvupa76ap" path="res://components/UI/ColorBar.tscn" id="1_0ngbn"]
|
||||||
[ext_resource type="Script" path="res://scripts/Statemachine/EntityStateBar.gd" id="1_ovbjr"]
|
[ext_resource type="Script" path="res://scripts/Statemachine/EntityStateBar.gd" id="1_ovbjr"]
|
||||||
|
|
||||||
|
[sub_resource type="LabelSettings" id="LabelSettings_ih2pl"]
|
||||||
|
font_size = 13
|
||||||
|
|
||||||
[node name="EntityStateBar" type="Node2D"]
|
[node name="EntityStateBar" type="Node2D"]
|
||||||
script = ExtResource("1_ovbjr")
|
script = ExtResource("1_ovbjr")
|
||||||
|
|
||||||
@@ -12,3 +15,27 @@ offset_left = -50.0
|
|||||||
offset_top = -5.0
|
offset_top = -5.0
|
||||||
offset_right = 50.0
|
offset_right = 50.0
|
||||||
offset_bottom = 5.0
|
offset_bottom = 5.0
|
||||||
|
|
||||||
|
[node name="levelLabel" type="HBoxContainer" parent="health"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = -1
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = -2.0
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = -2.0
|
||||||
|
offset_left = -25.0
|
||||||
|
offset_right = 26.0
|
||||||
|
offset_bottom = 19.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="tip" type="Label" parent="health/levelLabel"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 8
|
||||||
|
text = "Lv."
|
||||||
|
label_settings = SubResource("LabelSettings_ih2pl")
|
||||||
|
|
||||||
|
[node name="level" type="Label" parent="health/levelLabel"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "100"
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ particle_flag_disable_z = true
|
|||||||
emission_shape = 1
|
emission_shape = 1
|
||||||
emission_sphere_radius = 15.0
|
emission_sphere_radius = 15.0
|
||||||
angle_min = 1.07288e-05
|
angle_min = 1.07288e-05
|
||||||
angle_max = 720.0
|
angle_max = 90.0
|
||||||
angle_curve = SubResource("CurveTexture_orbge")
|
angle_curve = SubResource("CurveTexture_orbge")
|
||||||
gravity = Vector3(0, 0, 0)
|
gravity = Vector3(0, 0, 0)
|
||||||
scale_min = 5.0
|
scale_min = 5.0
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ static var current: int = 0
|
|||||||
static var data: Array[Wave] = [
|
static var data: Array[Wave] = [
|
||||||
# entity, minCount, maxCount, isBoss, from, to, per
|
# entity, minCount, maxCount, isBoss, from, to, per
|
||||||
create(preload("res://components/Characters/Hen.tscn"), 1, 5, false, 0, INF, 1),
|
create(preload("res://components/Characters/Hen.tscn"), 1, 5, false, 0, INF, 1),
|
||||||
create(preload("res://components/Characters/Chick.tscn"), 0, 0, true, 8, INF, 4)
|
create(preload("res://components/Characters/Chick.tscn"), 0, 0, true, 1, INF, 4)
|
||||||
]
|
]
|
||||||
|
|
||||||
static func create(
|
static func create(
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ var inventoryMax = {
|
|||||||
@export var drops: Array[ItemStore.ItemType] = []
|
@export var drops: Array[ItemStore.ItemType] = []
|
||||||
@export var dropCounts: Array[Vector2] = []
|
@export var dropCounts: Array[Vector2] = []
|
||||||
@export var appleCount: Vector2i = Vector2(0, 3) # 死亡后掉落的苹果数量
|
@export var appleCount: Vector2i = Vector2(0, 3) # 死亡后掉落的苹果数量
|
||||||
|
@export var level: int = 1 # 等级
|
||||||
|
|
||||||
@onready var animatree: AnimationTree = $"%animatree"
|
@onready var animatree: AnimationTree = $"%animatree"
|
||||||
@onready var texture: AnimatedSprite2D = $"%texture"
|
@onready var texture: AnimatedSprite2D = $"%texture"
|
||||||
@@ -72,6 +73,7 @@ func _ready():
|
|||||||
else:
|
else:
|
||||||
statebar = selfStatebar
|
statebar = selfStatebar
|
||||||
statebar.entity = self
|
statebar.entity = self
|
||||||
|
applyLevel()
|
||||||
health = fields.get(FieldStore.Entity.MAX_HEALTH)
|
health = fields.get(FieldStore.Entity.MAX_HEALTH)
|
||||||
energy = fields.get(FieldStore.Entity.MAX_ENERGY) * 0.5
|
energy = fields.get(FieldStore.Entity.MAX_ENERGY) * 0.5
|
||||||
if isPlayer():
|
if isPlayer():
|
||||||
@@ -98,9 +100,7 @@ func _ready():
|
|||||||
currentFocusedBoss = get_tree().get_nodes_in_group("players")[0]
|
currentFocusedBoss = get_tree().get_nodes_in_group("players")[0]
|
||||||
healthChanged.connect(
|
healthChanged.connect(
|
||||||
func(newHealth):
|
func(newHealth):
|
||||||
if is_instance_valid(statebar) or UIState.bossbar.entity == self:
|
if is_instance_valid(statebar):
|
||||||
if isBoss:
|
|
||||||
statebar = UIState.bossbar
|
|
||||||
statebar.healthBar.maxValue = fields.get(FieldStore.Entity.MAX_HEALTH)
|
statebar.healthBar.maxValue = fields.get(FieldStore.Entity.MAX_HEALTH)
|
||||||
statebar.healthBar.setCurrent(newHealth)
|
statebar.healthBar.setCurrent(newHealth)
|
||||||
)
|
)
|
||||||
@@ -111,6 +111,13 @@ func _process(_delta):
|
|||||||
energy = clamp(energy, 0, fields.get(FieldStore.Entity.MAX_ENERGY))
|
energy = clamp(energy, 0, fields.get(FieldStore.Entity.MAX_ENERGY))
|
||||||
for i in inventory:
|
for i in inventory:
|
||||||
inventory[i] = clamp(inventory[i], 0, inventoryMax[i])
|
inventory[i] = clamp(inventory[i], 0, inventoryMax[i])
|
||||||
|
if isBoss:
|
||||||
|
if UIState.player.currentFocusedBoss == self:
|
||||||
|
statebar = UIState.bossbar
|
||||||
|
else:
|
||||||
|
statebar = null
|
||||||
|
if is_instance_valid(statebar):
|
||||||
|
statebar.levelLabel.text = str(level)
|
||||||
func _physics_process(_delta: float) -> void:
|
func _physics_process(_delta: float) -> void:
|
||||||
animatree.set("parameters/blend_position", lerpf(animatree.get("parameters/blend_position"), lastDirection, 0.2))
|
animatree.set("parameters/blend_position", lerpf(animatree.get("parameters/blend_position"), lastDirection, 0.2))
|
||||||
if sprinting:
|
if sprinting:
|
||||||
@@ -125,6 +132,9 @@ func _physics_process(_delta: float) -> void:
|
|||||||
storeEnergy(0.01)
|
storeEnergy(0.01)
|
||||||
|
|
||||||
# 通用方法
|
# 通用方法
|
||||||
|
func applyLevel():
|
||||||
|
fields[FieldStore.Entity.MAX_HEALTH] *= (1 + GameRule.entityHealthIncreasePerWave * (GameRule.difficulty + 1)) ** level
|
||||||
|
fields[FieldStore.Entity.DAMAGE_MULTIPILER] *= (1 + GameRule.entityDamageIncreasePerWave * (GameRule.difficulty + 1)) ** level
|
||||||
func displace(direction: Vector2, isSprinting: bool = false):
|
func displace(direction: Vector2, isSprinting: bool = false):
|
||||||
return (direction if isSprinting else direction.normalized()) * fields.get(FieldStore.Entity.MOVEMENT_SPEED) * 400 * abs(animatree.get("parameters/blend_position"))
|
return (direction if isSprinting else direction.normalized()) * fields.get(FieldStore.Entity.MOVEMENT_SPEED) * 400 * abs(animatree.get("parameters/blend_position"))
|
||||||
func move(direction: Vector2, isSprinting: bool = false):
|
func move(direction: Vector2, isSprinting: bool = false):
|
||||||
@@ -246,6 +256,7 @@ static func generate(
|
|||||||
var instance: EntityBase = entity.instantiate()
|
var instance: EntityBase = entity.instantiate()
|
||||||
instance.position = spawnPosition
|
instance.position = spawnPosition
|
||||||
instance.isBoss = spawnAsBoss
|
instance.isBoss = spawnAsBoss
|
||||||
|
instance.level = clamp((round(Wave.current * (1 + GameRule.entityLevelOffsetByWave * randf_range(-1, 1)))), 1, INF)
|
||||||
if isMob:
|
if isMob:
|
||||||
instance.add_to_group("mobs")
|
instance.add_to_group("mobs")
|
||||||
if addToWorld:
|
if addToWorld:
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ class_name EntityStateBar
|
|||||||
@export var entity: EntityBase
|
@export var entity: EntityBase
|
||||||
|
|
||||||
@onready var healthBar: ColorBar = $"%health"
|
@onready var healthBar: ColorBar = $"%health"
|
||||||
|
@onready var levelLabel: Label = $"%level"
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
class_name GameRule
|
class_name GameRule
|
||||||
|
|
||||||
|
enum Difficulty {
|
||||||
|
EASY,
|
||||||
|
NORMAL,
|
||||||
|
HARD,
|
||||||
|
INSANE,
|
||||||
|
EXPERT,
|
||||||
|
MASTER,
|
||||||
|
}
|
||||||
|
static var difficulty: Difficulty = Difficulty.NORMAL
|
||||||
static var allowFriendlyFire: bool = false # 是否允许友军伤害
|
static var allowFriendlyFire: bool = false # 是否允许友军伤害
|
||||||
static var bulletSpeedMultiplier: float = 1 # 子弹速度倍率
|
static var bulletSpeedMultiplier: float = 1 # 子弹速度倍率
|
||||||
static var damageOffset: float = 0.2 # 伤害随机浮动比例,默认20%,即10的基础伤害会应用为8~12
|
static var damageOffset: float = 0.2 # 伤害随机浮动比例,默认20%,即10的基础伤害会应用为8~12
|
||||||
@@ -10,3 +19,6 @@ static var refreshCountIncreasePercent: Vector2 = Vector2(0.4, 1.1) # 刷新所
|
|||||||
static var entityCountBoostPerWave: float = 0.1 # 每波敌人数量增加的百分比,倍数级
|
static var entityCountBoostPerWave: float = 0.1 # 每波敌人数量增加的百分比,倍数级
|
||||||
static var itemShowStayTime: int = 1500 # 物品展示组件如果设置了自动隐藏,那么隐藏前可以存活的时间
|
static var itemShowStayTime: int = 1500 # 物品展示组件如果设置了自动隐藏,那么隐藏前可以存活的时间
|
||||||
static var tipSpawnRateWhenGetDroppedItem: float = 0.25 # 当玩家获取到掉落物时,提示的概率
|
static var tipSpawnRateWhenGetDroppedItem: float = 0.25 # 当玩家获取到掉落物时,提示的概率
|
||||||
|
static var entityHealthIncreasePerWave: float = 0.1 # 每波敌人生命值增加的百分比,指数级
|
||||||
|
static var entityDamageIncreasePerWave: float = 0.05 # 每波敌人伤害增加的百分比,指数级
|
||||||
|
static var entityLevelOffsetByWave: float = 0.3 # 每波敌人等级根据当前波数随机浮动的比例
|
||||||
Reference in New Issue
Block a user