Détecteur de zone

Une zone qui compte ce qui la traverse, à l'aide des signaux body_entered et body_exited.

L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.

Classes Godot utilisées

Area2DRigidBody2DLabel

Le code

scripts/main.gd
extends Node

const ZONE_SIZE: Vector2 = Vector2(320, 220)
const BALL_RADIUS: float = 26.0
const IDLE_COLOR: Color = Color(0.55, 0.65, 0.95, 0.15)
const BUSY_COLOR: Color = Color(0.55, 0.94, 0.6, 0.35)

var zone_visual: Polygon2D
var counter: Label
var inside: int = 0


func _ready() -> void:
	_add_background()

	var view: Vector2 = get_viewport().get_visible_rect().size
	var center: Vector2 = Vector2(view.x * 0.5, view.y * 0.62)

	var shape: RectangleShape2D = RectangleShape2D.new()
	shape.size = ZONE_SIZE

	var collision: CollisionShape2D = CollisionShape2D.new()
	collision.shape = shape

	zone_visual = _make_rect(ZONE_SIZE, IDLE_COLOR)

	var zone: Area2D = Area2D.new()
	zone.position = center
	zone.add_child(zone_visual)
	zone.add_child(collision)
	add_child(zone)

	zone.body_entered.connect(_on_entered)
	zone.body_exited.connect(_on_exited)

	counter = Label.new()
	counter.position = center + Vector2(-ZONE_SIZE.x * 0.5, -ZONE_SIZE.y * 0.5 - 30)
	add_child(counter)
	_update_label()

	_spawn_loop(view)


func _spawn_loop(view: Vector2) -> void:
	while is_inside_tree():
		_add_ball(Vector2(randf_range(view.x * 0.3, view.x * 0.7), -40))
		await get_tree().create_timer(0.7).timeout


func _on_entered(_body: Node) -> void:
	inside += 1
	zone_visual.color = BUSY_COLOR
	_update_label()


func _on_exited(_body: Node) -> void:
	inside = max(inside - 1, 0)

	if inside <= 0:
		zone_visual.color = IDLE_COLOR

	_update_label()


func _update_label() -> void:
	counter.text = 'bodies inside: %d' % inside


func _add_ball(at: Vector2) -> void:
	var circle: CircleShape2D = CircleShape2D.new()
	circle.radius = BALL_RADIUS

	var collision: CollisionShape2D = CollisionShape2D.new()
	collision.shape = circle

	var ball: RigidBody2D = RigidBody2D.new()
	ball.position = at
	ball.add_child(_make_circle(BALL_RADIUS, Color('#fc7f7f')))
	ball.add_child(collision)
	add_child(ball)

	await get_tree().create_timer(6.0).timeout

	if is_instance_valid(ball):
		ball.queue_free()


func _make_rect(size: Vector2, color: Color) -> Polygon2D:
	var rect: Polygon2D = Polygon2D.new()
	rect.polygon = PackedVector2Array([-size * 0.5, Vector2(size.x, -size.y) * 0.5, size * 0.5, Vector2(-size.x, size.y) * 0.5])
	rect.color = color

	return rect


func _make_circle(radius: float, color: Color) -> Polygon2D:
	var points: PackedVector2Array = PackedVector2Array()

	for i in 20:
		points.append(Vector2(cos(TAU * i / 20.0), sin(TAU * i / 20.0)) * radius)

	var circle: Polygon2D = Polygon2D.new()
	circle.polygon = points
	circle.color = color

	return circle


func _add_background() -> void:
	var background: ColorRect = ColorRect.new()
	background.color = Color('#12141a')
	add_child(background)
	background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)

Plus d'exemples de Physique