Godot - menggambar tanpa aturan

Kadang-kadang terjadi bahwa mesin hanya membatasi aliran ide yang tidak pernah berakhir. Jadi, dulu saya ingin menggambar dari mana saja, apa saja dan dimana saja. Inilah yang akan dibahas.





Untuk memulainya, bayangkan tugas yang sepele: dengan mengklik mouse, Anda perlu menggambar beberapa primitif yang ditentukan pengguna, misalnya, dengan menekan tombol. Kedengarannya sederhana, tapi dengan Godot bisa jadi pusing.





, : 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



, , , .





, . , , . ? Godot, . , :





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 . , !








All Articles