game: add enemy taunt on death
This commit is contained in:
		| @@ -1,3 +1,4 @@ | |||||||
|  | class_name Enemy | ||||||
| extends CharacterBody2D | extends CharacterBody2D | ||||||
|  |  | ||||||
| @export var target: CollisionObject2D | @export var target: CollisionObject2D | ||||||
| @@ -12,6 +13,7 @@ var move_speed: float | |||||||
| var health: float | var health: float | ||||||
| var max_health: float | var max_health: float | ||||||
| var god_mode: bool = false | var god_mode: bool = false | ||||||
|  | var is_dead: bool = false | ||||||
|  |  | ||||||
| func _ready() -> void: | func _ready() -> void: | ||||||
| 	move_speed = default_move_speed | 	move_speed = default_move_speed | ||||||
| @@ -33,6 +35,9 @@ func take_damage(value: float): | |||||||
| 	if god_mode: | 	if god_mode: | ||||||
| 		return | 		return | ||||||
| 	health -= value | 	health -= value | ||||||
|  | 	var dm = preload("res://scenes/damage_numbers.tscn").instantiate() | ||||||
|  | 	dm.damage_taken = value | ||||||
|  | 	add_child(dm) | ||||||
| 	if health <= 0: | 	if health <= 0: | ||||||
| 		die() | 		die() | ||||||
| 		 | 		 | ||||||
| @@ -43,10 +48,21 @@ func deal_damage(): | |||||||
| 			contact_damage_cd.start() | 			contact_damage_cd.start() | ||||||
|  |  | ||||||
| func die(): | func die(): | ||||||
| 	queue_free() | 	if is_dead: | ||||||
|  | 		return | ||||||
|  | 	is_dead = true | ||||||
|  | 	target = null | ||||||
|  | 	velocity = Vector2.ZERO | ||||||
|  | 	animation_player.play("die") | ||||||
|  | 	animation_player.animation_finished.connect(_on_die_anim_finished) | ||||||
|  |  | ||||||
| func cheer_anim(): | func cheer_anim(): | ||||||
| 	animation_player.play("jump") | 	if not animation_player.is_playing(): | ||||||
|  | 		animation_player.play("jump") | ||||||
| 	 | 	 | ||||||
| func enemy_god_mode_toggle(toggle_on: bool) -> void: | func enemy_god_mode_toggle(toggle_on: bool) -> void: | ||||||
| 	god_mode = toggle_on | 	god_mode = toggle_on | ||||||
|  |  | ||||||
|  | func _on_die_anim_finished(name: String): | ||||||
|  | 	visible = false | ||||||
|  | 	queue_free() | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| [gd_scene load_steps=7 format=3 uid="uid://bn8c0cgecvjxl"] | [gd_scene load_steps=8 format=3 uid="uid://bn8c0cgecvjxl"] | ||||||
|  |  | ||||||
| [ext_resource type="Texture2D" uid="uid://5x5wimok8uw2" path="res://assets/sprites/roguelikeChar_transparent.png" id="1_6xk8f"] | [ext_resource type="Texture2D" uid="uid://5x5wimok8uw2" path="res://assets/sprites/roguelikeChar_transparent.png" id="1_6xk8f"] | ||||||
| [ext_resource type="Script" uid="uid://ctigdofipl4q5" path="res://scenes/enemies/enemy.gd" id="1_8e3ao"] | [ext_resource type="Script" uid="uid://ctigdofipl4q5" path="res://scenes/enemies/enemy.gd" id="1_8e3ao"] | ||||||
| @@ -20,6 +20,30 @@ tracks/0/keys = { | |||||||
| "update": 0, | "update": 0, | ||||||
| "values": [Vector2(0, 0)] | "values": [Vector2(0, 0)] | ||||||
| } | } | ||||||
|  | tracks/1/type = "value" | ||||||
|  | tracks/1/imported = false | ||||||
|  | tracks/1/enabled = true | ||||||
|  | tracks/1/path = NodePath("Sprite2D:rotation") | ||||||
|  | tracks/1/interp = 1 | ||||||
|  | tracks/1/loop_wrap = true | ||||||
|  | tracks/1/keys = { | ||||||
|  | "times": PackedFloat32Array(0), | ||||||
|  | "transitions": PackedFloat32Array(1), | ||||||
|  | "update": 0, | ||||||
|  | "values": [0.0] | ||||||
|  | } | ||||||
|  | tracks/2/type = "value" | ||||||
|  | tracks/2/imported = false | ||||||
|  | tracks/2/enabled = true | ||||||
|  | tracks/2/path = NodePath("Sprite2D:modulate") | ||||||
|  | tracks/2/interp = 1 | ||||||
|  | tracks/2/loop_wrap = true | ||||||
|  | tracks/2/keys = { | ||||||
|  | "times": PackedFloat32Array(0), | ||||||
|  | "transitions": PackedFloat32Array(1), | ||||||
|  | "update": 0, | ||||||
|  | "values": [Color(1, 1, 1, 1)] | ||||||
|  | } | ||||||
|  |  | ||||||
| [sub_resource type="Animation" id="Animation_8e3ao"] | [sub_resource type="Animation" id="Animation_8e3ao"] | ||||||
| resource_name = "jump" | resource_name = "jump" | ||||||
| @@ -38,9 +62,38 @@ tracks/0/keys = { | |||||||
| "values": [Vector2(0, 0), Vector2(0, -7)] | "values": [Vector2(0, 0), Vector2(0, -7)] | ||||||
| } | } | ||||||
|  |  | ||||||
|  | [sub_resource type="Animation" id="Animation_fcftc"] | ||||||
|  | resource_name = "die" | ||||||
|  | length = 2.0 | ||||||
|  | tracks/0/type = "value" | ||||||
|  | tracks/0/imported = false | ||||||
|  | tracks/0/enabled = true | ||||||
|  | tracks/0/path = NodePath("Sprite2D:rotation") | ||||||
|  | tracks/0/interp = 1 | ||||||
|  | tracks/0/loop_wrap = true | ||||||
|  | tracks/0/keys = { | ||||||
|  | "times": PackedFloat32Array(0, 1), | ||||||
|  | "transitions": PackedFloat32Array(0.225313, -2), | ||||||
|  | "update": 0, | ||||||
|  | "values": [0.0, 1.5708] | ||||||
|  | } | ||||||
|  | tracks/1/type = "value" | ||||||
|  | tracks/1/imported = false | ||||||
|  | tracks/1/enabled = true | ||||||
|  | tracks/1/path = NodePath("Sprite2D:modulate") | ||||||
|  | tracks/1/interp = 1 | ||||||
|  | tracks/1/loop_wrap = true | ||||||
|  | tracks/1/keys = { | ||||||
|  | "times": PackedFloat32Array(0, 1, 2), | ||||||
|  | "transitions": PackedFloat32Array(1, 0.287175, 0.406126), | ||||||
|  | "update": 0, | ||||||
|  | "values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] | ||||||
|  | } | ||||||
|  |  | ||||||
| [sub_resource type="AnimationLibrary" id="AnimationLibrary_38ino"] | [sub_resource type="AnimationLibrary" id="AnimationLibrary_38ino"] | ||||||
| _data = { | _data = { | ||||||
| &"RESET": SubResource("Animation_38ino"), | &"RESET": SubResource("Animation_38ino"), | ||||||
|  | &"die": SubResource("Animation_fcftc"), | ||||||
| &"jump": SubResource("Animation_8e3ao") | &"jump": SubResource("Animation_8e3ao") | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ var enemy_scene = preload("res://scenes/enemies/enemy.tscn") | |||||||
| func _ready() -> void: | func _ready() -> void: | ||||||
| 	timer.wait_time = spawn_rate / 1 | 	timer.wait_time = spawn_rate / 1 | ||||||
| 	timer.start() | 	timer.start() | ||||||
|  | 	GlobalConst.sig_stop_spawning.connect(_on_stop_spawning) | ||||||
|  |  | ||||||
|  |  | ||||||
| func _on_timer_timeout() -> void: | func _on_timer_timeout() -> void: | ||||||
| @@ -22,3 +23,9 @@ func _on_timer_timeout() -> void: | |||||||
| 		new_enemy.position = target.position + Vector2(50, 50) | 		new_enemy.position = target.position + Vector2(50, 50) | ||||||
| 		new_enemy.target = target | 		new_enemy.target = target | ||||||
| 		add_child(new_enemy) | 		add_child(new_enemy) | ||||||
|  | 		 | ||||||
|  | func _on_stop_spawning(val: bool): | ||||||
|  | 	if val: | ||||||
|  | 		timer.stop() | ||||||
|  | 	elif timer.is_stopped(): | ||||||
|  | 		timer.start() | ||||||
|   | |||||||
| @@ -40,6 +40,10 @@ func take_damage(value: float) -> void: | |||||||
| 		return | 		return | ||||||
| 	health -= value | 	health -= value | ||||||
| 	print_debug("player took damage. now has %s hp" % health) | 	print_debug("player took damage. now has %s hp" % health) | ||||||
|  | 	var dm = preload("res://scenes/damage_numbers.tscn").instantiate() | ||||||
|  | 	dm.damage_taken = value | ||||||
|  | 	dm.player_damage = false | ||||||
|  | 	add_child(dm) | ||||||
| 	main_ui.player_ui.set_hp(health / max_health * 100) | 	main_ui.player_ui.set_hp(health / max_health * 100) | ||||||
| 	if health <= 0: | 	if health <= 0: | ||||||
| 		die() | 		die() | ||||||
| @@ -48,7 +52,9 @@ func die(): | |||||||
| 	dead = true | 	dead = true | ||||||
| 	remove_from_group("damagable") | 	remove_from_group("damagable") | ||||||
| 	get_tree().call_group("enemy", "cheer_anim") | 	get_tree().call_group("enemy", "cheer_anim") | ||||||
|  | 	GlobalConst.sig_stop_spawning.emit(true) | ||||||
| 	sprite_2d.z_index += 10 | 	sprite_2d.z_index += 10 | ||||||
|  | 	get_taunted() | ||||||
|  |  | ||||||
| func death_animation(delta: float): | func death_animation(delta: float): | ||||||
| 	# Engine.time_scale = clampf(lerpf(Engine.time_scale, 0.25, 0.5), 0.25, 0.9*delta) | 	# Engine.time_scale = clampf(lerpf(Engine.time_scale, 0.25, 0.5), 0.25, 0.9*delta) | ||||||
| @@ -57,7 +63,25 @@ func death_animation(delta: float): | |||||||
| 	if rotation_degrees > 88: | 	if rotation_degrees > 88: | ||||||
| 		main_ui.pause_ui.toggle_pause_ui() | 		main_ui.pause_ui.toggle_pause_ui() | ||||||
| 		death_anim_done = true | 		death_anim_done = true | ||||||
| 	 |  | ||||||
|  | func get_taunted(): | ||||||
|  | 	var taunting_enemies: Array[Enemy] = [] | ||||||
|  | 	for body in get_tree().get_nodes_in_group(GlobalConst.GROUP_ENEMY): | ||||||
|  | 		if global_position.distance_to(body.global_position) < 500.0: | ||||||
|  | 			taunting_enemies.append(body) | ||||||
|  | 	for i in range(taunting_enemies.size()): | ||||||
|  | 		var angle = (TAU / taunting_enemies.size()) * i | ||||||
|  | 		var target_pos = Vector2(cos(angle), sin(angle)) * 50 | ||||||
|  | 		print_debug("my_pos: %s" % position) | ||||||
|  | 		print_debug("pos: %s" % target_pos) | ||||||
|  | 		var new_target = StaticBody2D.new() | ||||||
|  | 		var collision = CollisionShape2D.new() | ||||||
|  | 		new_target.position = target_pos | ||||||
|  | 		add_child(new_target) | ||||||
|  | 		new_target.add_child(collision) | ||||||
|  | 		taunting_enemies[i].target = new_target | ||||||
|  | 		 | ||||||
|  |  | ||||||
| func toggle_god_mode(value: bool): | func toggle_god_mode(value: bool): | ||||||
| 	god_mode = value | 	god_mode = value | ||||||
| 	 | 	 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user