fight system and whatnot
This commit is contained in:
86
scripts/enemies/skull.gd
Normal file
86
scripts/enemies/skull.gd
Normal file
@@ -0,0 +1,86 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
@export var speed: int = 900
|
||||
@onready var navigation_agent_2d: NavigationAgent2D = $NavigationAgent2D
|
||||
@onready var follow_update_timer: Timer = $FollowUpdateTimer
|
||||
@onready var attack_timer: Timer = $AttackTimer
|
||||
@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
|
||||
|
||||
var idle: bool = true
|
||||
const DAMAGE: int = 1
|
||||
var health: int = 8
|
||||
var target: Player = null
|
||||
var in_attack_range: bool = false
|
||||
var stop_distance: int = 20
|
||||
var attack_cooldown_offset: float = 0.0
|
||||
var flicker_time: float = 0.2
|
||||
var flicker_timer: float = 0.0
|
||||
|
||||
func _ready() -> void:
|
||||
navigation_agent_2d.avoidance_priority = randf_range(0.5, 1.0)
|
||||
attack_cooldown_offset = randf_range(0.0, 0.5)
|
||||
animated_sprite.speed_scale = randf_range(0.4, 1.2)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if flicker_timer > 0.0:
|
||||
flicker_timer -= delta
|
||||
animated_sprite.modulate = Color(1, 0, 0)
|
||||
if flicker_timer <= 0.0:
|
||||
animated_sprite.modulate = Color(1, 1, 1)
|
||||
|
||||
func _on_area_body_entered(body: Node2D) -> void:
|
||||
if body is Player:
|
||||
idle = false
|
||||
target = body
|
||||
follow_update_timer.start()
|
||||
animated_sprite.play()
|
||||
|
||||
func _on_area_body_exited(body: Node2D) -> void:
|
||||
if body is Player:
|
||||
idle = true
|
||||
target = null
|
||||
follow_update_timer.stop()
|
||||
animated_sprite.frame = 0
|
||||
animated_sprite.stop()
|
||||
|
||||
func _on_attack_area_body_entered(body: Node2D) -> void:
|
||||
if body is Player:
|
||||
in_attack_range = true
|
||||
attack_timer.start(attack_timer.wait_time + attack_cooldown_offset)
|
||||
|
||||
func _on_attack_area_body_exited(body: Node2D) -> void:
|
||||
if body is Player:
|
||||
in_attack_range = false
|
||||
attack_timer.stop()
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if !idle && target:
|
||||
if !navigation_agent_2d.is_navigation_finished():
|
||||
var next_path_pos: Vector2 = navigation_agent_2d.get_next_path_position()
|
||||
var direction: Vector2 = (next_path_pos - global_position).normalized()
|
||||
var desired_velocity: Vector2 = direction * speed * delta
|
||||
navigation_agent_2d.set_velocity(desired_velocity)
|
||||
else:
|
||||
velocity = Vector2.ZERO
|
||||
move_and_slide()
|
||||
else:
|
||||
velocity = Vector2.ZERO
|
||||
move_and_slide()
|
||||
|
||||
func _on_follow_update_timer_timeout() -> void:
|
||||
if target && !idle:
|
||||
navigation_agent_2d.target_position = target.global_position
|
||||
|
||||
func _on_navigation_agent2d_velocity_computed(safe_velocity: Vector2) -> void:
|
||||
velocity = safe_velocity
|
||||
move_and_slide()
|
||||
|
||||
func _on_attack_timer_timeout() -> void:
|
||||
if target && in_attack_range:
|
||||
target.health -= DAMAGE
|
||||
|
||||
func _on_fightable_fought(player: Player) -> void:
|
||||
health -= player.damage
|
||||
flicker_timer = flicker_time
|
||||
if health <= 0:
|
||||
queue_free()
|
||||
1
scripts/enemies/skull.gd.uid
Normal file
1
scripts/enemies/skull.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cuc28u7op02gq
|
||||
6
scripts/fightable.gd
Normal file
6
scripts/fightable.gd
Normal file
@@ -0,0 +1,6 @@
|
||||
class_name Fightable
|
||||
extends Area2D
|
||||
|
||||
signal fought(player: Player)
|
||||
|
||||
func fight(player: Player) -> void: fought.emit(player)
|
||||
1
scripts/fightable.gd.uid
Normal file
1
scripts/fightable.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cvd86i6imfk24
|
||||
@@ -6,4 +6,5 @@ extends Node2D
|
||||
func _ready() -> void: $Interactable.auto_interact = auto_interact
|
||||
|
||||
func _on_interacted(_player: Player) -> void:
|
||||
EventManager.transition_scene_file(scene)
|
||||
if !scene.is_empty():
|
||||
EventManager.transition_scene_file(scene)
|
||||
|
||||
34
scripts/menus/util/hearts.gd
Normal file
34
scripts/menus/util/hearts.gd
Normal file
@@ -0,0 +1,34 @@
|
||||
@tool
|
||||
class_name Hearts
|
||||
extends Control
|
||||
|
||||
@export_range(0, 10, 1) var health: int = 10:
|
||||
set(value):
|
||||
health = clamp(value, 0, max_health)
|
||||
update_health_textures()
|
||||
|
||||
var max_health: int = 10
|
||||
var heart_textures: Array[Node]
|
||||
|
||||
func _ready() -> void:
|
||||
heart_textures = $HeartContainer.get_children()
|
||||
for heart_texture in heart_textures:
|
||||
heart_texture.texture = heart_texture.texture.duplicate()
|
||||
update_health_textures()
|
||||
|
||||
func update_health_textures() -> void:
|
||||
@warning_ignore("integer_division")
|
||||
var full_hearts: int = health / 2
|
||||
var half_heart: bool = health % 2 == 1
|
||||
|
||||
for i in range(heart_textures.size()):
|
||||
var heart_texture: TextureRect = heart_textures[i]
|
||||
var atlas: AtlasTexture = heart_texture.texture as AtlasTexture
|
||||
if i < full_hearts:
|
||||
atlas.region.position.x = 1
|
||||
heart_texture.visible = true
|
||||
elif i == full_hearts and half_heart:
|
||||
atlas.region.position.x = 17
|
||||
heart_texture.visible = true
|
||||
else:
|
||||
heart_texture.visible = false
|
||||
1
scripts/menus/util/hearts.gd.uid
Normal file
1
scripts/menus/util/hearts.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cfplt163iotph
|
||||
@@ -1,18 +1,22 @@
|
||||
class_name Player
|
||||
extends CharacterBody2D
|
||||
|
||||
const SPEED: int = 800
|
||||
const SPEED: int = 1000
|
||||
|
||||
@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
|
||||
@onready var fight_animation: AnimatedSprite2D = $FightAnimation
|
||||
@onready var cam: Camera2D = $Camera2D
|
||||
@onready var raycast: RayCast2D = $RayCast2D
|
||||
const RAYCAST_RAGE: int = 32
|
||||
|
||||
@onready var cursor_hide_timer: Timer = $CursorHideTimer
|
||||
const RAYCAST_RANGE: int = 22
|
||||
|
||||
@export var tilemap: TileMapLayer
|
||||
var tilesize: int = 32
|
||||
var position_limit_rect: Rect2
|
||||
const STILL_POSITIONS: Array[String] = ["sit", "hand_down", "hand_side", "hand_up"]
|
||||
const STILL_POSITIONS: Array[String] = ["sit_down", "sit_side", "hand_down", "hand_side", "hand_up"]
|
||||
|
||||
var health: int = 10
|
||||
var damage: int = 2
|
||||
|
||||
func _ready() -> void:
|
||||
EventManager.player = self
|
||||
@@ -35,9 +39,55 @@ func _ready() -> void:
|
||||
)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if EventManager.player_free && !EventManager.animation_player.is_playing() && Input.is_action_just_pressed("interact") && raycast.is_colliding() && raycast.get_collider() is Interactable:
|
||||
var interactable: Interactable = raycast.get_collider()
|
||||
if EventManager.player_free && !EventManager.animation_player.is_playing() && Input.is_action_just_pressed("interact"):
|
||||
interact()
|
||||
|
||||
func interact() -> void:
|
||||
var interactable: Interactable
|
||||
if raycast.is_colliding() && raycast.get_collider() is Interactable:
|
||||
interactable = raycast.get_collider()
|
||||
else:
|
||||
interactable = null
|
||||
var fightable: Fightable
|
||||
if raycast.is_colliding() && raycast.get_collider() is Fightable:
|
||||
fightable = raycast.get_collider()
|
||||
else:
|
||||
fightable = null
|
||||
|
||||
match animated_sprite.animation:
|
||||
"down":
|
||||
animated_sprite.play("hand_down")
|
||||
if interactable == null:
|
||||
fight_animation.rotation_degrees = 0
|
||||
fight_animation.play()
|
||||
if !fight_animation.is_playing():
|
||||
fight_animation.play()
|
||||
await animated_sprite.animation_finished
|
||||
animated_sprite.animation = "down"
|
||||
"up":
|
||||
animated_sprite.play("hand_up")
|
||||
if interactable == null:
|
||||
fight_animation.rotation_degrees = 180
|
||||
fight_animation.play()
|
||||
if !fight_animation.is_playing():
|
||||
fight_animation.play()
|
||||
await animated_sprite.animation_finished
|
||||
animated_sprite.animation = "up"
|
||||
"side":
|
||||
animated_sprite.play("hand_side")
|
||||
if interactable == null:
|
||||
if animated_sprite.flip_h:
|
||||
fight_animation.rotation_degrees = 90
|
||||
else:
|
||||
fight_animation.rotation_degrees = -90
|
||||
if !fight_animation.is_playing():
|
||||
fight_animation.play()
|
||||
await animated_sprite.animation_finished
|
||||
animated_sprite.animation = "side"
|
||||
if interactable != null:
|
||||
interactable.interact(self)
|
||||
elif fightable != null:
|
||||
fightable.fight(self)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if !STILL_POSITIONS.has(animated_sprite.animation) && EventManager.player_free && !EventManager.animation_player.is_playing():
|
||||
@@ -49,7 +99,7 @@ func _physics_process(delta: float) -> void:
|
||||
elif abs(input.y) > 0:
|
||||
raycast_input.y = sign(input.y)
|
||||
if raycast_input != Vector2.ZERO:
|
||||
raycast.target_position = raycast_input * RAYCAST_RAGE
|
||||
raycast.target_position = raycast_input * RAYCAST_RANGE
|
||||
|
||||
velocity = input * delta * SPEED * 3
|
||||
|
||||
@@ -71,6 +121,10 @@ func _physics_process(delta: float) -> void:
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouse:
|
||||
cursor_hide_timer.stop()
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
elif EventManager.player_free && !EventManager.animation_player.is_playing() && !event.is_action("escape"):
|
||||
if cursor_hide_timer.is_stopped():
|
||||
cursor_hide_timer.start()
|
||||
await cursor_hide_timer.timeout
|
||||
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN
|
||||
|
||||
Reference in New Issue
Block a user