LD55/gander_schwartz.gd

210 lines
6.1 KiB
GDScript

extends CharacterBody2D
class_name MainCharacter
var player_controlled = false
enum GanderSceneT {
Introduction,
Gameplay,
Battle,
}
var current_scene_type = GanderSceneT.Introduction
var auto_control_action = "facing_front"
var last_collided_id = null
@onready var parry_area = $ParryArea2D
@onready var hit_area = $HitArea2D
@onready var animated = $AnimatedSprite2D
var battle_started = false
var max_health = 30
var health = 30
var health_dirty = true
var summon_item = null
var summon_item_angle = 0.0
var summon_item_summoned = false
var summon_tween
var parry_tween = null
var parry_active = false
var parry_body = null
var hit_active = false
var parry_success = false
var parry_success_checked = false
enum AttackType {
SWORD,
HAMMER,
}
var attack_target = null
var attack_tween = null
var attack_type = AttackType.SWORD
const SPEED = 150.0
const ANIM_DEADZONE = 0.3
const SUMMON_ITEM_DIST = 100.0
const SUMMON_ITEM_Y_OFFSET = -30.0
func parry_entered(node):
parry_active = true
parry_success_checked = false
parry_body = node
func parry_exited(node):
parry_active = false
parry_body = null
if battle_started:
if parry_success:
print("Successful parry")
parry_success = false
else:
print("Failed to parry")
var rng = RandomNumberGenerator.new()
health -= rng.randi_range(1, 5)
health_dirty = true
func hit_entered(node):
hit_active = true
func hit_exited(node):
hit_active = false
func _ready():
parry_area.area_entered.connect(parry_entered)
parry_area.area_exited.connect(parry_exited)
hit_area.area_entered.connect(hit_entered)
hit_area.area_exited.connect(hit_exited)
func _process(delta):
if parry_tween == null and attack_target == null:
summon_item_angle += delta
if summon_item_angle > TAU:
summon_item_angle -= TAU
if summon_item != null and not parry_success:
summon_item.position.x = cos(-summon_item_angle) * SUMMON_ITEM_DIST
summon_item.position.y = sin(-summon_item_angle) * SUMMON_ITEM_DIST + SUMMON_ITEM_Y_OFFSET
elif parry_success and not parry_success_checked and parry_body != null:
parry_success_checked = true
parry_tween = get_tree().create_tween()
parry_tween.set_parallel()
parry_tween.set_trans(Tween.TRANS_SPRING)
var between = parry_body.get_parent().position - self.position
parry_tween.tween_property(summon_item, "position", between, 0.2)
parry_tween.set_trans(Tween.TRANS_EXPO)
parry_tween.tween_property(summon_item, "rotation", TAU * 10, 0.3)
parry_tween.set_parallel(false)
var old_x = cos(-summon_item_angle) * SUMMON_ITEM_DIST
var old_y = sin(-summon_item_angle) * SUMMON_ITEM_DIST + SUMMON_ITEM_Y_OFFSET
parry_tween.set_trans(Tween.TRANS_EXPO)
parry_tween.tween_property(summon_item, "position", Vector2(old_x, old_y), 0.4)
parry_tween.tween_callback(func():
parry_tween = null
summon_item.rotation = 0.0
)
elif attack_target != null and summon_item != null:
attack_tween = get_tree().create_tween()
var prev_x = cos(-summon_item_angle) * SUMMON_ITEM_DIST
var prev_y = sin(-summon_item_angle) * SUMMON_ITEM_DIST + SUMMON_ITEM_Y_OFFSET
attack_tween.set_parallel()
attack_tween.tween_property(summon_item, "position", attack_target.position - self.position, 0.2)
attack_tween.tween_property(summon_item, "rotation", -PI / 2.0, 0.2)
attack_tween.set_parallel(false)
var parent = get_parent()
attack_tween.tween_callback(func():
match attack_type:
AttackType.SWORD:
parent.play_attack_sfx_type = "sword"
AttackType.HAMMER:
parent.play_attack_sfx_type = "hammer"
)
attack_tween.set_parallel()
attack_tween.tween_property(summon_item, "position", Vector2(prev_x, prev_y), 0.4)
attack_tween.tween_property(summon_item, "rotation", 0.0, 0.4)
attack_tween.set_parallel(false)
attack_tween.tween_callback(func():
attack_target = null
)
if summon_item_summoned:
summon_item_summoned = false
var summon_overlay = Sprite2D.new()
summon_overlay.set_name(&"SummonOverlay")
summon_overlay.set_texture(summon_item.get_texture())
add_child(summon_overlay, true)
summon_overlay.set_owner(self)
summon_overlay.set_scale(Vector2(5.0, 5.0))
summon_overlay.self_modulate = Color(1.0, 1.0, 1.0, 0.4)
summon_tween = get_tree().create_tween()
summon_tween.set_parallel()
summon_tween.set_trans(Tween.TRANS_EXPO)
summon_tween.tween_property(summon_overlay, "rotation", -TAU * 50.0, 2.0)
summon_tween.set_trans(Tween.TRANS_QUAD)
summon_tween.tween_property(summon_overlay, "self_modulate", Color(1.0, 1.0, 1.0, 0.0), 2.0)
summon_tween.set_parallel(false)
summon_tween.tween_callback(func(): self.remove_child(summon_overlay))
if health_dirty:
health_dirty = false
var hp_label = find_child("PlayerHPLabel")
if hp_label == null:
hp_label = Label.new()
hp_label.set_name(&"PlayerHPLabel")
add_child(hp_label, true)
hp_label.set_owner(self)
hp_label.position.y += 10.0
hp_label.position.x -= 18.0
hp_label.text = "%d HP" % health
func _physics_process(delta):
var vec2 = Vector2()
if player_controlled:
if Input.is_action_pressed("Left"):
vec2.x = -1.0
elif Input.is_action_pressed("Right"):
vec2.x = 1.0
if Input.is_action_pressed("Up"):
vec2.y = -1.0
elif Input.is_action_pressed("Down"):
vec2.y = 1.0
if vec2.length() > 0.1:
vec2 = vec2.normalized()
else:
vec2.x = 0.0
vec2.y = 0.0
if vec2.x > ANIM_DEADZONE:
animated.play("walking_right")
elif vec2.x < -ANIM_DEADZONE:
animated.play("walking_left")
elif vec2.y > ANIM_DEADZONE:
animated.play("walking_front")
elif vec2.y < -ANIM_DEADZONE:
animated.play("walking_back")
else:
match animated.animation:
"walking_right":
animated.play("facing_right")
"walking_left":
animated.play("facing_left")
"walking_front":
animated.play("facing_front")
"walking_back":
animated.play("facing_back")
_:
pass
velocity = vec2 * SPEED
elif animated.animation != auto_control_action:
animated.play(auto_control_action)
if current_scene_type != GanderSceneT.Battle:
move_and_slide()
var last_collision = get_last_slide_collision()
if last_collision != null:
last_collided_id = last_collision.get_collider_id()
else:
last_collided_id = null