class_name WeatherIcon extends Control ## Значок погоды для HUD. ## ## Рисуется процедурно: иконок в наборе фона нет, а тащить шрифт с символами ## ради семи состояний неоправданно. Заодно значок красится темой, а не ## растром, и одинаково чёткий на любом масштабе. const SUN := Color("#f2b134") const MOON := Color("#cfd8e6") const CLOUD := Color("#c6d4e0") const CLOUD_DARK := Color("#8fa5ba") const RAIN := Color("#4aa8f2") const SNOW := Color("#e6f1f7") const BOLT := Color("#f2b134") ## Тип погоды из WeatherSystem.Kind. var kind := 0 ## Ночью в ясную погоду вместо солнца показываем луну. var night := false func _ready() -> void: custom_minimum_size = Vector2(24.0, 24.0) func set_state(weather_kind: int, is_night: bool) -> void: if weather_kind == kind and is_night == night: return kind = weather_kind night = is_night queue_redraw() func _draw() -> void: var box := Rect2(Vector2.ZERO, size) var center := box.get_center() match kind: WeatherSystem.Kind.CLEAR: _draw_body(center, size.x * 0.30) WeatherSystem.Kind.CLOUDY: _draw_body(center - Vector2(size.x * 0.14, size.y * 0.14), size.x * 0.22) _draw_cloud(center + Vector2(size.x * 0.06, size.y * 0.10), CLOUD) WeatherSystem.Kind.OVERCAST: _draw_cloud(center - Vector2(size.x * 0.10, size.y * 0.06), CLOUD_DARK) _draw_cloud(center + Vector2(size.x * 0.08, size.y * 0.08), CLOUD) WeatherSystem.Kind.RAIN: _draw_cloud(center - Vector2(0.0, size.y * 0.14), CLOUD) _draw_streaks(center, RAIN) WeatherSystem.Kind.STORM: _draw_cloud(center - Vector2(0.0, size.y * 0.14), CLOUD_DARK) _draw_streaks(center, RAIN) _draw_bolt(center) WeatherSystem.Kind.FOG: _draw_fog(box) WeatherSystem.Kind.SNOW: _draw_cloud(center - Vector2(0.0, size.y * 0.14), CLOUD) _draw_flakes(center) ## Солнце или луна — смотря какое время суток. func _draw_body(center: Vector2, radius: float) -> void: if night: # Полумесяц: круг с вырезом, вырез закрашен фоном значка. draw_circle(center, radius, MOON) draw_circle(center + Vector2(radius * 0.55, -radius * 0.30), radius * 0.92, Color(0, 0, 0, 0)) draw_arc(center, radius, PI * 0.35, PI * 1.65, 20, MOON, 2.0) return draw_circle(center, radius, SUN) for index in 8: var angle := TAU * float(index) / 8.0 var direction := Vector2(cos(angle), sin(angle)) draw_line(center + direction * (radius * 1.35), center + direction * (radius * 1.85), SUN, 1.6) func _draw_cloud(center: Vector2, tint: Color) -> void: var unit := size.x * 0.12 draw_circle(center + Vector2(-unit * 1.1, 0.0), unit * 1.05, tint) draw_circle(center + Vector2(unit * 1.1, unit * 0.15), unit * 0.9, tint) draw_circle(center + Vector2(0.0, -unit * 0.55), unit * 1.25, tint) draw_rect(Rect2(center + Vector2(-unit * 1.9, -unit * 0.1), Vector2(unit * 3.8, unit * 1.1)), tint) func _draw_streaks(center: Vector2, tint: Color) -> void: var unit := size.x * 0.12 for index in 3: var start := center + Vector2((float(index) - 1.0) * unit * 1.4, unit * 1.3) draw_line(start, start + Vector2(-unit * 0.35, unit * 1.3), tint, 1.8) func _draw_flakes(center: Vector2) -> void: var unit := size.x * 0.12 for index in 3: draw_circle(center + Vector2((float(index) - 1.0) * unit * 1.4, unit * 1.9), unit * 0.32, SNOW) func _draw_bolt(center: Vector2) -> void: var unit := size.x * 0.12 draw_polygon( PackedVector2Array([ center + Vector2(unit * 0.2, unit * 1.1), center + Vector2(unit * 1.2, unit * 1.1), center + Vector2(unit * 0.4, unit * 2.6), center + Vector2(unit * 0.7, unit * 1.7), center + Vector2(-unit * 0.2, unit * 1.7), ]), PackedColorArray([BOLT, BOLT, BOLT, BOLT, BOLT]) ) func _draw_fog(box: Rect2) -> void: for index in 3: var y := box.position.y + box.size.y * (0.32 + float(index) * 0.18) var inset := box.size.x * (0.08 + float(index % 2) * 0.12) draw_line( Vector2(box.position.x + inset, y), Vector2(box.end.x - inset, y), CLOUD_DARK, 2.0 )