6.6. Gegnercharactere
Im Spiel kommen zwei verschiedene Genertypen vor: Shooter und Charger
Alle Gegner teilen sich Characteristiken. So können sie Schaden bekommen und werden sie aus dem Spiel entfernt, sobald ihre Lebenspunkte auf Null sinken. Beim Entfernen aus dem Spiel erzeugen sie noch einen kleinen Explosionseffekt. Das wird über die Funktionen “take_damage” und “die” geregelt.
Die Bewegungslogik wird über die Funktion “_physics_process” geregelt. Diese behandelt auch die Zusammenstöße mit anderen Objekten.
func take_damage(damage: int):
health -= damage
if health <= 0:
die()
func die():
var explosion = preload("res://Entity/explosion.tscn")
explosion = explosion.instantiate()
explosion.position = position
get_tree().current_scene.add_child(explosion)
queue_free()
6.6.1. Shooter
Der Shooter Gegner stellt den klassischen Gegner eines “Shoot ‚em Up” Spiels dar. Er bewegt sich horizontal von einer Bildschirmseite zur anderen. Gemäß seines Namens schießt er konstant gerade nach unten und damit auf den Spieler zu. Berührt er ein anderes Objekt oder den Bildschirmrand ändert er seine Richtung. Mit der geringen Anzahl an Lebenspunkten und dem geringen am Spieler verursachten Schaden, dienen sie dazu, dem Spieler nach und nach die Lebenspunkte abzuziehen.
Das schießen nach unten wird über die Funktion “shoot” geregelt, die periodisch aufgerufen wird. Diese Funktion erzeugt einfach ein neues “Bullet” Objekt welches in die gewünschte Richtung fliegt. Alles Weitere übernimmt die Bullet selbst.
Das Ändern der Bewegungsrichtung wird über die Funktion “turn_around” geregelt. Diese wird von einem screen_checker Objekt aufgerufen sobald der Gegner den Bildschirm verlässt oder wenn dieser mit etwas zusammenstößt.
extends CharacterBody2D
signal max_health_updated(health)
signal health_updated(health)
signal killed()
const SPEED = 300.0
const JUMP_VELOCITY = -400.0
var screensize
export var move_direction = -1
export var max_health = 100
onready var health = max_health
onready var shooting_delay = $ShootingDelay
var sprite_index = randi_range(0, 2)
const turnaround_delay = 0.5
var next_turnaround = 0
const death_score_points = 100
func _ready():
emit_signal("max_health_updated", max_health)
emit_signal("health_updated", health)
screensize = get_viewport_rect().size
var random_number = randi()% 2
var direction
match random_number:
0: velocity.x = SPEED
1: velocity.x = -SPEED
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,100) + position
bullet.direction = -1
get_tree().current_scene.add_child(bullet)
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 turn_around():
if next_turnaround > turnaround_delay:
move_direction = -1 * move_direction
next_turnaround = 0
func _physics_process(delta):
next_turnaround += delta
shoot()
velocity.x = SPEED * move_direction
# turns around on collision
var collision_info = move_and_collide(velocity * delta)
if collision_info:
turn_around()
var collider = collision_info.get_collider()
if collider.is_class("Bullet"):
take_damage(collider.damage)
collider.free()
6.6.2. Charger
Der Charger Gegner stellt wiederum etwas Besonderes dar und stellt essentiell eine raumschiffförmige Ramme dar. Er steht erst für eine bestimmte Zeit still und richtet sich in Richtung des Spielers aus. Sobald die Zeit abgelaufen ist, hört er auf sich zu drehen und rast auf den letzten Zielpunkt zu. Dem Spieler bleibt etwas Zeit um dem Ansturm auszuweichen. Mit der großen Anzahl an Lebenspunkten und dem enormen Schaden bei Zusammenstoß, sind sie schwer für den Spieler zu entfernen und dienen dazu den Spieler dazu zu zwingen sich zu bewegen.
Die Entscheidung ob der Gegner stillsteht oder losfliegt wird über die Funktion “determine_flight” geregelt.
Das Zielen auf den Spieler übernimmt die Funktion “adjust_target_direction”.
extends StaticBody2D
const SPEED = 10.0
var target_locked = false
export var fuel_lifetime = 5
var current_fuel = fuel_lifetime
export var target_time = 5
export var remaining_target_time = target_time
export var max_health = 1000
var health = max_health
export var damage = 2000
onready var _sprite = $AnimatedSprite2D
const death_score_points = 100
func adjust_target_direction() :
if is_inside_tree():
var player = get_parent().get_node("Player")# only works if Player and Charger are on the same layer
if player != null:
player.position
look_at(player.position)
func determine_flight(delta):
if remaining_target_time > 0:
adjust_target_direction()
remaining_target_time -= delta
else:
target_locked = true
_sprite.play("blast")
constant_linear_velocity = transform.x * SPEED
func check_fuel(delta):
if current_fuel > 0:
current_fuel -= delta
else:
die()
func _physics_process(delta):
if target_locked: check_fuel(delta)
else: determine_flight(delta)
var collision_info = move_and_collide(constant_linear_velocity)
if target_locked:
if collision_info:
var collider = collision_info.get_collider()
if collider.has_method("take_damage"):
collider.call("take_damage", get_damage())
else:
collider.free()
func get_damage():
return damage
6.6.3. Healthpack
Obwohl sie dem Spieler nicht schaden werden Healthpacks genau wie die Gegner zufällig erzeugt.
Berührt der Spieler diese werden seine Lebenspunkte um einen bestimmten Betrag geheilt.
extends StaticBody2D
class_name Healthpack
export var health = 100
func get_healing():
return health