Shape cast
Una caja que pregunta dónde se detendría antes de moverse. El fantasma es la fracción segura que devuelve el cast.
El editor de arriba está ejecutando este proyecto. Cambia una línea y se recarga.
Clases de Godot usadas
ShapeCast2DPolygon2DStaticBody2D
El código
scripts/main.gd
extends Node
const PROBE_SIZE: Vector2 = Vector2(70, 70)
const REACH: float = 420.0
var probe: Polygon2D
var ghost: Polygon2D
var cast: ShapeCast2D
var path: Line2D
var origin: Vector2
func _ready() -> void:
_add_background()
var view: Vector2 = get_viewport().get_visible_rect().size
origin = Vector2(view.x * 0.2, view.y * 0.5)
for at in [Vector2(view.x * 0.6, view.y * 0.35), Vector2(view.x * 0.75, view.y * 0.7)]:
_add_wall(at, Vector2(50, 260))
var shape: RectangleShape2D = RectangleShape2D.new()
shape.size = PROBE_SIZE
cast = ShapeCast2D.new()
cast.shape = shape
cast.position = origin
add_child(cast)
path = Line2D.new()
path.width = 2.0
path.default_color = Color(0.55, 0.65, 0.95, 0.3)
add_child(path)
ghost = _make_rect(PROBE_SIZE, Color(0.98, 0.5, 0.5, 0.35))
add_child(ghost)
probe = _make_rect(PROBE_SIZE, Color('#8da5f3'))
probe.position = origin
add_child(probe)
print('the ghost is where the box would stop, computed before moving')
func _physics_process(_delta: float) -> void:
var target: Vector2 = get_viewport().get_mouse_position()
var to: Vector2 = (target - origin).limit_length(REACH)
cast.target_position = to
cast.force_shapecast_update()
var fraction: float = cast.get_closest_collision_safe_fraction() if cast.is_colliding() else 1.0
ghost.position = origin + to * fraction
ghost.color = Color(0.98, 0.5, 0.5, 0.35) if cast.is_colliding() else Color(0.55, 0.94, 0.6, 0.25)
path.points = PackedVector2Array([origin, origin + to])
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 wall: StaticBody2D = StaticBody2D.new()
wall.position = center
wall.add_child(_make_rect(size, Color('#2a2f3d')))
wall.add_child(collision)
add_child(wall)
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 _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)