initial merge
This commit is contained in:
+51
-1
@@ -1,23 +1,29 @@
|
||||
extends CharacterBody3D
|
||||
|
||||
signal died(points: int)
|
||||
signal merged(upgrade: bool)
|
||||
|
||||
enum State { CHASING, FLYING, STUNNED, DEAD }
|
||||
enum State { CHASING, FLYING, STUNNED, DEAD, MERGING }
|
||||
|
||||
var move_speed: float = 3.0
|
||||
var health: int = 30
|
||||
var damage_to_player: int = 8
|
||||
var score_value: int = 10
|
||||
var enemy_level: int = 1
|
||||
var enemy_type: String = "slime"
|
||||
var wall_damage_mult: float = 1.8
|
||||
var chain_factor: float = 0.65
|
||||
var stun_time: float = 0.5
|
||||
var base_scale: float = 1.0
|
||||
var wave_num: int = 1
|
||||
|
||||
var state: State = State.CHASING
|
||||
var fly_vel: Vector3 = Vector3.ZERO
|
||||
var stun_timer: float = 0.0
|
||||
var contact_timer: float = 0.0
|
||||
var target: Node3D = null
|
||||
var merge_partner: Node = null
|
||||
var is_upgrading: bool = false
|
||||
|
||||
@onready var mesh_node: MeshInstance3D = $BodyMesh
|
||||
var mat: StandardMaterial3D
|
||||
@@ -36,6 +42,8 @@ func _ready() -> void:
|
||||
COLOR_CHASE = mat.albedo_color
|
||||
|
||||
func setup(type: String, wave: int) -> void:
|
||||
enemy_type = type
|
||||
wave_num = wave
|
||||
match type:
|
||||
"slime":
|
||||
move_speed = 2.8 + wave * 0.12
|
||||
@@ -89,6 +97,7 @@ func _chase(delta: float) -> void:
|
||||
|
||||
func _fly(delta: float) -> void:
|
||||
var speed_now := Vector2(fly_vel.x, fly_vel.z).length()
|
||||
print_debug("speed is ", speed_now)
|
||||
velocity = fly_vel
|
||||
velocity.y = 0.0
|
||||
move_and_slide()
|
||||
@@ -108,6 +117,10 @@ func _fly(delta: float) -> void:
|
||||
hit_wall = true
|
||||
break
|
||||
elif col3d.is_in_group("enemies") and col3d != self:
|
||||
var other: Node = col3d
|
||||
if speed_now >= 3.0 and other.get("enemy_level") == enemy_level and other.get("is_upgrading") == false and is_upgrading == false:
|
||||
_start_merge(other)
|
||||
else:
|
||||
var chain_dir := col3d.global_position - global_position
|
||||
chain_dir.y = 0.0
|
||||
if chain_dir.length() > 0.01:
|
||||
@@ -141,6 +154,43 @@ func receive_kick(direction: Vector3, force: float) -> void:
|
||||
tw.tween_property(mesh_node, "scale:y", base_scale * 0.35, 0.06)
|
||||
tw.tween_property(mesh_node, "scale:y", base_scale, 0.18)
|
||||
|
||||
func _start_merge(other: Node) -> void:
|
||||
is_upgrading = true
|
||||
other.is_upgrading = true
|
||||
other.merge_partner = self
|
||||
merge_partner = other
|
||||
state = State.MERGING
|
||||
other.state = State.MERGING
|
||||
fly_vel = Vector3.ZERO
|
||||
velocity = Vector3.ZERO
|
||||
other.fly_vel = Vector3.ZERO
|
||||
other.velocity = Vector3.ZERO
|
||||
mat.albedo_color = Color(1.0, 1.0, 0.5)
|
||||
other.mat.albedo_color = Color(1.0, 1.0, 0.5)
|
||||
var tw := create_tween().set_parallel(true)
|
||||
tw.tween_property(self, "global_position", other.global_position, 0.2)
|
||||
tw.tween_property(other, "global_position", global_position, 0.2)
|
||||
tw.tween_callback(_on_merge_complete)
|
||||
|
||||
func _on_merge_complete() -> void:
|
||||
var merge_pos := global_position
|
||||
var merge_type := enemy_type
|
||||
var new_level: int = enemy_level + 1
|
||||
var new_wave: int = wave_num
|
||||
if is_instance_valid(merge_partner):
|
||||
merge_pos = (global_position + merge_partner.global_position) / 2.0
|
||||
merge_partner.queue_free()
|
||||
queue_free()
|
||||
emit_signal("merged", true)
|
||||
var tree := get_tree()
|
||||
if tree != null and tree.has_group("main"):
|
||||
var main := tree.get_nodes_in_group("main")[0] as Node
|
||||
if main != null and main.has_method("_spawn_upgraded_enemy"):
|
||||
var new_enemy := main.call("_spawn_upgraded_enemy", merge_pos, merge_type, new_level, new_wave) as CharacterBody3D
|
||||
if new_enemy != null:
|
||||
new_enemy.state = State.FLYING
|
||||
new_enemy.fly_vel = Vector3.ZERO
|
||||
|
||||
func _enter_stun() -> void:
|
||||
state = State.STUNNED
|
||||
stun_timer = stun_time
|
||||
|
||||
@@ -43,6 +43,7 @@ func _ready() -> void:
|
||||
_create_ui()
|
||||
_spawn_player()
|
||||
_start_game()
|
||||
add_to_group("main")
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
@@ -224,6 +225,7 @@ func _spawn_enemy() -> void:
|
||||
enemy.setup(type, wave)
|
||||
enemy.target = player
|
||||
enemy.connect("died", _on_enemy_died)
|
||||
enemy.connect("merged", _on_enemy_merged)
|
||||
|
||||
# Spawn at random edge
|
||||
var side := randi() % 4
|
||||
@@ -246,6 +248,31 @@ func _on_enemy_died(points: int) -> void:
|
||||
wave += 1
|
||||
_show_upgrade()
|
||||
|
||||
func _spawn_upgraded_enemy(pos: Vector3, type: String, level: int, w: int) -> CharacterBody3D:
|
||||
var enemy := ENEMY_SCENE.instantiate() as CharacterBody3D
|
||||
add_child(enemy)
|
||||
enemy.setup(type, w)
|
||||
enemy.target = player
|
||||
enemy.enemy_level = level + 1
|
||||
enemy.global_position = pos
|
||||
enemy.connect("died", _on_enemy_died)
|
||||
enemy.connect("merged", _on_enemy_merged)
|
||||
var tw := enemy.create_tween()
|
||||
var s: float = 1.0 + level * 0.3
|
||||
tw.tween_property(enemy.mesh_node, "scale", Vector3(s, s, s), 0.2)
|
||||
var col_shape := enemy.get_node_or_null("CollisionShape3D") as CollisionShape3D
|
||||
if col_shape != null and col_shape.shape != null:
|
||||
var s3d: BoxShape3D = col_shape.shape as BoxShape3D
|
||||
var old_size: Vector3 = s3d.size
|
||||
col_shape.shape = BoxShape3D.new()
|
||||
(col_shape.shape as BoxShape3D).size = old_size * s
|
||||
var color := Color(1.0, 1.0, 0.5) if level > 2 else Color(1.0, 0.9, 0.3)
|
||||
tw.tween_property(enemy.mat, "albedo_color", color, 0.25)
|
||||
return enemy
|
||||
|
||||
func _on_enemy_merged(_upgrade: bool) -> void:
|
||||
pass
|
||||
|
||||
func _on_player_died() -> void:
|
||||
game_active = false
|
||||
spawn_timer.stop()
|
||||
|
||||
Reference in New Issue
Block a user