Side-Scrolling-Shooter/Project/Scripts/player.gd
2025-04-15 11:58:44 -07:00

95 lines
2.8 KiB
GDScript

extends CharacterBody2D
@export_category("Basic")
@export var Health: int = 3
@export var Speed: int
@export var InvulnerabilityTime: int = 3
var Invulnerable: bool = false
var InvulnerabilityTimer: float = 0
@export_category("Shooting")
@export var Bullet: PackedScene
@export var FireRate: float
var FireRateTimer: float
@export_category("Images")
@export var PlaneUp: CompressedTexture2D
@export var PlaneNeutral: CompressedTexture2D
@export var PlaneDown: CompressedTexture2D
@export_category("Other")
@export var OnDeathScene: PackedScene
var PlayerControl: bool = true
signal PlayerTookDamage(Health: int)
func _physics_process(delta: float) -> void:
FireRateTimer += delta
# Invulnerability. This is the segment that runs after taking damage.
if Invulnerable == true:
InvulnerabilityTimer += delta
if InvulnerabilityTimer >= InvulnerabilityTime:
Invulnerable = false
InvulnerabilityTimer = 0
if PlayerControl:
# Movement
var SpeedUp = Input.get_action_raw_strength("SpeedUp")
var xdirection = Input.get_axis("Left", "Right")
var ydirection = Input.get_axis("Up", "Down")
if xdirection || ydirection:
self.velocity = Vector2(xdirection, ydirection).normalized() * Speed * (SpeedUp + 1)
# Adjust sprites on movement
if ydirection == 1:
get_node("Sprite2D").texture = PlaneDown
elif ydirection == -1:
get_node("Sprite2D").texture = PlaneUp
else:
get_node("Sprite2D").texture = PlaneNeutral
else:
# Stop the plane on not moving
self.velocity.x = move_toward(velocity.x, 0, Speed)
self.velocity.y = move_toward(velocity.y, 0, Speed)
# yes, this has to be here. I know, really stupid.
get_node("Sprite2D").texture = PlaneNeutral
# Shooting
if Input.get_action_raw_strength("Shoot") && FireRateTimer >= FireRate:
var bullet = Bullet.instantiate()
bullet.transform = get_node("Gun/Marker2D").global_transform
get_tree().current_scene.add_child(bullet)
FireRateTimer = 0
get_node("Gun/AudioStreamPlayer").play()
# If the player losses control (because they are dead)
else:
@warning_ignore("integer_division")
self.velocity.y = Speed / 2
self.velocity.x = move_toward(velocity.x, 0, Speed)
# Don't use move_and_collide() because it sticks to the walls.
move_and_slide()
# If an enemy collides into the player, they run this function.
func TakeDamage():
Health -= 1
Invulnerable = true
PlayerTookDamage.emit(Health)
get_node("Area2D/AudioStreamPlayer").play()
if Health == 0:
PlayerControl = false
get_node("AnimationPlayer").play("Death")
# Invulnerable so that way you won't be annoyed.
InvulnerabilityTime = 5
Invulnerable = true
else:
get_node("AnimationPlayer").play("Hit")
func _on_area_2d_body_entered(_body: Node2D):
if Invulnerable != true:
TakeDamage()
func GoToScene():
get_tree().change_scene_to_packed(OnDeathScene)