Untitled
unknown
plain_text
a year ago
6.9 kB
13
Indexable
Never
extends CharacterBody2D signal punch_animation_finished @onready var animation_tree = $AnimationTree @onready var animation_state_machine = animation_tree.get("parameters/playback") var DamageLabelScene = load("res://Scenes/DamageLabel.tscn") var CorpseScene = preload("res://Scenes/Corpse.tscn") # Punching Variables enum State {IDLE, MOVING, PUNCHING, RUNNING} var state = State.IDLE var punch_key = "" var punch_damage = randi_range(7, 12) var stamina_cost = 5 var bodies_in_hitbox = [] var hitbox_collision_shape var punch_cooldown = 1.0 var punch_timer = 0.0 var walk_speed = 55 var run_speed = 80 var current_speed = walk_speed var follow_distance = 300 var minimum_distance = 26 var player_follow = false var player = null var current_dir = "none" var last_dir = "down" var linear_velocity = Vector2.ZERO var running = false # Attributes var maxHealth = 100 var currentHealth var minHealth = 0 var maxStamina = 100 var currentStamina var minStamina = 0 var hitbox var input_vector = Vector2.ZERO var last_input_vector = Vector2.ZERO func _ready(): add_to_group("npc") $healthbar.max_value = maxHealth currentHealth = maxHealth $healthbar.value = currentHealth $staminabar.max_value = maxStamina currentStamina = maxStamina $staminabar.value = currentStamina set_motion_mode(MOTION_MODE_FLOATING) hitbox = get_node("npc_hitbox") hitbox_collision_shape = hitbox.get_node("CollisionShape2D") animation_tree.set("parameters/Idle/blend_position", Vector2(0, 1)) animation_tree.set("parameters/Walk/blend_position", Vector2(0, 1)) animation_tree.set("parameters/Run/blend_position", Vector2(0, 1)) animation_tree.set("parameters/RPunch/blend_position", Vector2(0, 1)) animation_tree.set("parameters/LPunch/blend_position", Vector2(0, 1)) animation_state_machine.start("Idle") #animated_sprite.connect("animation_finished", self, "_on_animated_sprite_2d_animation_finished") func _physics_process(delta): update_running_state() if state != State.PUNCHING: move_and_slide() if player_follow: follow_player(delta) velocity = linear_velocity move_and_slide() else: velocity = Vector2.ZERO punch_timer += delta if player in bodies_in_hitbox and punch_timer >= punch_cooldown: check_punch_condition() punch_timer = 0 update_animation() func update_animation(): var anim_name = "" if state == State.PUNCHING: anim_name = "RPunch" if last_input_vector.x > 0 else "LPunch" else: if input_vector != Vector2.ZERO: last_input_vector = input_vector.normalized() if state == State.IDLE: anim_name = "Idle" elif state == State.MOVING and current_speed == walk_speed: anim_name = "Walk" elif state == State.RUNNING: anim_name = "Run" if anim_name != "" and animation_state_machine.get_current_node() != anim_name: animation_tree.set("parameters/{0}/blend_position".format([anim_name]), last_input_vector) animation_state_machine.travel(anim_name) func play_punch_anim(): var blend_space_node = "RPunch" if last_input_vector.x > 0 else "LPunch" animation_tree.set("parameters/Idle/blend_position", last_input_vector) animation_tree.set("parameters/Walk/blend_position", last_input_vector) animation_tree.set("parameters/Run/blend_position", last_input_vector) animation_tree.set("parameters/RPunch/blend_position", last_input_vector) animation_tree.set("parameters/LPunch/blend_position", last_input_vector) animation_state_machine.travel(blend_space_node) func check_punch_condition(): if state != State.PUNCHING and player in bodies_in_hitbox and punch_timer >= punch_cooldown: state=State.PUNCHING # Set state to PUNCHING before calling perform_punch function. perform_punch() print("hit") punch_timer=0 func follow_player(_delta): var distance = global_position.distance_to(player.global_position) if distance <= follow_distance: input_vector = (player.global_position - global_position).normalized() linear_velocity = input_vector * current_speed if distance < minimum_distance: linear_velocity = Vector2.ZERO else: linear_velocity = Vector2.ZERO if linear_velocity.length() < 0.1: state = State.IDLE else: if running: state = State.RUNNING else: state = State.MOVING last_input_vector = input_vector.normalized() func update_running_state(): if state != State.PUNCHING: if currentStamina > 20: running = true current_speed = run_speed state = State.RUNNING else: running = false current_speed = walk_speed state = State.MOVING @warning_ignore("unused_parameter") func take_damage(damage, attacker_position): if currentStamina > 0: currentStamina -= damage update_stamina_bar() else: currentHealth -= damage update_health_bar() var damage_label=DamageLabelScene.instantiate() damage_label.text=str(damage) damage_label.modulate=Color.WHITE var x_offset=randf_range(-10,10) # Adjust the range as needed. damage_label.position=Vector2(x_offset,-50) add_child(damage_label) var tween=get_tree().create_tween() tween.tween_property(damage_label,"position:y",damage_label.position.y-100,1) tween.tween_property(damage_label,"modulate:a",0,1) if currentHealth <= 0: die() func die(): set_physics_process(false) await get_tree().create_timer(15).timeout queue_free() $CollisionShape2D.disabled=false await get_tree().create_timer(15).timeout queue_free() $CollisionShape2D.disabled=false func create_corpse(): var corpse=CorpseScene.instance() corpse.global_position=get_node("npc").global_position corpse.currentHealth = 0 corpse.take_damage = null #corpse.sprite_resource = animated_sprite.frames get_parent().add_child(corpse) await get_tree().create_timer(15).timeout func update_health_bar(): $healthbar.value = currentHealth func update_stamina_bar(): $staminabar.value = currentStamina func perform_punch(): if currentStamina > 0: punch_damage = randi_range(7, 12) play_punch_anim() for body in bodies_in_hitbox: if body.has_method("take_damage"): body.take_damage(punch_damage, global_position) currentStamina -= stamina_cost state = State.PUNCHING func _on_detectionarea_body_entered(body): if body.is_in_group("player"): player = body player_follow = true set_physics_process(true) print("Following player") func _on_detectionarea_body_exited(body): if body.is_in_group("player"): player = null player_follow = false state = State.IDLE # Set the state to IDLE when the NPC stops following the player print("Not following player") func enemy(): pass func _on_npc_hitbox_body_entered(body): if body.is_in_group("player"): bodies_in_hitbox.append(body) print("npc hitbox") if not $PunchTimer.is_stopped(): $PunchTimer.start() func _on_npc_hitbox_body_exited(body): if body.is_in_group("player"): bodies_in_hitbox.erase(body) print("npc out hitbox") $PunchTimer.stop() func _on_punch_timer_timeout(): perform_punch() print("hit")