Last active
February 15, 2025 03:47
-
-
Save Decapitated/735dfc30e9c7139919e2b5c792e1a71b to your computer and use it in GitHub Desktop.
A simple 2D curtain class.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @tool | |
| class_name Curtains extends Node2D | |
| @export_range(0.0, 100.0, 0.1,) var curtain_lerp: float = 50.0 | |
| @export_group("Rail", "rail_") | |
| @export var rail_texture: Texture2D = null | |
| @export_range(0.0, 500.0, 0.1, "or_greater") var rail_width: float = 500.0 | |
| @export_range(-1.0, 100.0, 0.1, "or_greater") var rail_thickness: float = 25.0 | |
| @export_range(0.0, 100.0, 0.1) var rail_max_width: float = 100.0 | |
| @export_range(0.0, 100.0, 0.1, "or_greater") var rail_end_padding: float = 0.0 | |
| @export_group("Curtains", "curtain_") | |
| @export_tool_button("Perfect Width") var curtain_tb_perfect_width: Callable = func(): curtain_width = get_perfect_width() | |
| @export var curtain_texture: Texture2D = null | |
| @export var curtain_use_texture_size: bool = true | |
| @export_range(2, 5, 1, "or_greater") var curtain_count: int = 5 | |
| @export_range(0.0, 500.0, 0.1, "or_greater") var curtain_width: float = 100.0 | |
| @export_range(0.0, 500.0, 0.1, "or_greater") var curtain_length: float = 500.0 | |
| @export_group("Debug", "debug_") | |
| @export var debug_draw_rail: bool = false | |
| @export var debug_draw_curtain_position: bool = false | |
| @export var debug_draw_curtains: bool = false | |
| func _process(_delta: float) -> void: | |
| queue_redraw() | |
| func _draw() -> void: | |
| var rail_rect := Rect2( | |
| Vector2(-rail_width / 2.0, -rail_thickness / 2.0), | |
| Vector2(rail_width, rail_thickness)) | |
| if rail_texture: | |
| draw_texture_rect(rail_texture, rail_rect, false) | |
| if debug_draw_rail: | |
| draw_rect(rail_rect, Color.BLACK) | |
| draw_rect(rail_rect, Color.GREEN, false, 2.0) | |
| var current_lerp_position := get_lerp_position(curtain_lerp / 100.0) | |
| var real_lerp_positions := get_real_lerps(current_lerp_position) | |
| for i in curtain_count: | |
| var lerp_i: float = i / float(curtain_count - 1) | |
| var curtain_position = real_lerp_positions[0].lerp(real_lerp_positions[1], lerp_i) | |
| var curtain_rect := Rect2( | |
| Vector2(-curtain_width / 2.0, 0.0) + curtain_position, | |
| Vector2(curtain_width, curtain_length)) | |
| if curtain_texture: | |
| if curtain_use_texture_size: | |
| var texture_size := curtain_texture.get_size() | |
| curtain_rect = Rect2( | |
| Vector2(-texture_size.x / 2.0, 0.0) + curtain_position, | |
| texture_size | |
| ) | |
| draw_texture_rect(curtain_texture, curtain_rect, false) | |
| if debug_draw_curtains: | |
| draw_rect(curtain_rect, Color.BROWN) | |
| draw_rect(curtain_rect, Color.WHITE, false, 2.0) | |
| if debug_draw_curtain_position: | |
| draw_circle(real_lerp_positions[0], rail_thickness / 2.0, Color.BLUE) | |
| draw_circle(real_lerp_positions[0], rail_thickness / 2.0, Color.SKY_BLUE, false, 2.0) | |
| draw_circle(real_lerp_positions[1], rail_thickness / 2.0, Color.BLUE) | |
| draw_circle(real_lerp_positions[1], rail_thickness / 2.0, Color.SKY_BLUE, false, 2.0) | |
| draw_circle(current_lerp_position, rail_thickness / 2.0, Color.RED) | |
| draw_circle(current_lerp_position, rail_thickness / 2.0, Color.WHITE, false, 2.0) | |
| func get_lerp_position(p_lerp: float) -> Vector2: | |
| var right := get_right() | |
| return (-right).lerp(right, p_lerp) | |
| func get_real_lerps(current_lerp_position: Vector2) -> Array[Vector2]: | |
| var right := get_right() | |
| var right_vec := right - current_lerp_position | |
| var max_length := right_vec.length() | |
| if max_length > right.x: | |
| max_length = (rail_width - rail_end_padding * 2.0) - max_length | |
| max_length = min(get_usable_width() / 2.0, max_length) | |
| return [ | |
| current_lerp_position + (-right).normalized() * max_length, | |
| current_lerp_position + right.normalized() * max_length | |
| ] | |
| func get_right() -> Vector2: | |
| return Vector2(rail_width / 2.0 - rail_end_padding, 0.0) | |
| func get_usable_width() -> float: | |
| return rail_width * (rail_max_width / 100.0) | |
| func get_perfect_width() -> float: | |
| return rail_width / curtain_count * (1.0 + 1.0 / maxi(1, curtain_count - 1)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment