Demo: Implement basic knockback
This commit is contained in:
parent
79813d57a8
commit
fa804f3f6d
|
@ -38,10 +38,10 @@ scale_max = 1.2
|
||||||
scale_curve = SubResource("CurveTexture_sb0wp")
|
scale_curve = SubResource("CurveTexture_sb0wp")
|
||||||
|
|
||||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2k81i"]
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2k81i"]
|
||||||
size = Vector2(100, 35)
|
size = Vector2(130, 35)
|
||||||
|
|
||||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_26abe"]
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_26abe"]
|
||||||
size = Vector2(70, 35)
|
size = Vector2(80, 35)
|
||||||
|
|
||||||
[sub_resource type="CircleShape2D" id="CircleShape2D_0c228"]
|
[sub_resource type="CircleShape2D" id="CircleShape2D_0c228"]
|
||||||
|
|
||||||
|
@ -359,6 +359,18 @@ tracks/25/keys = {
|
||||||
"update": 1,
|
"update": 1,
|
||||||
"values": [false]
|
"values": [false]
|
||||||
}
|
}
|
||||||
|
tracks/26/type = "value"
|
||||||
|
tracks/26/imported = false
|
||||||
|
tracks/26/enabled = true
|
||||||
|
tracks/26/path = NodePath("Root/Hitbox:knockback_enabled")
|
||||||
|
tracks/26/interp = 1
|
||||||
|
tracks/26/loop_wrap = true
|
||||||
|
tracks/26/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 1,
|
||||||
|
"values": [false]
|
||||||
|
}
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_8wj70"]
|
[sub_resource type="Animation" id="Animation_8wj70"]
|
||||||
resource_name = "attack_1"
|
resource_name = "attack_1"
|
||||||
|
@ -1142,6 +1154,18 @@ tracks/19/keys = {
|
||||||
"update": 1,
|
"update": 1,
|
||||||
"values": [true, false, true]
|
"values": [true, false, true]
|
||||||
}
|
}
|
||||||
|
tracks/20/type = "value"
|
||||||
|
tracks/20/imported = false
|
||||||
|
tracks/20/enabled = true
|
||||||
|
tracks/20/path = NodePath("Root/Hitbox:knockback_enabled")
|
||||||
|
tracks/20/interp = 1
|
||||||
|
tracks/20/loop_wrap = true
|
||||||
|
tracks/20/keys = {
|
||||||
|
"times": PackedFloat32Array(0.2, 0.35),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 1,
|
||||||
|
"values": [true, false]
|
||||||
|
}
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_wei72"]
|
[sub_resource type="Animation" id="Animation_wei72"]
|
||||||
resource_name = "death"
|
resource_name = "death"
|
||||||
|
@ -1704,6 +1728,18 @@ tracks/21/keys = {
|
||||||
"update": 1,
|
"update": 1,
|
||||||
"values": [false, false]
|
"values": [false, false]
|
||||||
}
|
}
|
||||||
|
tracks/22/type = "value"
|
||||||
|
tracks/22/imported = false
|
||||||
|
tracks/22/enabled = true
|
||||||
|
tracks/22/path = NodePath("Root/Hitbox:knockback_enabled")
|
||||||
|
tracks/22/interp = 1
|
||||||
|
tracks/22/loop_wrap = true
|
||||||
|
tracks/22/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.25),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 1,
|
||||||
|
"values": [false, false]
|
||||||
|
}
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_gnqgt"]
|
[sub_resource type="Animation" id="Animation_gnqgt"]
|
||||||
resource_name = "idle"
|
resource_name = "idle"
|
||||||
|
@ -3509,9 +3545,8 @@ fixed_fps = 60
|
||||||
|
|
||||||
[node name="WeaponNinjaStar" type="Sprite2D" parent="Root"]
|
[node name="WeaponNinjaStar" type="Sprite2D" parent="Root"]
|
||||||
visible = false
|
visible = false
|
||||||
position = Vector2(-71.6739, -72.9077)
|
position = Vector2(-55, -76)
|
||||||
rotation = 0.204683
|
scale = Vector2(0.999982, 0.999976)
|
||||||
scale = Vector2(0.999983, 0.999976)
|
|
||||||
texture = ExtResource("4_1c5xq")
|
texture = ExtResource("4_1c5xq")
|
||||||
|
|
||||||
[node name="Hitbox" type="Area2D" parent="Root"]
|
[node name="Hitbox" type="Area2D" parent="Root"]
|
||||||
|
@ -3519,6 +3554,7 @@ position = Vector2(50, 0)
|
||||||
collision_layer = 0
|
collision_layer = 0
|
||||||
collision_mask = 4
|
collision_mask = 4
|
||||||
script = ExtResource("5_taq6b")
|
script = ExtResource("5_taq6b")
|
||||||
|
knockback_strength = 1000.0
|
||||||
|
|
||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Root/Hitbox"]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="Root/Hitbox"]
|
||||||
shape = SubResource("RectangleShape2D_2k81i")
|
shape = SubResource("RectangleShape2D_2k81i")
|
||||||
|
|
|
@ -11,6 +11,11 @@ collision_layer = 0
|
||||||
collision_mask = 1
|
collision_mask = 1
|
||||||
script = ExtResource("2_24nyi")
|
script = ExtResource("2_24nyi")
|
||||||
|
|
||||||
|
[node name="WeaponNinjaStar" parent="Root" index="2"]
|
||||||
|
position = Vector2(-55, -76)
|
||||||
|
rotation = 0.0
|
||||||
|
scale = Vector2(0.999983, 0.999976)
|
||||||
|
|
||||||
[node name="Hitbox" parent="Root" index="3"]
|
[node name="Hitbox" parent="Root" index="3"]
|
||||||
collision_mask = 8
|
collision_mask = 8
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,10 @@ func _update(_delta: float) -> void:
|
||||||
var horizontal_move: float = Input.get_axis(&"move_left", &"move_right")
|
var horizontal_move: float = Input.get_axis(&"move_left", &"move_right")
|
||||||
var vertical_move: float = Input.get_axis(&"move_up", &"move_down")
|
var vertical_move: float = Input.get_axis(&"move_up", &"move_down")
|
||||||
|
|
||||||
agent.velocity = lerp(agent.velocity, Vector2(horizontal_move, vertical_move * VERTICAL_FACTOR) * speed, 0.2)
|
var desired_velocity := Vector2(horizontal_move, vertical_move * VERTICAL_FACTOR) * speed
|
||||||
|
agent.velocity = lerp(agent.velocity, desired_velocity, 0.2)
|
||||||
agent.move_and_slide()
|
agent.move_and_slide()
|
||||||
|
agent.update_facing()
|
||||||
|
|
||||||
if horizontal_move == 0.0 and vertical_move == 0.0:
|
if horizontal_move == 0.0 and vertical_move == 0.0:
|
||||||
get_root().dispatch(EVENT_FINISHED)
|
get_root().dispatch(EVENT_FINISHED)
|
||||||
|
|
|
@ -19,6 +19,7 @@ const NinjaStar := preload("res://demo/agents/ninja_star/ninja_star.tscn")
|
||||||
@onready var root: Node2D = $Root
|
@onready var root: Node2D = $Root
|
||||||
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
|
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
|
||||||
|
|
||||||
|
|
||||||
var _frames_since_facing_update: int = 0
|
var _frames_since_facing_update: int = 0
|
||||||
var _is_dead: bool = false
|
var _is_dead: bool = false
|
||||||
|
|
||||||
|
@ -27,11 +28,7 @@ func _ready() -> void:
|
||||||
health.death.connect(_die)
|
health.death.connect(_die)
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(_delta: float) -> void:
|
func update_facing() -> void:
|
||||||
_update_facing()
|
|
||||||
|
|
||||||
|
|
||||||
func _update_facing() -> void:
|
|
||||||
_frames_since_facing_update += 1
|
_frames_since_facing_update += 1
|
||||||
if _frames_since_facing_update > 3:
|
if _frames_since_facing_update > 3:
|
||||||
face_dir(velocity.x)
|
face_dir(velocity.x)
|
||||||
|
@ -57,7 +54,8 @@ func throw_ninja_star() -> void:
|
||||||
ninja_star.global_position = global_position + Vector2.RIGHT * 100.0 * get_facing()
|
ninja_star.global_position = global_position + Vector2.RIGHT * 100.0 * get_facing()
|
||||||
|
|
||||||
|
|
||||||
func _damaged(_amount: float) -> void:
|
func _damaged(_amount: float, knockback: Vector2) -> void:
|
||||||
|
apply_knockback(knockback)
|
||||||
animation_player.play(&"hurt")
|
animation_player.play(&"hurt")
|
||||||
var btplayer := get_node_or_null(^"BTPlayer") as BTPlayer
|
var btplayer := get_node_or_null(^"BTPlayer") as BTPlayer
|
||||||
if btplayer:
|
if btplayer:
|
||||||
|
@ -72,8 +70,18 @@ func _damaged(_amount: float) -> void:
|
||||||
hsm.set_active(true)
|
hsm.set_active(true)
|
||||||
|
|
||||||
|
|
||||||
|
func apply_knockback(knockback: Vector2, frames: int = 10) -> void:
|
||||||
|
if knockback.is_zero_approx():
|
||||||
|
return
|
||||||
|
for i in range(frames):
|
||||||
|
velocity = lerp(velocity, knockback, 0.2)
|
||||||
|
move_and_slide()
|
||||||
|
await get_tree().physics_frame
|
||||||
|
|
||||||
|
|
||||||
func _die() -> void:
|
func _die() -> void:
|
||||||
_is_dead = true
|
_is_dead = true
|
||||||
|
root.process_mode = Node.PROCESS_MODE_DISABLED
|
||||||
animation_player.play(&"death")
|
animation_player.play(&"death")
|
||||||
collision_shape_2d.set_deferred(&"disabled", true)
|
collision_shape_2d.set_deferred(&"disabled", true)
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ extends Node
|
||||||
|
|
||||||
|
|
||||||
signal death
|
signal death
|
||||||
signal damaged(amount: float)
|
signal damaged(amount: float, knockback: Vector2)
|
||||||
|
|
||||||
@export var max_health: float = 10.0
|
@export var max_health: float = 10.0
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ func _ready() -> void:
|
||||||
_current = max_health
|
_current = max_health
|
||||||
|
|
||||||
|
|
||||||
func take_damage(amount: float) -> void:
|
func take_damage(amount: float, knockback: Vector2) -> void:
|
||||||
if _current <= 0.0:
|
if _current <= 0.0:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ func take_damage(amount: float) -> void:
|
||||||
if _current <= 0.0:
|
if _current <= 0.0:
|
||||||
death.emit()
|
death.emit()
|
||||||
else:
|
else:
|
||||||
damaged.emit(amount)
|
damaged.emit(amount, knockback)
|
||||||
|
|
||||||
|
|
||||||
func get_current() -> float:
|
func get_current() -> float:
|
||||||
|
|
|
@ -12,14 +12,22 @@ class_name Hitbox
|
||||||
extends Area2D
|
extends Area2D
|
||||||
## Area that deals damage.
|
## Area that deals damage.
|
||||||
|
|
||||||
|
|
||||||
@export var damage: float = 1.0
|
@export var damage: float = 1.0
|
||||||
|
@export var knockback_enabled: bool = false
|
||||||
|
@export var knockback_strength: float = 500.0
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
area_entered.connect(_area_entered)
|
area_entered.connect(_area_entered)
|
||||||
|
|
||||||
|
|
||||||
func _area_entered(area: Area2D) -> void:
|
func _area_entered(hurtbox: Hurtbox) -> void:
|
||||||
var hurtbox := area as Hurtbox
|
if hurtbox.owner == owner:
|
||||||
hurtbox.take_damage(damage, self)
|
return
|
||||||
|
hurtbox.take_damage(damage, get_knockback())
|
||||||
|
|
||||||
|
|
||||||
|
func get_knockback() -> Vector2:
|
||||||
|
var knockback: Vector2
|
||||||
|
if knockback_enabled:
|
||||||
|
knockback = Vector2.RIGHT.rotated(global_rotation) * knockback_strength
|
||||||
|
return knockback
|
||||||
|
|
|
@ -16,8 +16,5 @@ extends Area2D
|
||||||
@export var health: Health
|
@export var health: Health
|
||||||
|
|
||||||
|
|
||||||
func take_damage(amount: float, source: Area2D) -> void:
|
func take_damage(amount: float, knockback: Vector2) -> void:
|
||||||
if source.owner == owner:
|
health.take_damage(amount, knockback)
|
||||||
# Don't damage yourself.
|
|
||||||
return
|
|
||||||
health.take_damage(amount)
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ func _tick(_delta: float) -> Status:
|
||||||
vertical_factor = clampf(vertical_factor, 0.0, 1.0)
|
vertical_factor = clampf(vertical_factor, 0.0, 1.0)
|
||||||
var dir: Vector2 = agent.global_position.direction_to(target_pos)
|
var dir: Vector2 = agent.global_position.direction_to(target_pos)
|
||||||
dir.y *= vertical_factor
|
dir.y *= vertical_factor
|
||||||
agent.velocity = dir.normalized() * speed
|
var desired_velocity: Vector2 = dir.normalized() * speed
|
||||||
|
agent.velocity = lerp(agent.velocity, desired_velocity, 0.2)
|
||||||
agent.move_and_slide()
|
agent.move_and_slide()
|
||||||
|
agent.update_facing()
|
||||||
return RUNNING
|
return RUNNING
|
||||||
|
|
|
@ -25,8 +25,10 @@ func _generate_name() -> String:
|
||||||
# Called each time this task is ticked (aka executed).
|
# Called each time this task is ticked (aka executed).
|
||||||
func _tick(_delta: float) -> Status:
|
func _tick(_delta: float) -> Status:
|
||||||
var facing: float = agent.get_facing()
|
var facing: float = agent.get_facing()
|
||||||
agent.velocity = Vector2.RIGHT * facing * force
|
var desired_velocity: Vector2 = Vector2.RIGHT * facing * force
|
||||||
|
agent.velocity = lerp(agent.velocity, desired_velocity, 0.2)
|
||||||
agent.move_and_slide()
|
agent.move_and_slide()
|
||||||
|
agent.update_facing()
|
||||||
if elapsed_time > duration:
|
if elapsed_time > duration:
|
||||||
return SUCCESS
|
return SUCCESS
|
||||||
return RUNNING
|
return RUNNING
|
||||||
|
|
|
@ -50,8 +50,10 @@ func _tick(_delta: float) -> Status:
|
||||||
var speed: float = blackboard.get_var(speed_var, 200.0)
|
var speed: float = blackboard.get_var(speed_var, 200.0)
|
||||||
if agent.global_position.distance_to(_waypoint) < TOLERANCE:
|
if agent.global_position.distance_to(_waypoint) < TOLERANCE:
|
||||||
_select_new_waypoint(desired_pos)
|
_select_new_waypoint(desired_pos)
|
||||||
agent.velocity = agent.global_position.direction_to(_waypoint) * speed
|
var desired_velocity: Vector2 = agent.global_position.direction_to(_waypoint) * speed
|
||||||
|
agent.velocity = lerp(agent.velocity, desired_velocity, 0.2)
|
||||||
agent.move_and_slide()
|
agent.move_and_slide()
|
||||||
|
agent.update_facing()
|
||||||
return RUNNING
|
return RUNNING
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue