Added rpg system for combat
added lots of loot to find added level up system
This commit is contained in:
169
src/scripts/attack_arrow.gd
Normal file
169
src/scripts/attack_arrow.gd
Normal file
@@ -0,0 +1,169 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
var speed = 300
|
||||
var direction = Vector2.ZERO
|
||||
var stick_duration = 3.0 # How long the arrow stays stuck to walls
|
||||
var is_stuck = false
|
||||
var stick_timer = 0.0
|
||||
|
||||
var initiated_by: Node2D = null
|
||||
|
||||
@onready var arrow_area = $ArrowArea # Assuming you have an Area2D node named ArrowArea
|
||||
@onready var shadow = $Shadow # Assuming you have a Shadow node under the CharacterBody2D
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
arrow_area.set_deferred("monitoring", true)
|
||||
#arrow_area.body_entered.connect(_on_body_entered)
|
||||
$SfxArrowFire.play()
|
||||
call_deferred("_initialize_arrow")
|
||||
|
||||
func _initialize_arrow() -> void:
|
||||
var angle = direction.angle()
|
||||
self.rotation = angle - PI / 2 # Adjust for sprite orientation
|
||||
# Set initial rotation based on direction
|
||||
velocity = direction * speed # Set initial velocity to move the arrow
|
||||
|
||||
# Calculate the offset for the shadow position, which should be below the arrow
|
||||
var shadow_offset = Vector2(0, 4) # Adjust the 16 to how far you want the shadow from the arrow (this is just an example)
|
||||
|
||||
# Apply the rotation of the arrow to the shadow offset
|
||||
shadow.position += shadow_offset.rotated(-self.rotation)
|
||||
if abs(direction.x) == 1:
|
||||
shadow.scale.x = 0.26
|
||||
shadow.scale.y = 0.062
|
||||
|
||||
elif abs(direction.x) > 0:
|
||||
shadow.scale.x = 0.18
|
||||
shadow.scale.y = 0.08
|
||||
else:
|
||||
shadow.scale.x = 0.1
|
||||
shadow.scale.y = 0.1
|
||||
|
||||
# Calculate the shadow's scale based on the velocity or direction of the arrow
|
||||
#var velocity_magnitude = velocity.length()
|
||||
|
||||
# Scale more in the horizontal direction if moving diagonally or horizontally
|
||||
#var scale_factor = 0.28 + abs(velocity.x) / velocity_magnitude # Adjust the factor to your preference
|
||||
|
||||
# Apply the scaling to the shadow
|
||||
shadow.rotation = -(angle - PI / 2)
|
||||
|
||||
func shoot(shoot_direction: Vector2, start_pos: Vector2) -> void:
|
||||
direction = shoot_direction.normalized()
|
||||
global_position = start_pos
|
||||
#position = start_pos
|
||||
|
||||
# Called every frame. 'delta' is the e lapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
if is_stuck:
|
||||
# Handle fade out here if it's stuck
|
||||
stick_timer += delta
|
||||
if stick_timer >= stick_duration:
|
||||
# Start fading out after it sticks
|
||||
modulate.a = max(0, 1 - (stick_timer - stick_duration) / 1.0) # Fade out over 1 second
|
||||
if stick_timer >= stick_duration + 1.0: # Extra second for fade out
|
||||
queue_free() # Remove the arrow after fade out
|
||||
move_and_slide()
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
# If the arrow is stuck, stop it from moving
|
||||
if is_stuck:
|
||||
velocity = Vector2.ZERO # Stop movement
|
||||
# Optional: disable further physics interaction by setting linear_velocity
|
||||
# move_and_slide(Vector2.ZERO) # You can also use this to stop the character
|
||||
|
||||
func play_impact():
|
||||
$SfxImpactSound.play()
|
||||
|
||||
# Called when the arrow hits a wall or another object
|
||||
func _on_body_entered(body: Node) -> void:
|
||||
if not is_stuck:
|
||||
if body == initiated_by:
|
||||
return
|
||||
if body is CharacterBody2D and body.stats.is_invulnerable == false and body.stats.hp > 0: # hit an enemy
|
||||
#if body is CharacterBody2D and body.collision_layer & (1 << 8) and body.taking_damage_timer <= 0 and body.stats.hp > 0: # Check if body is enemy (layer 9)
|
||||
|
||||
# Stop the arrow
|
||||
velocity = Vector2.ZERO
|
||||
is_stuck = true
|
||||
stick_timer = 0.0
|
||||
arrow_area.set_deferred("monitoring", false)
|
||||
# Calculate the collision point - move arrow slightly back from its direction
|
||||
var collision_normal = -direction # Opposite of arrow's direction
|
||||
var offset_distance = 8 # Adjust this value based on your collision shape sizes
|
||||
var stick_position = global_position + (collision_normal * offset_distance)
|
||||
|
||||
# Make arrow a child of the enemy to stick to it
|
||||
var global_rot = global_rotation
|
||||
get_parent().call_deferred("remove_child", self)
|
||||
body.call_deferred("add_child", self)
|
||||
self.set_deferred("global_position", stick_position)
|
||||
self.set_deferred("global_rotation", global_rot)
|
||||
#global_rotation = global_rot
|
||||
body.call_deferred("take_damage", self, initiated_by)
|
||||
self.call_deferred("play_impact") # need to play the sound on the next frame, because else it cuts it.
|
||||
|
||||
else:
|
||||
$SfxImpactWall.play()
|
||||
# Stop the arrow
|
||||
velocity = Vector2.ZERO
|
||||
is_stuck = true
|
||||
stick_timer = 0.0
|
||||
arrow_area.set_deferred("monitoring", false)
|
||||
# You can optionally stick the arrow at the collision point if you want:
|
||||
# position = body.position # Uncomment this if you want to "stick" it at the collision point
|
||||
# Additional logic for handling interaction with walls or other objects
|
||||
|
||||
|
||||
func _on_arrow_area_area_entered(area: Area2D) -> void:
|
||||
if not is_stuck:
|
||||
if area.get_parent() == initiated_by:
|
||||
return
|
||||
if area.get_parent() is CharacterBody2D and area.get_parent().stats.is_invulnerable == false and area.get_parent().stats.hp > 0: # hit an enemy
|
||||
#if body is CharacterBody2D and body.collision_layer & (1 << 8) and body.taking_damage_timer <= 0 and body.stats.hp > 0: # Check if body is enemy (layer 9)
|
||||
|
||||
# Stop the arrow
|
||||
velocity = Vector2.ZERO
|
||||
is_stuck = true
|
||||
stick_timer = 0.0
|
||||
arrow_area.set_deferred("monitoring", false)
|
||||
# Calculate the collision point - move arrow slightly back from its direction
|
||||
var collision_normal = -direction # Opposite of arrow's direction
|
||||
var offset_distance = 8 # Adjust this value based on your collision shape sizes
|
||||
var stick_position = global_position + (collision_normal * offset_distance)
|
||||
|
||||
# Make arrow a child of the enemy to stick to it
|
||||
var global_rot = global_rotation
|
||||
get_parent().call_deferred("remove_child", self)
|
||||
area.get_parent().call_deferred("add_child", self)
|
||||
self.set_deferred("global_position", stick_position)
|
||||
self.set_deferred("global_rotation", global_rot)
|
||||
#global_rotation = global_rot
|
||||
area.get_parent().call_deferred("take_damage", self, initiated_by)
|
||||
self.call_deferred("play_impact") # need to play the sound on the next frame, because else it cuts it.
|
||||
|
||||
else:
|
||||
$SfxImpactWall.play()
|
||||
# Stop the arrow
|
||||
velocity = Vector2.ZERO
|
||||
is_stuck = true
|
||||
stick_timer = 0.0
|
||||
arrow_area.set_deferred("monitoring", false)
|
||||
# You can optionally stick the arrow at the collision point if you want:
|
||||
# position = body.position # Uncomment this if you want to "stick" it at the collision point
|
||||
# Additional logic for handling interaction with walls or other objects
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
func _on_arrow_area_body_entered(body: Node2D) -> void:
|
||||
if not is_stuck:
|
||||
if body == initiated_by:
|
||||
return
|
||||
$SfxImpactWall.play()
|
||||
# Stop the arrow
|
||||
velocity = Vector2.ZERO
|
||||
is_stuck = true
|
||||
stick_timer = 0.0
|
||||
arrow_area.set_deferred("monitoring", false)
|
||||
pass # Replace with function body.
|
||||
Reference in New Issue
Block a user