feat: improved dragon walking behaviour
This commit is contained in:
parent
b4594bdd43
commit
d8419cb9a4
8 changed files with 150 additions and 66 deletions
|
@ -8,7 +8,7 @@ class_name DragonEntity
|
|||
@export var min_exit_time: float
|
||||
@export var max_exit_time: float
|
||||
|
||||
signal on_pick(dragon_id: int, position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String)
|
||||
signal on_pick(dragon_id: int, position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D)
|
||||
signal on_quit(dragon_id: int)
|
||||
|
||||
var rng: RandomNumberGenerator = RandomNumberGenerator.new()
|
||||
|
@ -43,13 +43,9 @@ func _input_event(viewport, event, shape_idx) -> void:
|
|||
if event is InputEventMouseButton \
|
||||
and event.button_index == MOUSE_BUTTON_LEFT \
|
||||
and event.is_pressed():
|
||||
on_pick.emit(id, position + $CollisionShape2D.position, dragon.hat.texture, dragon.shirt.texture, dragon.shoes.texture, dragon.name_label.text)
|
||||
on_pick.emit(id, position + $CollisionShape2D.position, dragon.hat.texture, dragon.shirt.texture, dragon.shoes.texture)
|
||||
queue_free()
|
||||
|
||||
|
||||
func dress(hat: Texture2D, shirt: Texture2D, shoes: Texture2D):
|
||||
dragon.dress(hat, shirt, shoes)
|
||||
|
||||
|
||||
func set_dragon_name(dragon_name: String):
|
||||
dragon.set_dragon_name(dragon_name)
|
||||
|
|
|
@ -5,11 +5,6 @@ class_name DragonSprite
|
|||
@export var hat: Sprite2D
|
||||
@export var shirt: Sprite2D
|
||||
@export var shoes: Sprite2D
|
||||
@export var name_label: Label
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
name_label.hide()
|
||||
|
||||
|
||||
func dress(hat: Texture2D, shirt: Texture2D, shoes: Texture2D):
|
||||
|
@ -18,13 +13,9 @@ func dress(hat: Texture2D, shirt: Texture2D, shoes: Texture2D):
|
|||
self.shoes.texture = shoes
|
||||
|
||||
|
||||
func set_dragon_name(dragon_name: String):
|
||||
name_label.text = dragon_name
|
||||
func walk_left():
|
||||
$Sprite.scale.x = 1
|
||||
|
||||
|
||||
func _on_area_2d_mouse_entered() -> void:
|
||||
name_label.show()
|
||||
|
||||
|
||||
func _on_area_2d_mouse_exited() -> void:
|
||||
name_label.hide()
|
||||
func walk_right():
|
||||
$Sprite.scale.x = -1
|
||||
|
|
|
@ -9,12 +9,11 @@
|
|||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_oaoux"]
|
||||
size = Vector2(76, 88)
|
||||
|
||||
[node name="Dragon" type="Node2D" node_paths=PackedStringArray("hat", "shirt", "shoes", "name_label")]
|
||||
[node name="Dragon" type="Node2D" node_paths=PackedStringArray("hat", "shirt", "shoes")]
|
||||
script = ExtResource("1_oaoux")
|
||||
hat = NodePath("Sprite/Hat")
|
||||
shirt = NodePath("Sprite/Shirt")
|
||||
shoes = NodePath("Sprite/Shoes")
|
||||
name_label = NodePath("Label")
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
|
||||
|
@ -35,16 +34,5 @@ texture = ExtResource("4_oaoux")
|
|||
[node name="Shoes" type="Sprite2D" parent="Sprite"]
|
||||
texture = ExtResource("5_stf6f")
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
offset_left = -10.0
|
||||
offset_top = 78.0
|
||||
offset_right = 86.0
|
||||
offset_bottom = 101.0
|
||||
theme_override_colors/font_color = Color(1, 1, 1, 1)
|
||||
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
|
||||
theme_override_constants/outline_size = 5
|
||||
text = "AAAAAAAA"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[connection signal="mouse_entered" from="Area2D" to="." method="_on_area_2d_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="Area2D" to="." method="_on_area_2d_mouse_exited"]
|
||||
|
|
|
@ -101,14 +101,13 @@ func _load_game():
|
|||
var hat: Texture2D = hat_outfits.get_texture(d['hat'])
|
||||
var shirt: Texture2D = shirt_outfits.get_texture(d['shirt'])
|
||||
var shoes: Texture2D = shoes_outfits.get_texture(d['shoes'])
|
||||
_pick_dragon(d['id'], d['pos'], hat, shirt, shoes, d['name'], false)
|
||||
_pick_dragon(d['id'], d['pos'], hat, shirt, shoes, false)
|
||||
print(_save_load.contents_to_save)
|
||||
|
||||
|
||||
func _instantiate_dragon_ingame(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, id: int) -> DragonEntity:
|
||||
var dragon: DragonEntity = dragon_ingame.instantiate()
|
||||
dragon.dress(hat, shirt, shoes)
|
||||
dragon.set_dragon_name(dragon_name)
|
||||
add_child(dragon)
|
||||
dragon.id = id
|
||||
dragon.position = position
|
||||
|
@ -118,8 +117,8 @@ func _instantiate_dragon_ingame(position: Vector2, hat: Texture2D, shirt: Textur
|
|||
return dragon
|
||||
|
||||
|
||||
func _pick_dragon(id: int, position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, drag: bool = true):
|
||||
var dragon: Dragon = _instantiator.instantiate(position, hat, shirt, shoes, dragon_name, drag)
|
||||
func _pick_dragon(id: int, position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, drag: bool = true):
|
||||
var dragon: Dragon = _instantiator.instantiate(position, hat, shirt, shoes, drag)
|
||||
dragon.id = id
|
||||
_dragon_entities[id] = dragon
|
||||
dragon.place_back.connect(_dragon_place_back)
|
||||
|
|
|
@ -9,6 +9,9 @@ var dragging_start_position: Vector2i = Vector2i()
|
|||
|
||||
var _initial_drag_requested: bool = false
|
||||
|
||||
signal on_drag()
|
||||
signal on_drop()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
set_process_input(true)
|
||||
|
@ -33,9 +36,11 @@ func _input(event) -> void:
|
|||
|
||||
if event.pressed:
|
||||
dragging = true
|
||||
on_drag.emit()
|
||||
dragging_start_position = Vector2i(get_global_mouse_position())
|
||||
else:
|
||||
dragging = false
|
||||
on_drop.emit()
|
||||
if _is_inside_main_window():
|
||||
_destroy_dragon()
|
||||
|
||||
|
|
|
@ -1,23 +1,43 @@
|
|||
extends Window
|
||||
class_name Dragon
|
||||
|
||||
@export var dragon_speed: float = 20.0
|
||||
@export var dragon_speed_min: float = 20.0
|
||||
@export var dragon_speed_max: float = 20.0
|
||||
var dragon_speed: float = 0.0
|
||||
@export var dragon: DragonSprite
|
||||
|
||||
@onready var _actual_position: Vector2 = position
|
||||
var main_window_rect: Rect2i
|
||||
@export var draggable: Draggable
|
||||
|
||||
var _walking: bool = false
|
||||
var _thinking_path: bool = false
|
||||
var _target_pos: Vector2
|
||||
var rng: RandomNumberGenerator = RandomNumberGenerator.new()
|
||||
var _fall_speed: float
|
||||
|
||||
signal place_back(dragon: Dragon)
|
||||
|
||||
var id: int
|
||||
|
||||
|
||||
enum State {
|
||||
WALKING_IDLE,
|
||||
WALKING,
|
||||
FLYING,
|
||||
FLYING_IDLE,
|
||||
FALLING,
|
||||
DRAGGING
|
||||
}
|
||||
|
||||
var current_state: State = State.WALKING_IDLE
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
draggable.on_drag.connect(_on_drag)
|
||||
draggable.on_drop.connect(_on_drop)
|
||||
current_state = State.FALLING
|
||||
|
||||
|
||||
func on_place_back() -> void:
|
||||
place_back.emit(self)
|
||||
|
||||
|
@ -26,50 +46,135 @@ func start_dragon_drag()-> void:
|
|||
draggable.queue_initial_drag()
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if draggable.dragging:
|
||||
_actual_position = position
|
||||
_walking = false
|
||||
return
|
||||
|
||||
if not _walking:
|
||||
if not _thinking_path:
|
||||
_thinking_path = true
|
||||
await get_tree().create_timer(rng.randf_range(2, 7)).timeout
|
||||
_pick_random_screen_position()
|
||||
return
|
||||
|
||||
_move_to_target(delta)
|
||||
match current_state:
|
||||
State.DRAGGING:
|
||||
_thinking_path = false
|
||||
_actual_position = position
|
||||
State.WALKING_IDLE:
|
||||
if not _thinking_path:
|
||||
_think_path()
|
||||
State.FLYING_IDLE:
|
||||
if not _thinking_path:
|
||||
_think_path()
|
||||
State.WALKING:
|
||||
_move_to_target(delta)
|
||||
State.FALLING:
|
||||
_fall(delta)
|
||||
State.FLYING:
|
||||
_move_to_target(delta)
|
||||
|
||||
|
||||
func dress(hat: Texture2D, shirt: Texture2D, shoes: Texture2D):
|
||||
dragon.dress(hat, shirt, shoes)
|
||||
|
||||
|
||||
func set_dragon_name(dragon_name: String):
|
||||
dragon.set_dragon_name(dragon_name)
|
||||
func _think_path():
|
||||
_thinking_path = true
|
||||
await get_tree().create_timer(rng.randf_range(2, 7)).timeout
|
||||
dragon_speed = rng.randf_range(dragon_speed_min, dragon_speed_max)
|
||||
|
||||
match current_state:
|
||||
State.WALKING_IDLE:
|
||||
var decision: int = rng.randi_range(0, 99)
|
||||
if decision < 30:
|
||||
_pick_random_screen_fly_position()
|
||||
else:
|
||||
_pick_random_screen_walk_position()
|
||||
State.FLYING_IDLE:
|
||||
var decision: int = rng.randi_range(0, 99)
|
||||
if decision < 30:
|
||||
_fall_speed = 0
|
||||
current_state = State.FALLING
|
||||
else:
|
||||
_pick_random_screen_fly_position()
|
||||
|
||||
|
||||
func _fall(delta: float) -> void:
|
||||
_fall_speed += 30 * delta
|
||||
_actual_position.y += _fall_speed
|
||||
position.y = _actual_position.y
|
||||
|
||||
var ground_height: int = _ground_height()
|
||||
if position.y >= ground_height:
|
||||
current_state = State.WALKING_IDLE
|
||||
position.y = ground_height
|
||||
_actual_position.y = ground_height
|
||||
|
||||
|
||||
func _move_to_target(delta: float):
|
||||
if _actual_position.distance_to(_target_pos) > 10.0:
|
||||
if _actual_position.distance_to(_target_pos) > 2.0:
|
||||
var direction: Vector2 = (_target_pos - _actual_position).normalized()
|
||||
_actual_position += dragon_speed * direction * delta
|
||||
position = _actual_position
|
||||
|
||||
if direction.x > 0:
|
||||
dragon.walk_right()
|
||||
elif direction.x < 0:
|
||||
dragon.walk_left()
|
||||
return
|
||||
|
||||
_walking = false
|
||||
match current_state:
|
||||
State.FLYING:
|
||||
current_state = State.FLYING_IDLE
|
||||
State.WALKING:
|
||||
current_state = State.WALKING_IDLE
|
||||
|
||||
|
||||
func _pick_random_screen_position() -> void:
|
||||
_walking = true
|
||||
_thinking_path = false
|
||||
func _on_drag():
|
||||
current_state = State.DRAGGING
|
||||
|
||||
|
||||
func _on_drop():
|
||||
var ground_height: int = _ground_height()
|
||||
if position.y >= ground_height:
|
||||
current_state = State.WALKING_IDLE
|
||||
position.y = ground_height
|
||||
_actual_position.y = ground_height
|
||||
else:
|
||||
_fall_speed = 0
|
||||
current_state = State.FALLING
|
||||
|
||||
|
||||
func _get_display_limits() -> Rect2i:
|
||||
var display_index: int = DisplayServer.window_get_current_screen()
|
||||
var work_area_position: Vector2i = DisplayServer.screen_get_usable_rect(display_index).position
|
||||
var work_area_size: Vector2i = DisplayServer.screen_get_usable_rect(display_index).size
|
||||
|
||||
return Rect2i(work_area_position + Vector2i(10, 10), work_area_size - Vector2i(20, 10) - size)
|
||||
|
||||
|
||||
func _ground_height() -> int:
|
||||
var limits: Rect2i = _get_display_limits()
|
||||
return limits.end.y
|
||||
|
||||
|
||||
func _pick_random_screen_fly_position() -> void:
|
||||
current_state = State.FLYING
|
||||
_thinking_path = false
|
||||
|
||||
var limits: Rect2i = _get_display_limits()
|
||||
|
||||
var random_pos: Vector2i = Vector2i(
|
||||
work_area_position.x + rng.randi_range(10, work_area_size.x - 10 - size.x),
|
||||
work_area_position.y + rng.randi_range(10, work_area_size.y - 10 - size.y)
|
||||
rng.randi_range(limits.position.x, limits.end.x),
|
||||
rng.randi_range(limits.position.y, limits.end.y)
|
||||
)
|
||||
|
||||
_target_pos = random_pos
|
||||
|
||||
|
||||
func _pick_random_screen_walk_position() -> void:
|
||||
current_state = State.WALKING
|
||||
_thinking_path = false
|
||||
|
||||
var limits: Rect2i = _get_display_limits()
|
||||
|
||||
var random_pos: Vector2i = Vector2i(
|
||||
rng.randi_range(limits.position.x, limits.end.x),
|
||||
_ground_height()
|
||||
)
|
||||
|
||||
_target_pos = random_pos
|
||||
|
||||
|
||||
func get_taskbar_height():
|
||||
return DisplayServer.screen_get_size().y - DisplayServer.screen_get_usable_rect().size.y
|
||||
|
|
|
@ -13,7 +13,8 @@ borderless = true
|
|||
transparent = true
|
||||
content_scale_mode = 2
|
||||
script = ExtResource("1_ctdir")
|
||||
dragon_speed = 100.0
|
||||
dragon_speed_min = 50.0
|
||||
dragon_speed_max = 120.0
|
||||
dragon = NodePath("Dragon")
|
||||
draggable = NodePath("DragDropDetector")
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ func _init(dragon: PackedScene, viewport: Viewport, window: Window) -> void:
|
|||
_dragon_template = dragon
|
||||
|
||||
|
||||
func instantiate(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, drag: bool) -> Node:
|
||||
func instantiate(position: Vector2, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, drag: bool) -> Node:
|
||||
if drag == false:
|
||||
return _instantiate_dragon(position, hat, shirt, shoes, dragon_name, drag)
|
||||
return _instantiate_dragon(position, hat, shirt, shoes, drag)
|
||||
var relative_position: Vector2i = _calculate_relative_position(position)
|
||||
return _instantiate_dragon(relative_position, hat, shirt, shoes, dragon_name, drag)
|
||||
return _instantiate_dragon(relative_position, hat, shirt, shoes, drag)
|
||||
|
||||
|
||||
func _calculate_window_scale() -> Vector2:
|
||||
|
@ -29,7 +29,7 @@ func _calculate_relative_position(position: Vector2) -> Vector2i:
|
|||
return Vector2i(Vector2(position) * scale)
|
||||
|
||||
|
||||
func _instantiate_dragon(relative_position: Vector2i, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, dragon_name: String, drag: bool) -> Node:
|
||||
func _instantiate_dragon(relative_position: Vector2i, hat: Texture2D, shirt: Texture2D, shoes: Texture2D, drag: bool) -> Node:
|
||||
var dragon: Dragon = _dragon_template.instantiate()
|
||||
|
||||
var window_position: Vector2i = DisplayServer.window_get_position()
|
||||
|
@ -40,7 +40,6 @@ func _instantiate_dragon(relative_position: Vector2i, hat: Texture2D, shirt: Tex
|
|||
else:
|
||||
dragon.position = window_position + relative_position - dragon.size / 2
|
||||
dragon.dress(hat, shirt, shoes)
|
||||
dragon.set_dragon_name(dragon_name)
|
||||
|
||||
var size: float = _calculate_window_scale().y
|
||||
dragon.main_window_rect = Rect2i(window_position, window_size)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue