mirror of
https://github.com/Rundll86/Dog-Lynx-And-HCN.git
synced 2026-05-28 06:51:54 +08:00
feat(角色): 为熊角色添加阶段转换功能
添加阶段转换系统,当熊的生命值低于50%时进入第二阶段 - 添加mask精灵用于阶段变化视觉效果 - 实现enterStage和exitStage方法处理阶段转换 - 添加stageAnimator处理转换动画 - 调整攻击7的音效播放位置
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=36 format=3 uid="uid://cvogxi7mktumf"]
|
||||
[gd_scene load_steps=40 format=3 uid="uid://cvogxi7mktumf"]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/Statemachine/EntityBase.gd" id="1_mvol6"]
|
||||
[ext_resource type="Texture2D" uid="uid://dwwpkn4q07ja2" path="res://icon.svg" id="2_7lpu0"]
|
||||
@@ -169,6 +169,123 @@ _data = {
|
||||
"hurt": SubResource("Animation_wl2we")
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_n7kxn"]
|
||||
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(1, -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(1, -0.25, 0, 0.25, 0),
|
||||
"times": PackedFloat32Array(0)
|
||||
}
|
||||
tracks/2/type = "bezier"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath(".:modulate:a")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"handle_modes": PackedInt32Array(0),
|
||||
"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0),
|
||||
"times": PackedFloat32Array(0)
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_lg0kn"]
|
||||
resource_name = "exit"
|
||||
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(2, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0),
|
||||
"times": PackedFloat32Array(0, 1)
|
||||
}
|
||||
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, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0),
|
||||
"times": PackedFloat32Array(0, 1)
|
||||
}
|
||||
tracks/2/type = "bezier"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath(".:modulate:a")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"handle_modes": PackedInt32Array(0, 0),
|
||||
"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0, 1, -0.25, 0, 0.25, 0),
|
||||
"times": PackedFloat32Array(0, 1)
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_nfj4q"]
|
||||
resource_name = "exit"
|
||||
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.25, 0, 0.25, 0, 2, -0.25, 0, 0.25, 0),
|
||||
"times": PackedFloat32Array(0, 1)
|
||||
}
|
||||
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(1, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0),
|
||||
"times": PackedFloat32Array(0, 1)
|
||||
}
|
||||
tracks/2/type = "bezier"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath(".:modulate:a")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"handle_modes": PackedInt32Array(0, 0),
|
||||
"points": PackedFloat32Array(1, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0),
|
||||
"times": PackedFloat32Array(0, 1)
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_vvkcp"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_n7kxn"),
|
||||
"enter": SubResource("Animation_lg0kn"),
|
||||
"exit": SubResource("Animation_nfj4q")
|
||||
}
|
||||
|
||||
[sub_resource type="Curve" id="Curve_cs3iy"]
|
||||
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 2
|
||||
@@ -280,7 +397,6 @@ stream = ExtResource("2_qt0aq")
|
||||
[node name="texture" type="AnimatedSprite2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
position = Vector2(0, -50)
|
||||
scale = Vector2(-1, 1)
|
||||
sprite_frames = SubResource("SpriteFrames_wcqpm")
|
||||
animation = &"idle"
|
||||
|
||||
@@ -309,6 +425,12 @@ libraries = {
|
||||
"": SubResource("AnimationLibrary_kbmff")
|
||||
}
|
||||
|
||||
[node name="stageAnimator" type="AnimationPlayer" parent="texture"]
|
||||
unique_name_in_owner = true
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_vvkcp")
|
||||
}
|
||||
|
||||
[node name="weapons" type="Node2D" parent="texture"]
|
||||
unique_name_in_owner = true
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=26 format=3 uid="uid://m60bwhdpbem8"]
|
||||
[gd_scene load_steps=30 format=3 uid="uid://m60bwhdpbem8"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://cvogxi7mktumf" path="res://components/Abstracts/EntityBase.tscn" id="1_3ves7"]
|
||||
[ext_resource type="Script" path="res://scripts/Contents/Characters/Bear.gd" id="2_kh2af"]
|
||||
@@ -34,6 +34,58 @@ animations = [{
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_akdh6"]
|
||||
size = Vector2(335, 344)
|
||||
|
||||
[sub_resource type="Animation" id="Animation_sxh2u"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath(".:scale")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_vxanw"]
|
||||
resource_name = "left"
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath(".:scale")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(-1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_nuh11"]
|
||||
resource_name = "left"
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath(".:scale")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_dwflo"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_sxh2u"),
|
||||
"left": SubResource("Animation_vxanw"),
|
||||
"right": SubResource("Animation_nuh11")
|
||||
}
|
||||
|
||||
[sub_resource type="Curve" id="Curve_u430e"]
|
||||
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.2, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 3
|
||||
@@ -125,6 +177,11 @@ visible = false
|
||||
position = Vector2(-2.5, -1)
|
||||
shape = SubResource("RectangleShape2D_akdh6")
|
||||
|
||||
[node name="animator" parent="texture" index="1"]
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_dwflo")
|
||||
}
|
||||
|
||||
[node name="normal" type="Node2D" parent="texture/weapons" index="0"]
|
||||
|
||||
[node name="sprintParticle" type="GPUParticles2D" parent="texture" index="6"]
|
||||
@@ -136,6 +193,8 @@ process_material = SubResource("ParticleProcessMaterial_5v3nj")
|
||||
texture = ExtResource("13_v2sdb")
|
||||
|
||||
[node name="mask" type="Sprite2D" parent="texture" index="7"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
material = SubResource("ShaderMaterial_6h05p")
|
||||
texture = ExtResource("13_v2sdb")
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ extends EntityBase
|
||||
class_name Bear # 攻击方式模仿泰拉瑞亚光之女皇
|
||||
|
||||
@onready var sprintParticle: GPUParticles2D = $"%sprintParticle"
|
||||
@onready var mask: Sprite2D = $"%mask"
|
||||
|
||||
func register():
|
||||
fields[FieldStore.Entity.MAX_HEALTH] = 2000
|
||||
@@ -15,12 +16,19 @@ func register():
|
||||
attackCooldownMap[6] = 10000
|
||||
attackCooldownMap[7] = 9000
|
||||
sprintMultiplier = 80
|
||||
healthChanged.connect(
|
||||
func(newHealth):
|
||||
setStage(1 if newHealth < fields[FieldStore.Entity.MAX_HEALTH] * 0.5 else 0)
|
||||
)
|
||||
func spawn():
|
||||
texture.play("walk")
|
||||
func ai():
|
||||
PresetEntityAI.follow(self, currentFocusedBoss, 400)
|
||||
for i in len(attackCooldownMap.keys()):
|
||||
tryAttack(i)
|
||||
func enterStage(stage):
|
||||
mask.visible = !!stage
|
||||
await TickTool.millseconds(2000)
|
||||
func attack(type):
|
||||
var weaponPos = findWeaponAnchor("normal")
|
||||
if type == 0:
|
||||
@@ -82,11 +90,11 @@ func attack(type):
|
||||
await TickTool.millseconds(100)
|
||||
return false
|
||||
elif type == 7:
|
||||
playSound("attack7")
|
||||
var angle = deg_to_rad(70)
|
||||
for j in 4:
|
||||
var initAngle = randf_range(0, 360)
|
||||
if !is_instance_valid(currentFocusedBoss): return false
|
||||
playSound("attack7")
|
||||
for i in 16:
|
||||
for bullet in BulletBase.generate(preload("res://components/Bullets/BossAttack/Bear/LightGun.tscn"), self, currentFocusedBoss.position, 0):
|
||||
bullet.rotation_degrees += initAngle
|
||||
|
||||
@@ -78,6 +78,7 @@ var inventoryMax = {
|
||||
@onready var hurtbox: Area2D = $"%hurtbox"
|
||||
@onready var sounds: Node2D = $"%sounds"
|
||||
@onready var hurtAnimator: AnimationPlayer = $"%hurtAnimator"
|
||||
@onready var stageAnimator: AnimationPlayer = $"%stageAnimator"
|
||||
@onready var damageAnchor: Node2D = $"%damageAnchor"
|
||||
@onready var trailParticle: GPUParticles2D = $"%trailParticle"
|
||||
@onready var weaponStore = $"%weaponStore"
|
||||
@@ -94,6 +95,7 @@ var currentFocusedBoss: EntityBase = null
|
||||
var charginup: bool = false
|
||||
var weapons: Array[Weapon] = []
|
||||
var canRunAi: bool = true
|
||||
var currentStage: int = 0
|
||||
|
||||
func _ready():
|
||||
register()
|
||||
@@ -164,6 +166,19 @@ func _physics_process(_delta: float) -> void:
|
||||
trailParticle.emitting = trailing
|
||||
|
||||
# 通用方法
|
||||
func setStage(stage: int):
|
||||
if currentStage == stage:
|
||||
return
|
||||
canRunAi = false
|
||||
var oldStage = currentStage
|
||||
currentStage = stage
|
||||
stageAnimator.play("exit")
|
||||
await stageAnimator.animation_finished
|
||||
await exitStage(oldStage)
|
||||
await enterStage(stage)
|
||||
stageAnimator.play("enter")
|
||||
await stageAnimator.animation_finished
|
||||
canRunAi = true
|
||||
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
|
||||
@@ -342,6 +357,10 @@ func register():
|
||||
pass
|
||||
func spawn():
|
||||
pass
|
||||
func exitStage(_stage: int):
|
||||
pass
|
||||
func enterStage(_stage: int):
|
||||
pass
|
||||
|
||||
static func generate(
|
||||
entity: PackedScene,
|
||||
|
||||
Reference in New Issue
Block a user