+1 vote

Hi! Fairly new to godot and I've started experimenting with Control nodes. At the moment I'm attempting to create a Windows 10 style window to the best of my ability. I'm wondering how I would go about expanding and contracting the window with my mouse in game.

Basically what I want:
enter image description here
I was thinking if I could check if the mouse was colliding with a horizontal side / vertical side I could then change the size relative to the mouse, but I'm not sure how to do that beyond putting a node on each side and checking if the mouse entered. Also doubtful that'd be the best way to handle it.

Thanks in advance for any advice given!

Also, my node tree if relevant:
enter image description here

in Engine by (17 points)
edited by

2 Answers

0 votes

After two days of messing around I figured something out, seems to work fine though i'm not sure if this is the best way to achieve the resizing. If anyone is interested here is my code, hopefully, it will help you.
https://pastebin.com/TwXkPzLn

Also if anyone is willing to skim through my code and give me any advice that'd be great, could be as simple as some best practice advice. I'm coming from gamemaker studio and have no formal programming knowledge.

by (17 points)
+3 votes

I did it this way using a ColorRect node, and creating 4 child nodes that warn the parent when pressed. I don't know if this is more or less efficient than your solution, but here's the code in case it helps someone:

ColorRect script: (item you want to move, I think this would work with any node that uses rectsize and rectposition)

extends ColorRect

var clicked_pos
var rects_positions = []
var corn_clicked = false

func _ready():
    set_rectangles_positions()
    create_rectangles()


func _gui_input(event):
    if event is InputEventMouseButton:
        if event.pressed:
            clicked_pos = event.position
        else:
            clicked_pos = false
    if event is InputEventMouseMotion:
        if clicked_pos is Vector2:
            move()


func move():
    rect_position = get_global_mouse_position() - clicked_pos

func resize(corner): #triggered from children (squaret.gd)
    var to_size = rect_size
    var to_pos = rect_position
    match corner:
        0: #topleft
            to_pos = get_global_mouse_position() 
            to_size = rect_size - get_local_mouse_position()
        1: #topright
            to_pos.y = get_global_mouse_position().y
            to_size.y = rect_size.y - get_local_mouse_position().y
            to_size.x = get_local_mouse_position().x
        2: #botleft
            to_pos.x = get_global_mouse_position().x
            to_size.x = rect_size.x - get_local_mouse_position().x
            to_size.y = get_local_mouse_position().y
        3: #botright
            to_size = get_local_mouse_position()
    rect_size = to_size
    rect_position = to_pos
    set_rectangles_positions()
    update_rects_positions()

func set_rectangles_positions():
        rects_positions = [
        Vector2(-4, -4), #topleft
        Vector2(rect_size.x-6, -4), #topright
        Vector2(-4, rect_size.y-6), #botleft
        rect_size - Vector2(6, 6) #botright
    ]

func create_rectangles():
    for i in 4:
        var newrect = ColorRect.new()
        newrect.rect_size = Vector2(10, 10)
        newrect.color = Color(0,0,0)
        newrect.rect_position = rects_positions[i]
        newrect.name = "squaret" + str(i)
        newrect.set_script(load("res://squaret.gd")) #attach the other script
        newrect.ind = i
        add_child(newrect, true)

func update_rects_positions():
    for item in get_children():
        if item is ColorRect:
            item.rect_position = rects_positions[item.ind]

squaret.gd script (script that gets attached to children squares when created):

extends ColorRect

var ind: int
var clicked = false

func _gui_input(event):
    if event is InputEventMouseButton:
        if event.pressed:
            clicked = true
        else:
            clicked = false
    if event is InputEventMouseMotion:
        if clicked:
            get_parent().resize(ind) #trigger resize function in parent

Maybe this could also be done by using a signal from childen nodes, but I found this cleaner. Performance-wise I don't have any idea about what is better.

by (64 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.