1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
class_name MapArea
extends Area2D
signal transitioned_to
@export var can_plant_bomb: bool = true
@export_node_path("TileMap") var _tilemap: NodePath
var tilemap: TileMap
func _ready():
if not _tilemap:
tilemap = $TileMap
else:
tilemap = get_node(_tilemap)
add_area_edges()
func add_area_edges():
var area_edges = StaticBody2D.new()
area_edges.set_collision_layer_value(Utilities.Collision.Layer.SOLID, true)
area_edges.add_collision_exception_with(Global.player)
var bounds = Utilities.get_collision_shape_bounds($CollisionShape2D)
var edges = [
{ "a": bounds.position, "b": Vector2(bounds.end.x, bounds.position.y) },
{ "a": bounds.position, "b": Vector2(bounds.position.x, bounds.end.y) },
{ "a": bounds.end, "b": Vector2(bounds.end.x, bounds.position.y) },
{ "a": bounds.end, "b": Vector2(bounds.position.x, bounds.end.y) },
]
for edge in edges:
var collision_shape = CollisionShape2D.new()
var shape = SegmentShape2D.new()
shape.a = edge.a
shape.b = edge.b
collision_shape.shape = shape
area_edges.add_child(collision_shape)
add_child(area_edges)
func _on_body_entered(body):
if body is Player:
self._on_player_entered(body)
func _on_player_entered(player: Player):
var exited_area = Global.last_area
if Global.last_area == self:
return
if exited_area:
player.process_mode = Node.PROCESS_MODE_ALWAYS
exited_area.set_collision_mask_value(Utilities.Collision.Layer.PLAYER, false)
else:
tilemap.process_mode = Node.PROCESS_MODE_INHERIT
self.set_collision_mask_value(Utilities.Collision.Layer.PLAYER, false)
tilemap.visible = true
self.adjust_camera_to_area(player)
if not player.get_parent() == tilemap:
(func(): player.reparent(tilemap)).call_deferred()
var position_tween: Tween
if exited_area:
tilemap.process_mode = Node.PROCESS_MODE_DISABLED
exited_area.tilemap.process_mode = Node.PROCESS_MODE_DISABLED
# animate sprite
var sprite: AnimatedSprite2D = player.get_node("AnimatedSprite2D")
var bounds: Rect2 = Utilities.get_collision_shape_bounds($CollisionShape2D)
var sprite_direction = ""
var direction = Vector2.UP
if player.global_position.x <= bounds.position.x:
sprite_direction = "right"
direction = Vector2.RIGHT
elif player.global_position.x >= bounds.end.x:
sprite_direction = "left"
direction = Vector2.LEFT
elif player.global_position.y <= bounds.position.y:
sprite_direction = "down"
direction = Vector2.DOWN
elif player.global_position.y >= bounds.end.y:
sprite_direction = "up"
direction = Vector2.UP
var sprite_tween = get_tree().create_tween().set_loops(5)
sprite_tween.tween_interval(0.25)
sprite_tween.tween_callback(func():
sprite.play(sprite_direction)
)
player.set_process(false)
position_tween = get_tree().create_tween()
position_tween.tween_property(
player, "global_position", player.global_position + direction * (16 + 8), 1.25
)
position_tween.tween_callback(func():
tilemap.process_mode = Node.PROCESS_MODE_INHERIT
player.process_mode = Node.PROCESS_MODE_INHERIT
player.set_process(true)
exited_area.tilemap.visible = false
sprite_tween.kill()
sprite.play("idle_" + sprite_direction)
exited_area.set_collision_mask_value(Utilities.Collision.Layer.PLAYER, true)
transitioned_to.emit()
)
Global.last_area = self
func adjust_camera_to_area(player: Player) -> Camera2D:
var camera: Camera2D = player.get_node("Camera2D")
var bounds: Rect2 = Utilities.get_collision_shape_bounds($CollisionShape2D)
var duration = 0
if Global.last_area:
duration = 1.25
var tween = get_tree().create_tween().set_parallel().set_ease(Tween.EASE_OUT)
tween.tween_property(camera, "limit_top", bounds.position.y, duration)
tween.tween_property(camera, "limit_right", bounds.end.x, duration)
tween.tween_property(camera, "limit_bottom", bounds.end.y, duration)
tween.tween_property(camera, "limit_left", bounds.position.x, duration)
return camera
|