homework
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
extends Node
|
||||
var player_HP : int = 3
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
pass
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
uid://dr23nagrdi6jv
|
||||
@@ -0,0 +1,10 @@
|
||||
extends Area2D
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
# 1. 检查是不是玩家
|
||||
if body.is_in_group("Player"):
|
||||
# 2. 检查玩家有没有 heal 方法
|
||||
if body.has_method("heal"):
|
||||
# 3. 关键逻辑:如果玩家满血,就不要浪费这个道具
|
||||
if body.HP < body.MAX_HP: # 假设你玩家脚本里的变量叫 HP 和 MAX_HP
|
||||
body.heal(1) # 调用玩家脚本里的回血函数
|
||||
queue_free() # 只有成功回血了,草莓才消失
|
||||
@@ -0,0 +1 @@
|
||||
uid://dybg0afpbxpkg
|
||||
@@ -0,0 +1,85 @@
|
||||
extends CharacterBody2D
|
||||
var HP = 30
|
||||
var target : Node2D
|
||||
var target_two : Node2D
|
||||
var Player_inside: bool = false
|
||||
var slow_timer: float = 0.0
|
||||
var slow_factor: float = 0.5
|
||||
var is_hurt = false
|
||||
var is_dead: bool = false
|
||||
const SPEED = 150.0
|
||||
const JUMP_VELOCITY = -250.0
|
||||
@onready var TIMEJUMP = $timeJUMP
|
||||
@onready var animated_sprite = $AnimatedSprite2D
|
||||
func _ready() -> void:
|
||||
add_to_group("enemy")
|
||||
|
||||
func die():
|
||||
HP = max(0,HP)
|
||||
if HP <= 0:
|
||||
queue_free()
|
||||
is_dead = true
|
||||
|
||||
|
||||
func take_damage(amount:int,slow_during:float = 0.0,factor:float = 0.5):
|
||||
if is_dead:
|
||||
return
|
||||
HP -= amount #伤害
|
||||
animated_sprite.play("HIT")
|
||||
is_hurt = true
|
||||
if slow_during > 0.0:
|
||||
slow_timer = max(slow_during,slow_timer)
|
||||
slow_factor = factor
|
||||
animated_sprite.play("HIT")
|
||||
if not is_dead:
|
||||
die()
|
||||
await get_tree().create_timer(0.3).timeout
|
||||
is_hurt = false
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var current_SPEED = SPEED
|
||||
if not is_on_floor():
|
||||
velocity += get_gravity() * delta
|
||||
if Player_inside and is_instance_valid(target_two):
|
||||
if target_two.has_method("take_damage"):
|
||||
target_two.take_damage(1)
|
||||
Player_inside = false
|
||||
if slow_timer > 0.0:
|
||||
slow_timer -= delta
|
||||
if slow_timer < 0.0:
|
||||
slow_timer = 0.0
|
||||
if slow_timer > 0.0:
|
||||
current_SPEED = SPEED * slow_factor
|
||||
|
||||
if target:
|
||||
var direction := signf(target.global_position.x - global_position.x)
|
||||
velocity.x = direction * SPEED
|
||||
if direction < 0:
|
||||
animated_sprite.flip_h = true
|
||||
elif direction > 0:
|
||||
animated_sprite.flip_h = false
|
||||
if direction != 0 :
|
||||
velocity.x = current_SPEED * direction
|
||||
if animated_sprite.animation != "RUN" and not is_hurt:
|
||||
animated_sprite.play("RUN")
|
||||
if is_on_floor() and TIMEJUMP.is_stopped():
|
||||
velocity.y = JUMP_VELOCITY
|
||||
TIMEJUMP.start()
|
||||
elif is_on_floor():
|
||||
velocity.x = 0
|
||||
if not is_hurt:
|
||||
animated_sprite.play("IDLE")
|
||||
move_and_slide()
|
||||
|
||||
|
||||
func _on_jiance_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
target = body
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_damage_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
target_two = body
|
||||
Player_inside = true
|
||||
@@ -0,0 +1 @@
|
||||
uid://ow65qtakttsq
|
||||
@@ -0,0 +1,72 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
var HP = 30
|
||||
var Blink : Node2D = null
|
||||
@onready var animated = $Block_damage_animation
|
||||
var is_playing_blink: bool = false
|
||||
var is_in_observe : bool = false
|
||||
var is_playing_transition: bool = false
|
||||
var down_SPEED = 1000.0
|
||||
var down : bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
add_to_group("block")
|
||||
if not animated.animation_finished.is_connected(_on_animation_finished):
|
||||
animated.animation_finished.connect(_on_animation_finished)
|
||||
animated.play("SLEEP")
|
||||
|
||||
# 玩家进入 observe 区域
|
||||
func _on_area_2d_observe_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
is_in_observe = true
|
||||
# 如果没有在播过渡动画,就播 BLINK
|
||||
if not is_playing_transition:
|
||||
is_playing_transition = true
|
||||
animated.play("BLINK")
|
||||
# 如果你想强制打断 NOBLINK 直接播 BLINK,可以把上面换成:
|
||||
# is_playing_transition = true
|
||||
# animated.play("BLINK")
|
||||
|
||||
# 玩家离开 observe 区域
|
||||
func _on_area_2d_observe_body_exited(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
is_in_observe = false
|
||||
# 如果没有在播过渡动画,就播 NOBLINK
|
||||
if not is_playing_transition:
|
||||
is_playing_transition = true
|
||||
animated.play("NOBLINK")
|
||||
|
||||
# 【统一回调】所有动画播放完毕时触发
|
||||
func _on_animation_finished() -> void:
|
||||
# 只要播放完 BLINK 或 NOBLINK,就解除过渡锁定
|
||||
if animated.animation == "BLINK" or animated.animation == "NOBLINK":
|
||||
is_playing_transition = false
|
||||
|
||||
# 根据玩家最终是否在区域内,决定稳定状态
|
||||
if is_in_observe:
|
||||
animated.play("IDLE")
|
||||
else:
|
||||
animated.play("SLEEP")
|
||||
|
||||
|
||||
func _on_area_2d_damage_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
animated.play("HIT")
|
||||
down = true
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if down:
|
||||
velocity.y += down_SPEED * delta
|
||||
if is_on_floor():
|
||||
down = false
|
||||
velocity.y = -down_SPEED * 2
|
||||
|
||||
move_and_slide()
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_area_2d_take_damage_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
if body.has_method("take_damage"):
|
||||
body.take_damage(1)
|
||||
@@ -0,0 +1 @@
|
||||
uid://rtq2bo02xen7
|
||||
@@ -0,0 +1,23 @@
|
||||
extends Area2D
|
||||
var HP = 10
|
||||
@onready var animated_sprite = $AnimatedSprite2D
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
add_to_group("block")
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_area_entered(area: Area2D) -> void:
|
||||
if area.is_in_group("bullet"):
|
||||
animated_sprite.play("Hitside.block")
|
||||
HP -= 10
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
animated_sprite.play("Idle.block")
|
||||
if HP <= 0:
|
||||
get_parent().queue_free()
|
||||
else:
|
||||
animated_sprite.play("Idle.block")
|
||||
@@ -0,0 +1 @@
|
||||
uid://bcrwr7xxuh6rb
|
||||
@@ -0,0 +1,25 @@
|
||||
extends Area2D
|
||||
|
||||
@export var SPEED : float = 450.0
|
||||
@export var timing : float = 4.0
|
||||
var target_pos : Vector2
|
||||
var direction : Vector2 = Vector2.RIGHT
|
||||
|
||||
func _ready() -> void:
|
||||
add_to_group("bullet")
|
||||
direction = (target_pos - global_position).normalized()
|
||||
await get_tree().create_timer(timing).timeout
|
||||
queue_free()
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
global_position += direction * SPEED * delta
|
||||
|
||||
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("enemy") or body.is_in_group("wall") or body.is_in_group("blcok"):
|
||||
if body.has_method("take_damage"):
|
||||
body.take_damage(10,0.55,0.4)
|
||||
queue_free()
|
||||
elif body.is_in_group("wall"):
|
||||
queue_free()
|
||||
@@ -0,0 +1 @@
|
||||
uid://clwre6bop31u6
|
||||
@@ -0,0 +1,22 @@
|
||||
extends Area2D
|
||||
@onready var animated = $Animation_flag
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
animated.play("NULL")
|
||||
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
animated.play("ROLL")
|
||||
body.respawn_position = global_position
|
||||
await animated.animation_finished
|
||||
animated.play("YES")
|
||||
monitoring = false
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://dqrhmj1p0nklt
|
||||
@@ -0,0 +1,25 @@
|
||||
extends Area2D
|
||||
@onready var animated = $AnimatedSprite2D
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
animated.play("IDLE")
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
if animated.animation != "END":
|
||||
animated.play("END")
|
||||
await animated.animation_finished
|
||||
call_deferred("go_to_next_level")
|
||||
|
||||
func go_to_next_level():
|
||||
var player = get_tree().get_first_node_in_group("Player")
|
||||
if player:
|
||||
Global.player_HP = player.HP
|
||||
get_tree().change_scene_to_file("res://scene/entities/level_2.tscn")
|
||||
@@ -0,0 +1 @@
|
||||
uid://bvs3jagxfk5px
|
||||
@@ -0,0 +1,145 @@
|
||||
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()
|
||||
@@ -0,0 +1 @@
|
||||
uid://cu71l16bkptlq
|
||||
@@ -0,0 +1,17 @@
|
||||
extends Area2D
|
||||
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
pass # Replace with function body.
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta: float) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
if body.has_method("take_damage"):
|
||||
body.take_damage(1)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://c40ox7fx62471
|
||||
@@ -0,0 +1,11 @@
|
||||
extends StaticBody2D
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
add_to_group("wall")
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta: float) -> void:
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
uid://ccs2hy30dvdww
|
||||
@@ -0,0 +1,24 @@
|
||||
extends Area2D
|
||||
@onready var animated = $AnimatedSprite2D
|
||||
var target : Node2D = null
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
animated.play("ROLL")
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
if target:
|
||||
if target.has_method("take_damage"):
|
||||
target.take_damage(1)
|
||||
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
target = body
|
||||
|
||||
|
||||
func _on_body_exited(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
target = null
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
uid://1rvs6xclfn7l
|
||||
@@ -0,0 +1,35 @@
|
||||
extends Area2D
|
||||
|
||||
const SPEED = 200
|
||||
@onready var animated = $AnimatedSprite2D
|
||||
var target : Node2D = null
|
||||
var trans : bool
|
||||
var direction
|
||||
@onready var timer = $Timer
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
animated.play("ROLL")
|
||||
timer.start()
|
||||
direction = 1
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
global_position.x += direction * SPEED * delta
|
||||
if target:
|
||||
if target.has_method("take_damage"):
|
||||
target.take_damage(1)
|
||||
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
target = body
|
||||
|
||||
|
||||
func _on_body_exited(body: Node2D) -> void:
|
||||
if body.is_in_group("Player"):
|
||||
target = null
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
direction *= -1
|
||||
timer.start()
|
||||
@@ -0,0 +1 @@
|
||||
uid://b5ux5luvsai6h
|
||||
Reference in New Issue
Block a user