Manchmal kommt es vor, dass der Motor einfach den nie endenden Ideenstrom begrenzt. Also, einmal wollte ich von überall, irgendetwas und überall zeichnen. Dies wird diskutiert.
Stellen wir uns zunächst eine so triviale Aufgabe vor: Durch Klicken mit der Maus müssen Sie ein Grundelement zeichnen, das der Benutzer beispielsweise durch Drücken von Tasten angibt. Klingt einfach, aber bei Godot kann es Kopfschmerzen geben.
, : Godot _draw
CanvasItem
, .. , , , _process
. , , _draw
, . . , ? ? ? .
– «» . Godot – , - , . godot API , – VisualServer
. ( ) Godot. , , VisualServer
.
CanvasItem
- , , ? , . RID
(Resource ID), World2D
. CanvasItem
get_canvas_item()
, , _draw
. , , :
: Controller
Drawer
.
"" , . Controller
:
extends Node2D
onready var drawer = $"../Drawer"
var counter = 0
func custom_draw_line(start, goal, color, width=1.0, antialising=false):
VisualServer.canvas_item_add_line(drawer.get_canvas_item(), start, goal, color, width, antialising)
func _process(delta):
if Input.is_action_just_pressed("mouse_left"):
counter += 2
custom_draw_line(Vector2(100, 100)+Vector2(counter, counter), Vector2(300, 150)+Vector2(counter, counter), Color.green)
custom_draw_line(...)
, VisualServer
canvas_item_add_line(...)
, Drawer
. , Controller
, , , .
void CanvasItem::_update_callback() {
if (!is_inside_tree()) {
pending_update = false;
return;
}
RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item());
//todo updating = true - only allow drawing here
if (is_visible_in_tree()) { //todo optimize this!!
if (first_draw) {
notification(NOTIFICATION_VISIBILITY_CHANGED);
first_draw = false;
}
drawing = true;
current_item_drawn = this;
notification(NOTIFICATION_DRAW);
emit_signal(SceneStringNames::get_singleton()->draw);
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_draw);
}
current_item_drawn = nullptr;
drawing = false;
}
//todo updating = false
pending_update = false; // don't change to false until finished drawing (avoid recursive update)
}
7:
RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item())
, . , .. , . , Drawer
. VisualServer.canvas_item_create()
, , , , World2D.canvas
( "" ) .. Drawer
, . VisualServer
VisualServer.canvas_item_set_parent(item, parent)
. : , . , , . :VisualServer.canvas_item_clear(surface)
. :
extends Node2D
onready var drawer = $"../Drawer"
var counter = 0
var surface
func _ready():
surface = VisualServer.canvas_item_create()
VisualServer.canvas_item_set_parent(surface, drawer.get_canvas_item())
func custom_draw_line(start, goal, color, width=1.0, antialising=false):
VisualServer.canvas_item_add_line(surface, start, goal, color, width, antialising)
func _process(delta):
if Input.is_action_just_pressed("mouse_left"):
counter += 2
custom_draw_line(Vector2(100, 100)+Vector2(counter, counter), Vector2(300, 150)+Vector2(counter, counter), Color.green)
elif Input.is_action_just_pressed("mouse_right"):
VisualServer.canvas_item_clear(surface)
counter = 0
, . , Drawer
, .
, , . , CanvasItem
, CanvasItem
( ):
void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
}
4, VisualServer
, , .
? , .. - , . , Resource
, . , , .
, , . , " ". , , ( ), , " ", .
, .. .
, , . , , _draw
CanvasItem
. , 3D , , , .
. : , Godot . , !