How to draw a line in 2D?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Tort
:warning: Old Version Published before Godot 3 was released.

How to draw a line in 2D?

enter image description here

:bust_in_silhouette: Reply From: Beamer159

The CanvasItem node has the function draw_line(…). Add a CanvasItem node to your project and attach a script with this code added to it:

func _draw():
    draw_line(Vector2(0,0), Vector2(50, 50), Color(255, 0, 0), 1)

This creates a red diagonal line in the top-left corner. Note that draw_line(…) function must be put in the _draw() function. To call the _draw() function again, call update().

:bust_in_silhouette: Reply From: tiernich

use: func _draw() instead

oh, dont see the answer above :slight_smile:

tiernich | 2016-05-09 19:54

:bust_in_silhouette: Reply From: Tort

Function _draw() is executed only once. How to make the function run forever?

function _draw() is executed automatically only once. It is then executed whenever the node calls update(). If you want _draw() to be called forever, then do the following:

  1. In ready(), add the line “set_process(true)”. This line will allow you to do something every iteration of the game loop.
  2. Add function _process(delta). This is the function that is called for every iteration of the game loop. In this function, add “update()”

In summary:

extends Area2D

func _ready():
    set_process(true)

func _process(delta):
    update()

func _draw():
    draw_line(Vector2(0,0), Vector2(50, 50), Color(255, 0, 0), 1)

Beamer159 | 2016-05-09 20:22

Thanks. Now I try to draw a curved line on the coordinates of the list …

Tort | 2016-05-09 20:45

Add update() at the end of func _draw()

luislodosm | 2020-09-07 12:36

:bust_in_silhouette: Reply From: Tort

Solved

var draw_list = []

func _ready():
	set_fixed_process(true)
	set_process(true)
	draw_list = [Vector2(0, 0), Vector2(250, 10), Vector2(50, 300), Vector2(500, 500)]

func _fixed_process(delta):
	pass

func _process(delta):
	update()
	
func _draw():
	if draw_list != []:
		var temp_draw_list = []
		for ob in draw_list:
			temp_draw_list.append(ob)
			if temp_draw_list != []:
				if temp_draw_list != draw_list:
					draw_line(temp_draw_list[temp_draw_list.size()-1], draw_list[temp_draw_list.size()], Color(1.0, 1.0, 0.5, 1.0), 3)
			print(ob)
:bust_in_silhouette: Reply From: Ransome

A Line2D node type was added in 3.0

In the example below $MyLine is a reference to a Line2D on my scene. from and to are Vector2D:

func createLine(from, to):
  $MyLine.add_point(from)
  $MyLine.add_point(to)

func removeLine():
  $MyLine.points = []

Thanks for the Line2D hint. For those looking, here is the working code I used to draw a box I needed.

func draw_domain_box():
	# setting solid lines
	var solid_box = ([[Vector2(30,185), Vector2(30, 585)],
		[Vector2(30,585), Vector2(230, 735)],
		[Vector2(230, 735), Vector2(230,335)],
		[Vector2(230, 335), Vector2(30,185)],
		[Vector2(30,185), Vector2(430, 185)],
		[Vector2(430,185), Vector2(630, 335)],
		[Vector2(630, 335), Vector2(230,335)],
		[Vector2(230,735), Vector2(630, 735)],
		[Vector2(630, 735), Vector2(630,335)]])

	# setting dotted lines
	var dotted_box = ([[Vector2(430,185),Vector2(430,535)],
		[Vector2(430,585),Vector2(630, 735)],
		[Vector2(30,585),Vector2(430, 585)]])

	# drawing solid lines
	var line = get_node('DomainBox/SolidLine')
	for loop in range(0,solid_box.size()):
		createLine(solid_box[loop][0], solid_box[loop][1],line)
		
	# drawing dotted lines
	createDottedLine(dotted_box[0][0], dotted_box[0][1],1,12)
	createDottedLine(dotted_box[1][0], dotted_box[1][1],13,11)
	createDottedLine(dotted_box[2][0], dotted_box[2][1],25,11)

func createLine(from, to, line):
	# drawing solid line
	line.add_point(from)
	line.add_point(to)

func createDottedLine(from, to, line_counter, loop_counter):
	# calculating xy changes
	var x_distance = (to.x - from.x)
	var y_distance = (to.y - from.y)

	# setting starting position
	var x_current = from.x
	var y_current = from.y

	# creating dotted lines
	for loop in range(0,loop_counter):
		# setting dotted control line to use
		var dotted_line = get_node('DomainBox/DottedLine' + str(line_counter + loop))

		# setting start/finish positions
		var x_start = x_current
		var x_finish = (x_start + (x_distance/32))
		var y_start = y_current
		var y_finish = (y_start + (y_distance/32))

		# drawing line
		dotted_line.add_point(Vector2(x_start,y_start))
		dotted_line.add_point(Vector2(x_finish,y_finish))

		# incrementing positions, adding gap 
		x_current = x_finish + (x_distance/16)
		y_current = y_finish + (y_distance/16)

grymjack | 2023-04-04 18:51