mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-04 15:00:09 +01:00
Add a custom drawing in 2D demo (#1185)
This commit is contained in:
23
2d/custom_drawing/README.md
Normal file
23
2d/custom_drawing/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Custom drawing in 2D
|
||||
|
||||
A demo showing how to draw 2D elements in Godot without using nodes. This can be done
|
||||
to create procedural graphics, perform debug drawing to help troubleshoot issues in
|
||||
game logic, or to improve performance by not creating a node for every visible element.
|
||||
|
||||
Antialiasing can be performed using two approaches: either by enabling the `antialiasing`
|
||||
parameter provided by some of the CanvasItem `draw_*` methods, or by enabling 2D MSAA
|
||||
in the Project Settings. 2D MSAA is generally slower, but it works with any kind of line-based
|
||||
or polygon-based 2D drawing, even for `draw_*` methods that don't support an `antialiasing`
|
||||
parameter. Note that 2D MSAA is only available in the Forward+ and Mobile
|
||||
renderers, not Compatibility.
|
||||
|
||||
See [Custom drawing in 2D](https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html)
|
||||
in the documentation for more information.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Mobile
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
43
2d/custom_drawing/animation.gd
Normal file
43
2d/custom_drawing/animation.gd
Normal file
@@ -0,0 +1,43 @@
|
||||
# This is a `@tool` script so that the custom 2D drawing can be seen in the editor.
|
||||
@tool
|
||||
extends Panel
|
||||
|
||||
var use_antialiasing := false
|
||||
|
||||
var time := 0.0
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
# Increment a counter variable that we use in `_draw()`.
|
||||
time += delta
|
||||
# Force redrawing on every processed frame, so that the animation can visibly progress.
|
||||
# Only do this when the node is visible in tree, so that we don't force continuous redrawing
|
||||
# when not needed (low-processor usage mode is enabled in this demo).
|
||||
if is_visible_in_tree():
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var margin := Vector2(240, 70)
|
||||
var offset := Vector2()
|
||||
|
||||
# Line width of `-1.0` is only usable with draw antialiasing disabled,
|
||||
# as it uses hardware line drawing as opposed to polygon-based line drawing.
|
||||
# Automatically use polygon-based line drawing when needed to avoid runtime warnings.
|
||||
# We also use a line width of `0.5` instead of `1.0` to better match the appearance
|
||||
# of non-antialiased line drawing, as draw antialiasing tends to make lines look thicker.
|
||||
var line_width_thin := 0.5 if use_antialiasing else -1.0
|
||||
|
||||
# Draw an animated arc to simulate a circular progress bar.
|
||||
# The start angle is set so the arc starts from the top.
|
||||
const POINT_COUNT = 48
|
||||
var progress := wrapf(time, 0.0, 1.0)
|
||||
draw_arc(
|
||||
margin + offset,
|
||||
50.0,
|
||||
0.75 * TAU,
|
||||
(0.75 + progress) * TAU,
|
||||
POINT_COUNT,
|
||||
Color.MEDIUM_AQUAMARINE,
|
||||
line_width_thin,
|
||||
use_antialiasing
|
||||
)
|
||||
1
2d/custom_drawing/animation.gd.uid
Normal file
1
2d/custom_drawing/animation.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b8d4d0s3gujbp
|
||||
36
2d/custom_drawing/animation_slice.gd
Normal file
36
2d/custom_drawing/animation_slice.gd
Normal file
@@ -0,0 +1,36 @@
|
||||
extends Control
|
||||
|
||||
var use_antialiasing := false
|
||||
|
||||
func _draw() -> void:
|
||||
var margin := Vector2(240, 70)
|
||||
var offset := Vector2(0, 150)
|
||||
# This is an example of using draw commands to create animations.
|
||||
# For "continuous" animations, you can use a timer within `_draw()` and call `queue_redraw()`
|
||||
# in `_process()` to redraw every frame.
|
||||
# Animation length in seconds. The animation will loop after the specified duration.
|
||||
const ANIMATION_LENGTH = 2.0
|
||||
# 5 frames per second.
|
||||
const ANIMATION_FRAMES = 10
|
||||
|
||||
# Declare an animation frame with randomized rotation and color for each frame.
|
||||
# `draw_animation_slice()` makes it so the following draw commands are only visible
|
||||
# on screen when the current time is within the animation slice.
|
||||
# NOTE: Pause does not affect animations drawn by `draw_animation_slice()`
|
||||
# (they will keep playing).
|
||||
for frame in ANIMATION_FRAMES:
|
||||
# `remap()` is useful to determine the time slice in which a frame is visible.
|
||||
# For example, on the 2nd frame, `slice_begin` is `0.2` and `slice_end` is `0.4`.
|
||||
var slice_begin := remap(frame, 0, ANIMATION_FRAMES, 0, ANIMATION_LENGTH)
|
||||
var slice_end := remap(frame + 1, 0, ANIMATION_FRAMES, 0, ANIMATION_LENGTH)
|
||||
draw_animation_slice(ANIMATION_LENGTH, slice_begin, slice_end)
|
||||
draw_set_transform(margin + offset, deg_to_rad(randf_range(-5.0, 5.0)))
|
||||
draw_rect(
|
||||
Rect2(Vector2(), Vector2(100, 50)),
|
||||
Color.from_hsv(randf(), 0.4, 1.0),
|
||||
true,
|
||||
-1.0,
|
||||
use_antialiasing
|
||||
)
|
||||
|
||||
draw_end_animation()
|
||||
1
2d/custom_drawing/animation_slice.gd.uid
Normal file
1
2d/custom_drawing/animation_slice.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://wksdrvv65620
|
||||
14
2d/custom_drawing/custom_drawing.gd
Normal file
14
2d/custom_drawing/custom_drawing.gd
Normal file
@@ -0,0 +1,14 @@
|
||||
extends Control
|
||||
|
||||
|
||||
func _on_msaa_2d_item_selected(index: int) -> void:
|
||||
get_viewport().msaa_2d = index as Viewport.MSAA
|
||||
|
||||
|
||||
func _on_draw_antialiasing_toggled(toggled_on: bool) -> void:
|
||||
var nodes: Array[Node] = %TabContainer.get_children()
|
||||
nodes.push_back(%AnimationSlice)
|
||||
for tab: Control in nodes:
|
||||
tab.use_antialiasing = toggled_on
|
||||
# Force all tabs to redraw so that the antialiasing updates.
|
||||
tab.queue_redraw()
|
||||
1
2d/custom_drawing/custom_drawing.gd.uid
Normal file
1
2d/custom_drawing/custom_drawing.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cinaeqsrawkbw
|
||||
272
2d/custom_drawing/custom_drawing.tscn
Normal file
272
2d/custom_drawing/custom_drawing.tscn
Normal file
@@ -0,0 +1,272 @@
|
||||
[gd_scene load_steps=10 format=3 uid="uid://btxwm0qudsn3t"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cinaeqsrawkbw" path="res://custom_drawing.gd" id="1_rtndo"]
|
||||
[ext_resource type="Script" uid="uid://3gt2v4l0gy1" path="res://lines.gd" id="2_exx0l"]
|
||||
[ext_resource type="Script" uid="uid://cquneapbjf3e0" path="res://rectangles.gd" id="3_yrx86"]
|
||||
[ext_resource type="Script" uid="uid://clsf8dubgyrig" path="res://polygons.gd" id="4_obj11"]
|
||||
[ext_resource type="Script" uid="uid://dtxyrnurokare" path="res://textures.gd" id="5_84cac"]
|
||||
[ext_resource type="Script" uid="uid://dy8ofskb8bg4a" path="res://meshes.gd" id="5_exx0l"]
|
||||
[ext_resource type="Script" uid="uid://0kv1wvfyg058" path="res://text.gd" id="6_4w081"]
|
||||
[ext_resource type="Script" uid="uid://b8d4d0s3gujbp" path="res://animation.gd" id="8_yrx86"]
|
||||
[ext_resource type="Script" uid="uid://wksdrvv65620" path="res://animation_slice.gd" id="9_obj11"]
|
||||
|
||||
[node name="CustomDrawing" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_rtndo")
|
||||
|
||||
[node name="TabContainer" type="TabContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
current_tab = 0
|
||||
|
||||
[node name="Lines" type="Panel" parent="TabContainer"]
|
||||
layout_mode = 2
|
||||
script = ExtResource("2_exx0l")
|
||||
metadata/_tab_index = 0
|
||||
|
||||
[node name="DrawLine" type="Label" parent="TabContainer/Lines"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 48.0
|
||||
offset_right = 172.0
|
||||
offset_bottom = 97.0
|
||||
theme_override_colors/font_color = Color(0.501961, 1, 0.501961, 1)
|
||||
text = "draw_line()
|
||||
draw_dashed_line()"
|
||||
|
||||
[node name="DrawCircle" type="Label" parent="TabContainer/Lines"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 154.0
|
||||
offset_right = 122.0
|
||||
offset_bottom = 177.0
|
||||
theme_override_colors/font_color = Color(0.501961, 1, 0.501961, 1)
|
||||
text = "draw_circle()"
|
||||
|
||||
[node name="DrawArc" type="Label" parent="TabContainer/Lines"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 264.0
|
||||
offset_right = 109.0
|
||||
offset_bottom = 287.0
|
||||
theme_override_colors/font_color = Color(0.501961, 1, 0.501961, 1)
|
||||
text = "draw_arc()"
|
||||
|
||||
[node name="Rectangles" type="Panel" parent="TabContainer"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
script = ExtResource("3_yrx86")
|
||||
metadata/_tab_index = 1
|
||||
|
||||
[node name="DrawRect" type="Label" parent="TabContainer/Rectangles"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 48.0
|
||||
offset_right = 109.0
|
||||
offset_bottom = 71.0
|
||||
theme_override_colors/font_color = Color(0.501961, 1, 0.501961, 1)
|
||||
text = "draw_rect()"
|
||||
|
||||
[node name="DrawStyleBox" type="Label" parent="TabContainer/Rectangles"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 296.0
|
||||
offset_right = 153.0
|
||||
offset_bottom = 319.0
|
||||
text = "draw_style_box()"
|
||||
|
||||
[node name="Polygons" type="Panel" parent="TabContainer"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
script = ExtResource("4_obj11")
|
||||
metadata/_tab_index = 2
|
||||
|
||||
[node name="DrawPrimitive" type="Label" parent="TabContainer/Polygons"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 48.0
|
||||
offset_right = 207.0
|
||||
offset_bottom = 97.0
|
||||
text = "draw_primitive()"
|
||||
|
||||
[node name="DrawPolygon" type="Label" parent="TabContainer/Polygons"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 168.0
|
||||
offset_right = 207.0
|
||||
offset_bottom = 217.0
|
||||
text = "draw_polygon()
|
||||
draw_colored_polygon()"
|
||||
|
||||
[node name="DrawPolyline" type="Label" parent="TabContainer/Polygons"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 264.0
|
||||
offset_right = 195.0
|
||||
offset_bottom = 313.0
|
||||
theme_override_colors/font_color = Color(0.501961, 1, 0.501961, 1)
|
||||
text = "draw_polyline()
|
||||
draw_polyline_colors()"
|
||||
|
||||
[node name="DrawMultiline" type="Label" parent="TabContainer/Polygons"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 392.0
|
||||
offset_right = 203.0
|
||||
offset_bottom = 441.0
|
||||
theme_override_colors/font_color = Color(0.501961, 1, 0.501961, 1)
|
||||
text = "draw_multiline()
|
||||
draw_multiline_colors()"
|
||||
|
||||
[node name="Meshes" type="Panel" parent="TabContainer"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
script = ExtResource("5_exx0l")
|
||||
metadata/_tab_index = 3
|
||||
|
||||
[node name="DrawMesh" type="Label" parent="TabContainer/Meshes"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 48.0
|
||||
offset_right = 207.0
|
||||
offset_bottom = 97.0
|
||||
text = "draw_mesh()"
|
||||
|
||||
[node name="DrawMultiMesh" type="Label" parent="TabContainer/Meshes"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 208.0
|
||||
offset_right = 207.0
|
||||
offset_bottom = 257.0
|
||||
text = "draw_multimesh()"
|
||||
|
||||
[node name="Textures" type="Panel" parent="TabContainer"]
|
||||
visible = false
|
||||
texture_repeat = 2
|
||||
layout_mode = 2
|
||||
script = ExtResource("5_84cac")
|
||||
metadata/_tab_index = 4
|
||||
|
||||
[node name="DrawTexture" type="Label" parent="TabContainer/Textures"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 48.0
|
||||
offset_right = 175.0
|
||||
offset_bottom = 97.0
|
||||
text = "draw_texture()
|
||||
draw_texture_rect()"
|
||||
|
||||
[node name="DrawTextureRectRegion" type="Label" parent="TabContainer/Textures"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 392.0
|
||||
offset_right = 231.0
|
||||
offset_bottom = 415.0
|
||||
text = "draw_texture_rect_region()"
|
||||
|
||||
[node name="Text" type="Panel" parent="TabContainer"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
script = ExtResource("6_4w081")
|
||||
metadata/_tab_index = 5
|
||||
|
||||
[node name="DrawChar" type="Label" parent="TabContainer/Text"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 48.0
|
||||
offset_right = 125.0
|
||||
offset_bottom = 97.0
|
||||
text = "draw_char()
|
||||
draw_string()"
|
||||
|
||||
[node name="Animation" type="Panel" parent="TabContainer"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
script = ExtResource("8_yrx86")
|
||||
metadata/_tab_index = 6
|
||||
|
||||
[node name="DrawArcTime" type="Label" parent="TabContainer/Animation"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 48.0
|
||||
offset_right = 125.0
|
||||
offset_bottom = 97.0
|
||||
theme_override_colors/font_color = Color(0.501961, 1, 0.501961, 1)
|
||||
text = "draw_arc()
|
||||
+ time variable"
|
||||
|
||||
[node name="DrawAnimationSlice" type="Label" parent="TabContainer/Animation"]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 216.0
|
||||
offset_right = 201.0
|
||||
offset_bottom = 265.0
|
||||
text = "draw_animation_slice()"
|
||||
|
||||
[node name="AnimationSlice" type="Control" parent="TabContainer/Animation"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("9_obj11")
|
||||
|
||||
[node name="Options" type="HBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 2
|
||||
anchor_top = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 24.0
|
||||
offset_top = -64.0
|
||||
offset_right = 441.0
|
||||
offset_bottom = -24.0
|
||||
grow_vertical = 0
|
||||
theme_override_constants/separation = 20
|
||||
|
||||
[node name="MSAA2DLabel" type="Label" parent="Options"]
|
||||
layout_mode = 2
|
||||
text = "MSAA 2D"
|
||||
|
||||
[node name="MSAA2DOptionButton" type="OptionButton" parent="Options"]
|
||||
layout_mode = 2
|
||||
selected = 0
|
||||
item_count = 4
|
||||
popup/item_0/text = "Disabled"
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "2×"
|
||||
popup/item_1/id = 1
|
||||
popup/item_2/text = "4×"
|
||||
popup/item_2/id = 2
|
||||
popup/item_3/text = "8×"
|
||||
popup/item_3/id = 3
|
||||
|
||||
[node name="VSeparator" type="VSeparator" parent="Options"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="DrawAntialiasing" type="CheckButton" parent="Options"]
|
||||
layout_mode = 2
|
||||
tooltip_text = "Performs antialiasing by adding a feathered outline
|
||||
to lines that are drawn in 2D. This is generally faster to render
|
||||
than 2D MSAA, but not all draw commands support it.
|
||||
|
||||
Commands that support draw antialiasing are
|
||||
highlighted in green."
|
||||
theme_override_colors/font_color = Color(0.501961, 1, 0.501961, 1)
|
||||
theme_override_colors/font_focus_color = Color(0.501961, 1, 0.501961, 1)
|
||||
theme_override_colors/font_pressed_color = Color(0.501961, 1, 0.501961, 1)
|
||||
text = "Draw Antialiasing"
|
||||
|
||||
[connection signal="item_selected" from="Options/MSAA2DOptionButton" to="." method="_on_msaa_2d_item_selected"]
|
||||
[connection signal="toggled" from="Options/DrawAntialiasing" to="." method="_on_draw_antialiasing_toggled"]
|
||||
1
2d/custom_drawing/icon.svg
Normal file
1
2d/custom_drawing/icon.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m15.999738 8a7.9997377 7.9997377 0 0 0 -7.999738 7.999738v67.99777c11.999607 3.999869 7.999738-7.999738 15.999475-7.999738v-51.998295h79.997375v17.599423a19.319367 19.319367 0 0 1 15.99948 3.999869v-29.599029a7.9997377 7.9997377 0 0 0 -7.99974-7.999738zm10.879643 81.43733c-2.263926 1.351955-4.127865 3.727878-5.159831 6.919773-3.327891 10.215667-19.3353659-7.519754-7.567752 16.071477 3.719878 7.44775 15.295499 9.61568 22.679257 5.78381a15.375496 15.375496 0 0 0 6.639782-20.439334c-4.623848-9.263696-11.59962-11.287629-16.591456-8.327726zm17.775417-5.599817 10.175666 19.959347 56.550146-28.815056a11.319629 11.319629 0 0 0 -10.07167-20.271336zm27.343104-43.838562v7.999737h-7.999738v7.999738h-15.999476v7.999738h-7.999737v7.999738h-7.999738v7.999737h1.999935l53.998229-27.783089v-4.215862h-7.999738v-7.999737z" fill="#808080" stroke-width=".999999"/></svg>
|
||||
|
After Width: | Height: | Size: 935 B |
37
2d/custom_drawing/icon.svg.import
Normal file
37
2d/custom_drawing/icon.svg.import
Normal file
@@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dfc361vvrguif"
|
||||
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.svg"
|
||||
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
89
2d/custom_drawing/lines.gd
Normal file
89
2d/custom_drawing/lines.gd
Normal file
@@ -0,0 +1,89 @@
|
||||
# This is a `@tool` script so that the custom 2D drawing can be seen in the editor.
|
||||
@tool
|
||||
extends Panel
|
||||
|
||||
var use_antialiasing := false
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var margin := Vector2(200, 50)
|
||||
|
||||
# Line width of `-1.0` is only usable with draw antialiasing disabled,
|
||||
# as it uses hardware line drawing as opposed to polygon-based line drawing.
|
||||
# Automatically use polygon-based line drawing when needed to avoid runtime warnings.
|
||||
# We also use a line width of `0.5` instead of `1.0` to better match the appearance
|
||||
# of non-antialiased line drawing, as draw antialiasing tends to make lines look thicker.
|
||||
var line_width_thin := 0.5 if use_antialiasing else -1.0
|
||||
|
||||
# Make thick lines 1 pixel thinner when draw antialiasing is enabled,
|
||||
# as draw antialiasing tends to make lines look thicker.
|
||||
var antialiasing_width_offset := 1.0 if use_antialiasing else 0.0
|
||||
|
||||
var offset := Vector2()
|
||||
var line_length := Vector2(140, 35)
|
||||
draw_line(margin + offset, margin + offset + line_length, Color.GREEN, line_width_thin, use_antialiasing)
|
||||
offset += Vector2(line_length.x + 15, 0)
|
||||
draw_line(margin + offset, margin + offset + line_length, Color.GREEN, 2.0 - antialiasing_width_offset, use_antialiasing)
|
||||
offset += Vector2(line_length.x + 15, 0)
|
||||
draw_line(margin + offset, margin + offset + line_length, Color.GREEN, 6.0 - antialiasing_width_offset, use_antialiasing)
|
||||
offset += Vector2(line_length.x + 15, 0)
|
||||
draw_dashed_line(margin + offset, margin + offset + line_length, Color.CYAN, line_width_thin, 5.0, true, use_antialiasing)
|
||||
offset += Vector2(line_length.x + 15, 0)
|
||||
draw_dashed_line(margin + offset, margin + offset + line_length, Color.CYAN, 2.0 - antialiasing_width_offset, 10.0, true, use_antialiasing)
|
||||
offset += Vector2(line_length.x + 15, 0)
|
||||
draw_dashed_line(margin + offset, margin + offset + line_length, Color.CYAN, 6.0 - antialiasing_width_offset, 15.0, true, use_antialiasing)
|
||||
|
||||
|
||||
offset = Vector2(40, 120)
|
||||
draw_circle(margin + offset, 40, Color.ORANGE, false, line_width_thin, use_antialiasing)
|
||||
|
||||
offset += Vector2(100, 0)
|
||||
draw_circle(margin + offset, 40, Color.ORANGE, false, 2.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
offset += Vector2(100, 0)
|
||||
draw_circle(margin + offset, 40, Color.ORANGE, false, 6.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
# Draw a filled circle. The width parameter is ignored for filled circles (it's set to `-1.0` to avoid warnings).
|
||||
# We also reduce the radius by half the antialiasing width offset.
|
||||
# Otherwise, the circle becomes very slightly larger when draw antialiasing is enabled.
|
||||
offset += Vector2(100, 0)
|
||||
draw_circle(margin + offset, 40 - antialiasing_width_offset * 0.5, Color.ORANGE, true, -1.0, use_antialiasing)
|
||||
|
||||
# `draw_set_transform()` is a stateful command: it affects *all* `draw_` methods within this
|
||||
# `_draw()` function after it. This can be used to translate, rotate or scale `draw_` methods
|
||||
# that don't offer dedicated parameters for this (such as `draw_primitive()` not having a position parameter).
|
||||
# To reset back to the initial transform, call `draw_set_transform(Vector2())`.
|
||||
#
|
||||
# Draw an horizontally stretched circle.
|
||||
offset += Vector2(200, 0)
|
||||
draw_set_transform(margin + offset, 0.0, Vector2(3.0, 1.0))
|
||||
draw_circle(Vector2(), 40, Color.ORANGE, false, line_width_thin, use_antialiasing)
|
||||
draw_set_transform(Vector2())
|
||||
|
||||
# Draw a quarter circle (`TAU` represents a full turn in radians).
|
||||
const POINT_COUNT_HIGH = 24
|
||||
offset = Vector2(0, 200)
|
||||
draw_arc(margin + offset, 60, 0, 0.25 * TAU, POINT_COUNT_HIGH, Color.YELLOW, line_width_thin, use_antialiasing)
|
||||
|
||||
offset += Vector2(100, 0)
|
||||
draw_arc(margin + offset, 60, 0, 0.25 * TAU, POINT_COUNT_HIGH, Color.YELLOW, 2.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
offset += Vector2(100, 0)
|
||||
draw_arc(margin + offset, 60, 0, 0.25 * TAU, POINT_COUNT_HIGH, Color.YELLOW, 6.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
# Draw a three quarters of a circle with a low point count, which gives it an angular look.
|
||||
const POINT_COUNT_LOW = 7
|
||||
offset += Vector2(125, 30)
|
||||
draw_arc(margin + offset, 40, -0.25 * TAU, 0.5 * TAU, POINT_COUNT_LOW, Color.YELLOW, line_width_thin, use_antialiasing)
|
||||
|
||||
offset += Vector2(100, 0)
|
||||
draw_arc(margin + offset, 40, -0.25 * TAU, 0.5 * TAU, POINT_COUNT_LOW, Color.YELLOW, 2.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
offset += Vector2(100, 0)
|
||||
draw_arc(margin + offset, 40, -0.25 * TAU, 0.5 * TAU, POINT_COUNT_LOW, Color.YELLOW, 6.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
# Draw an horizontally stretched arc.
|
||||
offset += Vector2(200, 0)
|
||||
draw_set_transform(margin + offset, 0.0, Vector2(3.0, 1.0))
|
||||
draw_arc(Vector2(), 40, -0.25 * TAU, 0.5 * TAU, POINT_COUNT_LOW, Color.YELLOW, line_width_thin, use_antialiasing)
|
||||
draw_set_transform(Vector2())
|
||||
1
2d/custom_drawing/lines.gd.uid
Normal file
1
2d/custom_drawing/lines.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://3gt2v4l0gy1
|
||||
76
2d/custom_drawing/meshes.gd
Normal file
76
2d/custom_drawing/meshes.gd
Normal file
@@ -0,0 +1,76 @@
|
||||
# This is a `@tool` script so that the custom 2D drawing can be seen in the editor.
|
||||
@tool
|
||||
extends Panel
|
||||
|
||||
var use_antialiasing := false
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var margin := Vector2(300, 70)
|
||||
|
||||
var offset := Vector2()
|
||||
var text_mesh := TextMesh.new()
|
||||
text_mesh.text = "TextMesh"
|
||||
# In 2D, 1 unit equals 1 pixel, so the default size at which PrimitiveMeshes are displayed is tiny.
|
||||
# Use much larger mesh size to compensate, or use `draw_set_transform()` before using `draw_mesh()`
|
||||
# to scale the draw command.
|
||||
text_mesh.pixel_size = 2.5
|
||||
|
||||
var noise_texture := NoiseTexture2D.new()
|
||||
noise_texture.seamless = true
|
||||
noise_texture.as_normal_map = true
|
||||
noise_texture.noise = FastNoiseLite.new()
|
||||
|
||||
# FIXME: The mesh needs to be added to a MeshInstance2D (even out-of-tree)
|
||||
# for it to be usable in `draw_mesh()` (otherwise, nothing appears and an error is printed).
|
||||
# Same goes for the texture. I don't know why.
|
||||
var mi2d := MeshInstance2D.new()
|
||||
mi2d.mesh = text_mesh
|
||||
mi2d.texture = noise_texture
|
||||
|
||||
var mi2d2 := MeshInstance2D.new()
|
||||
var sphere_mesh := SphereMesh.new()
|
||||
sphere_mesh.height = 80.0
|
||||
sphere_mesh.radius = 40.0
|
||||
mi2d2.mesh = sphere_mesh
|
||||
mi2d2.texture = noise_texture
|
||||
|
||||
# `draw_set_transform()` is a stateful command: it affects *all* `draw_` methods within this
|
||||
# `_draw()` function after it. This can be used to translate, rotate or scale `draw_` methods
|
||||
# that don't offer dedicated parameters for this (such as `draw_primitive()` not having a position parameter).
|
||||
# To reset back to the initial transform, call `draw_set_transform(Vector2())`.
|
||||
#
|
||||
# Flip drawing on the Y axis so the text appears upright.
|
||||
draw_set_transform(margin + offset, 0.0, Vector2(1, -1))
|
||||
draw_mesh(text_mesh, noise_texture)
|
||||
|
||||
offset += Vector2(150, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_mesh(sphere_mesh, noise_texture)
|
||||
|
||||
var gradient_texture := GradientTexture2D.new()
|
||||
gradient_texture.gradient = Gradient.new()
|
||||
var multi_mesh := MultiMesh.new()
|
||||
multi_mesh.use_colors = true
|
||||
multi_mesh.instance_count = 5
|
||||
multi_mesh.set_instance_transform_2d(0, Transform2D(0.0, Vector2(0, 0)))
|
||||
multi_mesh.set_instance_color(0, Color(1, 0.7, 0.7))
|
||||
multi_mesh.set_instance_transform_2d(1, Transform2D(0.0, Vector2(0, 100)))
|
||||
multi_mesh.set_instance_color(1, Color(0.7, 1, 0.7))
|
||||
multi_mesh.set_instance_transform_2d(2, Transform2D(0.0, Vector2(100, 100)))
|
||||
multi_mesh.set_instance_color(2, Color(0.7, 0.7, 1))
|
||||
multi_mesh.set_instance_transform_2d(3, Transform2D(0.0, Vector2(100, 0)))
|
||||
multi_mesh.set_instance_color(3, Color(1, 1, 0.7))
|
||||
multi_mesh.set_instance_transform_2d(4, Transform2D(0.0, Vector2(50, 50)))
|
||||
multi_mesh.set_instance_color(4, Color(0.7, 1, 1))
|
||||
multi_mesh.mesh = sphere_mesh
|
||||
var mmi2d := MultiMeshInstance2D.new()
|
||||
mmi2d.multimesh = multi_mesh
|
||||
mmi2d.texture = gradient_texture
|
||||
|
||||
# FIXME: The multimesh needs to be added to a MultiMeshInstance2D (even out-of-tree)
|
||||
# for it to be usable in `draw_multimesh()` (otherwise, it crashes).
|
||||
# Same goes for the texture. I don't know why.
|
||||
offset = Vector2(0, 120)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_multimesh(multi_mesh, gradient_texture)
|
||||
1
2d/custom_drawing/meshes.gd.uid
Normal file
1
2d/custom_drawing/meshes.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dy8ofskb8bg4a
|
||||
126
2d/custom_drawing/polygons.gd
Normal file
126
2d/custom_drawing/polygons.gd
Normal file
@@ -0,0 +1,126 @@
|
||||
# This is a `@tool` script so that the custom 2D drawing can be seen in the editor.
|
||||
@tool
|
||||
extends Panel
|
||||
|
||||
var use_antialiasing := false
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var margin := Vector2(240, 40)
|
||||
|
||||
# Line width of `-1.0` is only usable with draw antialiasing disabled,
|
||||
# as it uses hardware line drawing as opposed to polygon-based line drawing.
|
||||
# Automatically use polygon-based line drawing when needed to avoid runtime warnings.
|
||||
# We also use a line width of `0.5` instead of `1.0` to better match the appearance
|
||||
# of non-antialiased line drawing, as draw antialiasing tends to make lines look thicker.
|
||||
var line_width_thin := 0.5 if use_antialiasing else -1.0
|
||||
|
||||
# Make thick lines 1 pixel thinner when draw antialiasing is enabled,
|
||||
# as draw antialiasing tends to make lines look thicker.
|
||||
var antialiasing_width_offset := 1.0 if use_antialiasing else 0.0
|
||||
|
||||
var points := PackedVector2Array([
|
||||
Vector2(0, 0),
|
||||
Vector2(0, 60),
|
||||
Vector2(60, 90),
|
||||
Vector2(60, 0),
|
||||
Vector2(40, 25),
|
||||
Vector2(10, 40),
|
||||
])
|
||||
var colors := PackedColorArray([
|
||||
Color.WHITE,
|
||||
Color.RED,
|
||||
Color.GREEN,
|
||||
Color.BLUE,
|
||||
Color.MAGENTA,
|
||||
Color.MAGENTA,
|
||||
])
|
||||
|
||||
var offset := Vector2()
|
||||
# `draw_set_transform()` is a stateful command: it affects *all* `draw_` methods within this
|
||||
# `_draw()` function after it. This can be used to translate, rotate or scale `draw_` methods
|
||||
# that don't offer dedicated parameters for this (such as `draw_primitive()` not having a position parameter).
|
||||
# To reset back to the initial transform, call `draw_set_transform(Vector2())`.
|
||||
draw_set_transform(margin + offset)
|
||||
draw_primitive(points.slice(0, 1), colors.slice(0, 1), PackedVector2Array())
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_primitive(points.slice(0, 2), colors.slice(0, 2), PackedVector2Array())
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_primitive(points.slice(0, 3), colors.slice(0, 3), PackedVector2Array())
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_primitive(points.slice(0, 4), colors.slice(0, 4), PackedVector2Array())
|
||||
|
||||
# Draw a polygon with multiple colors that are interpolated between each point.
|
||||
# Colors are specified in the same order as points' positions, but in a different array.
|
||||
offset = Vector2(0, 120)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_polygon(points, colors)
|
||||
|
||||
# Draw a polygon with a single color. Only a points array is needed in this case.
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_colored_polygon(points, Color.YELLOW)
|
||||
|
||||
# Draw a polygon-based line. Each segment is connected to the previous one, which means
|
||||
# `draw_polyline()` always draws a contiguous line.
|
||||
offset = Vector2(0, 240)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_polyline(points, Color.SKY_BLUE, line_width_thin, use_antialiasing)
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_polyline(points, Color.SKY_BLUE, 2.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_polyline(points, Color.SKY_BLUE, 6.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_polyline_colors(points, colors, line_width_thin, use_antialiasing)
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_polyline_colors(points, colors, 2.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_polyline_colors(points, colors, 6.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
# Draw multiple lines in a single draw command. Unlike `draw_polyline()`,
|
||||
# lines are not connected to the last segment.
|
||||
# This is faster than calling `draw_line()` several times and should be preferred
|
||||
# when drawing dozens of lines or more at once.
|
||||
offset = Vector2(0, 360)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_multiline(points, Color.SKY_BLUE, line_width_thin, use_antialiasing)
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_multiline(points, Color.SKY_BLUE, 2.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_multiline(points, Color.SKY_BLUE, 6.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
# `draw_multiline_colors()` makes it possible to draw lines of different colors in a single
|
||||
# draw command, although gradients are not possible this way (unlike `draw_polygon()` and `draw_polyline()`).
|
||||
# This means the number of supplied colors must be equal to the number of segments, which means
|
||||
# we have to only pass a subset of the colors array in this example.
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_multiline_colors(points, colors.slice(0, 3), line_width_thin, use_antialiasing)
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_multiline_colors(points, colors.slice(0, 3), 2.0 - antialiasing_width_offset, use_antialiasing)
|
||||
|
||||
offset += Vector2(90, 0)
|
||||
draw_set_transform(margin + offset)
|
||||
draw_multiline_colors(points, colors.slice(0, 3), 6.0 - antialiasing_width_offset, use_antialiasing)
|
||||
1
2d/custom_drawing/polygons.gd.uid
Normal file
1
2d/custom_drawing/polygons.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://clsf8dubgyrig
|
||||
31
2d/custom_drawing/project.godot
Normal file
31
2d/custom_drawing/project.godot
Normal file
@@ -0,0 +1,31 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Custom Drawing in 2D"
|
||||
config/description="A demo showing how to draw 2D elements in Godot without using nodes."
|
||||
run/main_scene="uid://btxwm0qudsn3t"
|
||||
config/features=PackedStringArray("4.4", "Mobile")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
window/stretch/aspect="expand"
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="mobile"
|
||||
146
2d/custom_drawing/rectangles.gd
Normal file
146
2d/custom_drawing/rectangles.gd
Normal file
@@ -0,0 +1,146 @@
|
||||
# This is a `@tool` script so that the custom 2D drawing can be seen in the editor.
|
||||
@tool
|
||||
extends Panel
|
||||
|
||||
var use_antialiasing := false
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var margin := Vector2(200, 40)
|
||||
|
||||
# Line width of `-1.0` is only usable with draw antialiasing disabled,
|
||||
# as it uses hardware line drawing as opposed to polygon-based line drawing.
|
||||
# Automatically use polygon-based line drawing when needed to avoid runtime warnings.
|
||||
# We also use a line width of `0.5` instead of `1.0` to better match the appearance
|
||||
# of non-antialiased line drawing, as draw antialiasing tends to make lines look thicker.
|
||||
var line_width_thin := 0.5 if use_antialiasing else -1.0
|
||||
|
||||
# Make thick lines 1 pixel thinner when draw antialiasing is enabled,
|
||||
# as draw antialiasing tends to make lines look thicker.
|
||||
var antialiasing_width_offset := 1.0 if use_antialiasing else 0.0
|
||||
|
||||
var offset := Vector2()
|
||||
draw_rect(
|
||||
Rect2(margin + offset, Vector2(100, 50)),
|
||||
Color.PURPLE,
|
||||
false,
|
||||
line_width_thin,
|
||||
use_antialiasing
|
||||
)
|
||||
|
||||
offset += Vector2(120, 0)
|
||||
draw_rect(
|
||||
Rect2(margin + offset, Vector2(100, 50)),
|
||||
Color.PURPLE,
|
||||
false,
|
||||
2.0 - antialiasing_width_offset,
|
||||
use_antialiasing
|
||||
)
|
||||
|
||||
offset += Vector2(120, 0)
|
||||
draw_rect(
|
||||
Rect2(margin + offset, Vector2(100, 50)),
|
||||
Color.PURPLE,
|
||||
false,
|
||||
6.0 - antialiasing_width_offset,
|
||||
use_antialiasing
|
||||
)
|
||||
|
||||
# Draw a filled rectangle. The width parameter is ignored for filled rectangles (it's set to `-1.0` to avoid warnings).
|
||||
# We also reduce the rectangle's size by half the antialiasing width offset.
|
||||
# Otherwise, the rectangle becomes very slightly larger when draw antialiasing is enabled.
|
||||
offset += Vector2(120, 0)
|
||||
draw_rect(
|
||||
Rect2(margin + offset, Vector2(100, 50)).grow(-antialiasing_width_offset * 0.5),
|
||||
Color.PURPLE,
|
||||
true,
|
||||
-1.0,
|
||||
use_antialiasing
|
||||
)
|
||||
|
||||
# `draw_set_transform()` is a stateful command: it affects *all* `draw_` methods within this
|
||||
# `_draw()` function after it. This can be used to translate, rotate or scale `draw_` methods
|
||||
# that don't offer dedicated parameters for this (such as `draw_rect()` not having a rotation parameter).
|
||||
# To reset back to the initial transform, call `draw_set_transform(Vector2())`.
|
||||
offset += Vector2(170, 0)
|
||||
draw_set_transform(margin + offset, deg_to_rad(22.5))
|
||||
draw_rect(
|
||||
Rect2(Vector2(), Vector2(100, 50)),
|
||||
Color.PURPLE,
|
||||
false,
|
||||
line_width_thin,
|
||||
use_antialiasing
|
||||
)
|
||||
offset += Vector2(120, 0)
|
||||
draw_set_transform(margin + offset, deg_to_rad(22.5))
|
||||
draw_rect(
|
||||
Rect2(Vector2(), Vector2(100, 50)),
|
||||
Color.PURPLE,
|
||||
false,
|
||||
2.0 - antialiasing_width_offset,
|
||||
use_antialiasing
|
||||
)
|
||||
offset += Vector2(120, 0)
|
||||
draw_set_transform(margin + offset, deg_to_rad(22.5))
|
||||
draw_rect(
|
||||
Rect2(Vector2(), Vector2(100, 50)),
|
||||
Color.PURPLE,
|
||||
false,
|
||||
6.0 - antialiasing_width_offset,
|
||||
use_antialiasing
|
||||
)
|
||||
|
||||
# `draw_set_transform_matrix()` is a more advanced counterpart of `draw_set_transform()`.
|
||||
# It can be used to apply transforms that are not supported by `draw_set_transform()`, such as
|
||||
# skewing.
|
||||
offset = Vector2(20, 60)
|
||||
var custom_transform := get_transform().translated(margin + offset)
|
||||
# Perform horizontal skewing (the rectangle will appear "slanted").
|
||||
custom_transform.y.x -= 0.5
|
||||
draw_set_transform_matrix(custom_transform)
|
||||
draw_rect(
|
||||
Rect2(Vector2(), Vector2(100, 50)),
|
||||
Color.PURPLE,
|
||||
false,
|
||||
6.0 - antialiasing_width_offset,
|
||||
use_antialiasing
|
||||
)
|
||||
draw_set_transform(Vector2())
|
||||
|
||||
offset = Vector2(0, 250)
|
||||
var style_box_flat := StyleBoxFlat.new()
|
||||
style_box_flat.set_border_width_all(4)
|
||||
style_box_flat.set_corner_radius_all(8)
|
||||
style_box_flat.shadow_size = 1
|
||||
style_box_flat.shadow_offset = Vector2(4, 4)
|
||||
style_box_flat.shadow_color = Color.RED
|
||||
style_box_flat.anti_aliasing = use_antialiasing
|
||||
draw_style_box(style_box_flat, Rect2(margin + offset, Vector2(100, 50)))
|
||||
|
||||
offset += Vector2(130, 0)
|
||||
var style_box_flat_2 := StyleBoxFlat.new()
|
||||
style_box_flat_2.draw_center = false
|
||||
style_box_flat_2.set_border_width_all(4)
|
||||
style_box_flat_2.set_corner_radius_all(8)
|
||||
style_box_flat_2.corner_detail = 1
|
||||
style_box_flat_2.border_color = Color.GREEN
|
||||
style_box_flat_2.anti_aliasing = use_antialiasing
|
||||
draw_style_box(style_box_flat_2, Rect2(margin + offset, Vector2(100, 50)))
|
||||
|
||||
offset += Vector2(160, 0)
|
||||
var style_box_flat_3 := StyleBoxFlat.new()
|
||||
style_box_flat_3.draw_center = false
|
||||
style_box_flat_3.set_border_width_all(4)
|
||||
style_box_flat_3.set_corner_radius_all(8)
|
||||
style_box_flat_3.border_color = Color.CYAN
|
||||
style_box_flat_3.shadow_size = 40
|
||||
style_box_flat_3.shadow_offset = Vector2()
|
||||
style_box_flat_3.shadow_color = Color.CORNFLOWER_BLUE
|
||||
style_box_flat_3.anti_aliasing = use_antialiasing
|
||||
custom_transform = get_transform().translated(margin + offset)
|
||||
# Perform vertical skewing (the rectangle will appear "slanted").
|
||||
custom_transform.x.y -= 0.5
|
||||
draw_set_transform_matrix(custom_transform)
|
||||
draw_style_box(style_box_flat_3, Rect2(Vector2(), Vector2(100, 50)))
|
||||
|
||||
draw_set_transform(Vector2())
|
||||
1
2d/custom_drawing/rectangles.gd.uid
Normal file
1
2d/custom_drawing/rectangles.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cquneapbjf3e0
|
||||
0
2d/custom_drawing/screenshots/.gdignore
Normal file
0
2d/custom_drawing/screenshots/.gdignore
Normal file
BIN
2d/custom_drawing/screenshots/custom_drawing.webp
Normal file
BIN
2d/custom_drawing/screenshots/custom_drawing.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
60
2d/custom_drawing/text.gd
Normal file
60
2d/custom_drawing/text.gd
Normal file
@@ -0,0 +1,60 @@
|
||||
# This is a `@tool` script so that the custom 2D drawing can be seen in the editor.
|
||||
@tool
|
||||
extends Panel
|
||||
|
||||
var use_antialiasing := false
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var font := get_theme_default_font()
|
||||
const FONT_SIZE = 24
|
||||
const STRING = "Hello world!"
|
||||
var margin := Vector2(240, 60)
|
||||
|
||||
var offset := Vector2()
|
||||
var advance := Vector2()
|
||||
for character in STRING:
|
||||
# Draw each character with a random pastel color.
|
||||
# Notice how the advance calculated on the loop's previous iteration is used as an offset here.
|
||||
draw_char(font, margin + offset + advance, character, FONT_SIZE, Color.from_hsv(randf(), 0.4, 1.0))
|
||||
|
||||
# Get the glyph index of the character we've just drawn, so we can retrieve the glyph advance.
|
||||
# This determines the spacing between glyphs so the next character is positioned correctly.
|
||||
var glyph_idx := TextServerManager.get_primary_interface().font_get_glyph_index(
|
||||
get_theme_default_font().get_rids()[0],
|
||||
FONT_SIZE,
|
||||
character.unicode_at(0),
|
||||
0
|
||||
)
|
||||
advance.x += TextServerManager.get_primary_interface().font_get_glyph_advance(
|
||||
get_theme_default_font().get_rids()[0],
|
||||
FONT_SIZE,
|
||||
glyph_idx
|
||||
).x
|
||||
|
||||
offset += Vector2(0, 32)
|
||||
# When drawing a font outline, it must be drawn *before* the main text.
|
||||
# This way, the outline appears behind the main text.
|
||||
draw_string_outline(
|
||||
font,
|
||||
margin + offset,
|
||||
STRING,
|
||||
HORIZONTAL_ALIGNMENT_LEFT,
|
||||
-1,
|
||||
FONT_SIZE,
|
||||
12,
|
||||
Color.ORANGE.darkened(0.6)
|
||||
)
|
||||
# NOTE: Use `draw_multiline_string()` to draw strings that contain line breaks (`\n`) or with
|
||||
# automatic line wrapping based on the specified width.
|
||||
# A width of `-1` is used here, which means "no limit". If width is limited, the end of the string
|
||||
# will be cut off if it doesn't fit within the specified width.
|
||||
draw_string(
|
||||
font,
|
||||
margin + offset,
|
||||
STRING,
|
||||
HORIZONTAL_ALIGNMENT_LEFT,
|
||||
-1,
|
||||
FONT_SIZE,
|
||||
Color.YELLOW
|
||||
)
|
||||
1
2d/custom_drawing/text.gd.uid
Normal file
1
2d/custom_drawing/text.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://0kv1wvfyg058
|
||||
67
2d/custom_drawing/textures.gd
Normal file
67
2d/custom_drawing/textures.gd
Normal file
@@ -0,0 +1,67 @@
|
||||
# This is a `@tool` script so that the custom 2D drawing can be seen in the editor.
|
||||
@tool
|
||||
extends Panel
|
||||
|
||||
var use_antialiasing := false
|
||||
|
||||
func _draw() -> void:
|
||||
const ICON = preload("res://icon.svg")
|
||||
var margin := Vector2(260, 40)
|
||||
|
||||
var offset := Vector2()
|
||||
# Draw a texture.
|
||||
draw_texture(ICON, margin + offset, Color.WHITE)
|
||||
|
||||
# `draw_set_transform()` is a stateful command: it affects *all* `draw_` methods within this
|
||||
# `_draw()` function after it. This can be used to translate, rotate or scale `draw_` methods
|
||||
# that don't offer dedicated parameters for this (such as `draw_rect()` not having a rotation parameter).
|
||||
# To reset back to the initial transform, call `draw_set_transform(Vector2())`.
|
||||
#
|
||||
# Draw a rotated texture at half the scale of its original pixel size.
|
||||
offset += Vector2(200, 20)
|
||||
draw_set_transform(margin + offset, deg_to_rad(45.0), Vector2(0.5, 0.5))
|
||||
draw_texture(ICON, Vector2(), Color.WHITE)
|
||||
draw_set_transform(Vector2())
|
||||
|
||||
# Draw a stretched texture. In this example, the icon is 128×128 so it will be drawn at 2× scale.
|
||||
offset += Vector2(70, -20)
|
||||
draw_texture_rect(
|
||||
ICON,
|
||||
Rect2(margin + offset, Vector2(256, 256)),
|
||||
false,
|
||||
Color.GREEN
|
||||
)
|
||||
|
||||
|
||||
# Draw a tiled texture. In this example, the icon is 128×128 so it will be drawn twice on each axis.
|
||||
offset += Vector2(270, 0)
|
||||
draw_texture_rect(
|
||||
ICON,
|
||||
Rect2(margin + offset, Vector2(256, 256)),
|
||||
true,
|
||||
Color.GREEN
|
||||
)
|
||||
|
||||
offset = Vector2(0, 300)
|
||||
|
||||
draw_texture_rect_region(
|
||||
ICON,
|
||||
Rect2(margin + offset, Vector2(128, 128)),
|
||||
Rect2(Vector2(32, 32), Vector2(64, 64)),
|
||||
Color.VIOLET
|
||||
)
|
||||
|
||||
# Draw a tiled texture from a region that is larger than the original texture size (128×128).
|
||||
# Transposing is enabled, which will rotate the image by 90 degrees counter-clockwise.
|
||||
# (For more advanced transforms, use `draw_set_transform()` before calling `draw_texture_rect_region()`.)
|
||||
#
|
||||
# For tiling to work with this approach, the CanvasItem in which this `_draw()` method is called
|
||||
# must have its Repeat property set to Enabled in the inspector.
|
||||
offset += Vector2(140, 0)
|
||||
draw_texture_rect_region(
|
||||
ICON,
|
||||
Rect2(margin + offset, Vector2(128, 128)),
|
||||
Rect2(Vector2(), Vector2(512, 512)),
|
||||
Color.VIOLET,
|
||||
true
|
||||
)
|
||||
1
2d/custom_drawing/textures.gd.uid
Normal file
1
2d/custom_drawing/textures.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dtxyrnurokare
|
||||
Reference in New Issue
Block a user