Cono de visión

Veintiocho rayos abiertos en abanico hacia el ratón. Cada uno se pone rojo donde choca con un muro, que es línea de visión en su forma más simple.

El editor de arriba está ejecutando este proyecto. Cambia una línea y se recarga.

Clases de Godot usadas

RayCast2DLine2DStaticBody2D

El código

scripts/main.gd
extends Node

const RAYS: int = 28
const SPREAD: float = 1.0
const LENGTH: float = 560.0
const CLEAR_COLOR: Color = Color(0.55, 0.65, 0.95, 0.35)
const HIT_COLOR: Color = Color(0.98, 0.5, 0.5, 0.9)

var origin: Vector2
var rays: Array[RayCast2D] = []
var lines: Array[Line2D] = []


func _ready() -> void:
	_add_background()

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

	for at in [Vector2(view.x * 0.25, view.y * 0.4), Vector2(view.x * 0.6, view.y * 0.3), Vector2(view.x * 0.78, view.y * 0.55)]:
		_add_wall(at, Vector2(160, 40))

	for i in RAYS:
		var ray: RayCast2D = RayCast2D.new()
		ray.position = origin
		add_child(ray)
		rays.append(ray)

		var line: Line2D = Line2D.new()
		line.width = 2.0
		add_child(line)
		lines.append(line)

	add_child(_make_circle(origin, 16.0, Color('#8eef97')))

	print('the cone follows the mouse, a ray turns red where it hits a wall')


func _process(_delta: float) -> void:
	var aim: float = (get_viewport().get_mouse_position() - origin).angle()

	for i in RAYS:
		var angle: float = aim + (float(i) / (RAYS - 1) - 0.5) * SPREAD
		var direction: Vector2 = Vector2(cos(angle), sin(angle))

		rays[i].target_position = direction * LENGTH
		rays[i].force_raycast_update()

		var hit: bool = rays[i].is_colliding()
		var to: Vector2 = rays[i].get_collision_point() if hit else origin + direction * LENGTH

		lines[i].points = PackedVector2Array([origin, to])
		lines[i].default_color = HIT_COLOR if hit else CLEAR_COLOR


func _add_wall(center: Vector2, size: Vector2) -> void:
	var shape: RectangleShape2D = RectangleShape2D.new()
	shape.size = size

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

	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('#2a2f3d')

	var wall: StaticBody2D = StaticBody2D.new()
	wall.position = center
	wall.add_child(rect)
	wall.add_child(collision)
	add_child(wall)


func _make_circle(at: Vector2, 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
	circle.position = at

	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)

Más ejemplos de Física