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)