extends CharacterBody2D @onready var bullet = preload("res://scene/entities/bullet.tscn") @onready var animated_sprite = $AnimatedSprite2D @onready var muzzle = $FIRE @onready var TimerFIRE = $TimerFIRE @onready var hurt_timer = $Timerinvincibility const SPEED = 140.0 const JUMP_VELOCITY = -230.0 const JUMP_MAX = 2 var JUMP_COUNT = 0 var HP = 3 var invincibility = false var is_jump : bool = false var respawn_position @onready var hp_icons = [ $HP_Block, # 对应第1滴血 $HP_Block2, # 对应第2滴血 $HP_Block3 # 对应第3滴血 ] const MAX_HP = 3 # 最大血量 # 刷新 UI 的核心函数 func _update_hp_ui(): # 遍历所有的生命图标 for i in range(hp_icons.size()): # 如果索引小于当前HP,就显示,否则隐藏 # 比如 HP=2,那么 i=0(显示)、i=1(显示)、i=2(隐藏) hp_icons[i].visible = i < HP func _ready() -> void: animated_sprite.play("IDLE") add_to_group("Player") hurt_timer.timeout.connect(_on_hurt_timer_timeout) # 1. 从全局单例读取血量(注意大小写要和 Global.gd 里一致!) if Global: HP = Global.player_HP else: HP = 3 # 如果没有全局单例,默认给3滴血(防止报错) # 2. 寻找第二关场景里的出生点 (需要你给出生点节点加上 "SpawnPoint" 组) var spawn_point = get_tree().get_first_node_in_group("SpawnPoint") if spawn_point: global_position = spawn_point.global_position # 把玩家移动到出生点 # 3. 更新玩家死亡后的复活点(非常重要!否则在第二关死了会复活回第一关的位置) respawn_position = global_position # 4. 刷新血量UI,确保血条显示正确 _update_hp_ui() func _physics_process(delta: float) -> void: # Add the gravity. if not is_on_floor(): velocity += get_gravity() * delta else: JUMP_COUNT = 0 # Handle jump. if Input.is_action_just_pressed("move_up") and JUMP_COUNT < JUMP_MAX: velocity.y = JUMP_VELOCITY animated_sprite.play("JUMP") JUMP_COUNT += 1 if JUMP_COUNT == 1: is_jump = true animated_sprite.play("JUMP") is_jump = false elif JUMP_COUNT == 2: animated_sprite.play("DOUBLE_JUMP") await get_tree().create_timer(0.26).timeout animated_sprite.play("JUMP") # Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. var direction := Input.get_axis("move_left", "move_right") if invincibility:#无敌帧 if direction < 0: #无敌阵期间 animated_sprite.flip_h = true elif direction > 0: animated_sprite.flip_h = false velocity.x = SPEED * direction move_and_slide() else: if direction < 0: #动画运行 animated_sprite.flip_h = true elif direction > 0: animated_sprite.flip_h = false if direction != 0 : velocity.x = SPEED * direction #RUN动画 if animated_sprite.animation != "RUN" and is_on_floor() and not is_jump: animated_sprite.play("RUN") else: #IDLE动画 if is_on_floor() and not is_jump: velocity.x = move_toward(velocity.x, 0, SPEED) animated_sprite.play("IDLE") move_and_slide() if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) and TimerFIRE.is_stopped(): shoot() TimerFIRE.start() func shoot(): #射击 var bullet_scene = bullet.instantiate() var mouse_pos = get_global_mouse_position() bullet_scene.target_pos = mouse_pos bullet_scene.global_position = muzzle.global_position get_parent().add_child(bullet_scene) func die(): #死亡 HP = 3 velocity = Vector2.ZERO global_position = respawn_position _update_hp_ui() animated_sprite.play("IDLE") invincibility = true hurt_timer.start() func take_damage(amount:int): #伤害 if invincibility: return HP -= amount if HP <0: HP = 0 _update_hp_ui() animated_sprite.play("HIT") #print("当前的HP是:", HP) if HP <= 0: die() else: invincibility = true # 开启无敌 hurt_timer.start() # 启动无敌计时器 func _on_hurt_timer_timeout() -> void: invincibility = false func heal(amount:int): if HP >= MAX_HP: return HP += amount _update_hp_ui()