#Making a bulletin board

1 messages · Page 1 of 1 (latest)

patent fossil
#

I'm trying to make a bulletin board and I started with the pin's📌

What I want to do is: clicking on pin's will always places start, and the end will be moving with the mouse until the second click (if it's on another pin then place end there, if not on any pin's then discard the new line), and if the second click is on a pin that's already connecting with start, then remove that existing line.

#

@heavy topaz

heavy topaz
#

Let's say I want to make a line from pin1 to pin2, and a line from pin2 to pin3

#

Oh I see

#

Copying your existing code over for reference:

var line_end : float
var line_points : Array = [null, null] 

@import pin_01 # this is the button01 node
@import pin_02 # button02 node


func _on_button01_pressed():
    line_points.push_front(pin_01.global_position)
    queue_redraw()


func _on_button02_pressed():
    line_points.push_front(pin_02.global_position)
    queue_redraw()


func _draw():
    line_start = line_points[0] if line_points[0] != null else line_start
    line_end = line_points[1] if line_points[1] != null else line_end
    draw_line(line_start, line_end, Color.GOLD)```
#

Instead of line_points, you need an array containing the pairs of points. line_pairs or something; each element of line_pairs is a size two array containing a pair of points.

#

you still need line_start- you need to know what button you've clicked first. line_end isn't needed; when you finish a line you'll add it to line_pairs.
However, line_start probably wants to be a reference to the button you've clicked, rather than just it's position- it's type should be Button instead of float (this is not strictly necessary but I think it's gonna make life easier)

#

in your _on_button_pressed() function, if line_start is null, then all you do is set line_start = <the button that was pressed>

patent fossil
#

🤔

heavy topaz
#

if line_start is not null, then you look through line_pairs- if any entry of line pairs is an array containing both line_start and the button you just clicked, then remove that entry. Otherwise, call line_pairs.append([line_start, clicked_button]) to add that pair

#

then in draw, you loop through line_pairs and draw_line(entry[0], entry[1], Color.GOLD)

heavy topaz
#

an element in the array

patent fossil
heavy topaz
#

The current _button_pressed() basically only works if you have a fixed number of buttons and you set up a function for each one, since there's no parameters in the signal

#

you will probably want to emit a custom signal, something like
owner.PinClicked.emit(self) in the button's _button_pressed() function

#

and then in the owner's ready function PinClicked.connect(_on_button_pressed)

patent fossil
# heavy topaz then in draw, you loop through line_pairs and draw_line(entry[0], entry[1], Colo...
extends Control

var line_start : Button = null
var line_pairs : Array = []

@onready var button: Button = $Button
@onready var button_2: Button = $Button2
@onready var button_3: Button = $Button3


func update_line(btn_clicked: Button):
    if line_start == null:
        line_start = btn_clicked
    
    if line_start != null:
        for i in line_pairs:
            if i == [line_start, btn_clicked]:
                line_pairs.erase(i)
            else:
                line_pairs.append([line_start, btn_clicked])
    
    queue_redraw()


func _on_button_pressed() -> void:
    update_line(button)


func _on_button_2_pressed() -> void:
    update_line(button_2)


func _on_button_3_pressed() -> void:
    update_line(button_3)


func _draw() -> void:
    draw_line(line_pairs[0], line_pairs[1], Color.GOLD)
#

This is now what I do, but the thing is that draw_line can only accept Vector2

#

Also I tried to print line_pairs[0], " | ", line_pairs[1] before the queue_redraw() but it says Out of bounds get index '0' (on base: 'Array')

#

🤔

#

btw I haven't start to make the pin buttons as class yet

heavy topaz
#

two things:
line_pairs is a two dimensional array. Each element is a pair (a size two array) of buttons that should have a line between them.
You want to draw a line for each element of line_pairs, not a line between the first two elements- this means a for loop, something like

    draw_line(...```

To deal with needing vectors you should be doing 
```draw_line(pair[0].global_position, pair[1].global_position, Color.GOLD)```
(said this incorrectly earlier, sorry)
patent fossil
#
extends Control

var line_start : Button = null
var line_pairs : Array = []

@onready var button: Button = $Button
@onready var button_2: Button = $Button2
@onready var button_3: Button = $Button3


func update_line(btn_clicked: Button):
    print(line_start, " was clicked!")
    if line_start == null:
        line_start = btn_clicked
    
    if line_start != null:
        for i in line_pairs:
            if i == [line_start, btn_clicked]:
                line_pairs.erase(i)
            else:
                line_pairs.append([line_start, btn_clicked])
    
    print("Current LinePairs: ", line_pairs)
    queue_redraw()


func _on_button_pressed() -> void:
    update_line(button)


func _on_button_2_pressed() -> void:
    update_line(button_2)


func _on_button_3_pressed() -> void:
    update_line(button_3)


func _draw() -> void:
    for pair in line_pairs:
        draw_line(pair[0].global_position, pair[1].global_position, Color.GOLD)
#

This is what I wrote now, but there's two problems: 1) the first print cannot change after I clicked the button once; 2) the second print can only print [], which I think means that my line_pairs never changed since it's created at the beginning of my script 😭

patent fossil
heavy topaz
#

I believe what is happening is that you're changing line_pairs while iterating through it

#

and this is causing problems

#

I would put a 'break' statement after line_pairs.erase(i) an after line_pairs.append(....

#

oh, wait, no, the logic here is just off

#

you want to run line_pairs.append([line_start, btn_clicked]) if no element of the list is the pair

#

right now you look at each element of the list, and add a new line if the element you're currently looking at fails the check

#

so if you've got 50 lines in your list, you're gonna add 50 copies of the same line

patent fossil
#

hmm but that print cannot be activated no matter how many times I clicked the buttons

heavy topaz
#

if <no line_pairs got erased>:
line_pairs.append([line_start, btn_clicked])
needs to be outside the for loop

#

by being inside the for loop, you potentially add the line once for every existing line

#

when there are no lines, this for loop happens 0 times and no chance to add the line occurs

#

if there were 50 lines going into this function, the for loop woul happen 50 times and you could add the line up to 50 times

patent fossil
heavy topaz
#

rather, you'd want to put the

    if i == [line_start, btn_cclicked:
        <DO SOMETHIN HERE>```
in a function
#

what you've done there still has the line_pairs.append in a for loop

#

you just make that fact slightly less easy to see

patent fossil
#

🤔

#

lemme try

#
if line_start != null:
        for i in line_pairs:
            if i == [line_start, btn_clicked]:
                line_pairs.erase(i)
        if not line_pairs.has([line_start, btn_clicked]):
            line_pairs.append([line_start, btn_clicked])
``` something did happened
#

it cannot erase the line nor add a third line tho

heavy topaz
#

I think you need to step back and figure out the logic of what shoul be happening here

patent fossil
#

🤔

heavy topaz
#

.has solves a lot of problems here

#

but you're doing this for loop which removes the potential line and then checking if line_pairs has the line in it

patent fossil
#

ah I see what you mean

#

so um, the erase step does need to go through all the existing lines right?

heavy topaz
#

yes, but it turns out erase can do that automatically

patent fossil
#

but the draw step doesn't, which is why you told me to take it out of the for

heavy topaz
#

er, the append step doesn't

#

(there's another bug that hasn't come up yet btw, but we'll get to that later)

patent fossil
#

hmm somehow my line_start never changes