6.5. Spielercharacter

Der Spielercharacter ermöglicht dem Spieler die Interaktion mit der Spielwelt. Dieser Charakter kann sich bewegen und auf Gegner schießen. Wird er getroffen, erleidet er Schaden und fallen seine Lebenspunkte auf Null endet das Spiel. Das wird über die Funktionen “take_damage” und “die” geregelt.

Der Spielerinput wird über die Funktionen “get_keyboard_input” und “_input” behandelt. Das Ermöglicht das Aufrufen der Funktionen “shoot” für das Schießen und “boost” für den Geschwindigkeitsboost.

Der Geschwindigkeitsboost wird über die Funktion “level_speed” wieder abgebaut.

Das heilen durch Healthpacks wird über die Funktion “restore_health” geregelt.

Die Bewegungslogik wird über die Funktion “_physics_process” geregelt.

extends CharacterBody2D

const SPEED = 400.0

signal max_health_updated(health)
signal health_updated(health)
signal boost_updated(seconds)
signal killed()

export var max_health = 500
onready var health = max_health
onready var invulnerability = $InvulnerabilityTimer
onready var shooting_delay = $ShootTimer
onready var boost_delay = $BoostTimer

var current_speed = SPEED

func _ready():
	emit_signal("max_health_updated", max_health)
	emit_signal("health_updated", health)


func _input(event):
	if event.is_action_pressed("ui_select"):
		shoot()
	elif event.is_action_pressed("boost"):
		boost()


func boost():
	if boost_delay.is_stopped():
		boost_delay.start()
		current_speed = SPEED * 2


func level_speed(delta):
	var td = 200 * delta
	if SPEED - td < current_speed && current_speed < SPEED + td:
		current_speed = SPEED
	elif current_speed > SPEED + td:
		current_speed -= td
	elif current_speed < SPEED - td:
		current_speed += td
	emit_signal("boost_updated", 5 - boost_delay.time_left)


func get_keyboard_input():
	var input_direction = Input.get_vector("ui_left","ui_right", "ui_up","ui_down")
	velocity = input_direction * current_speed


func take_damage(damage: int):
	if invulnerability.is_stopped():
		var rootnode = get_parent()
		rootnode.subtractScore(damage/10) #/10 for balance purposes
		invulnerability.start()
		_set_health(health - damage)


func restore_health(heal_value: int):
	var rootnode = get_parent()
	rootnode.addScore(heal_value)
	_set_health(health + heal_value)


func _set_health(value):
	var prev_health = health
	health = clamp(value, 0, max_health)
	if health != prev_health:
		emit_signal("health_updated", health)
		if health == 0:
			die()
			emit_signal("killed")


func shoot():
	if shooting_delay.is_stopped():
		shooting_delay.start()
		var projectile = preload("res://Entity/bullet.tscn")
		var bullet = projectile.instantiate()
		bullet.position = Vector2(0, -60) + position
		get_tree().current_scene.add_child(bullet)


func die():
	var explosion = preload("res://Entity/explosion.tscn")
	explosion = explosion.instantiate()
	explosion.position = position
	get_tree().current_scene.add_child(explosion)
	queue_free()


func _physics_process(delta):
	get_keyboard_input()
	level_speed(delta)
	var collision_info = move_and_collide(velocity * delta)
	if collision_info:
		var collider = collision_info.get_collider()
		if collider.has_method("get_damage"):
			take_damage(collider.get_damage())
			collider.free()
		elif collider.has_method("get_healing"):
			restore_health(collider.get_healing())
			collider.free()