How to repeat code?

Hi! I’m having trouble with a simple project.
:arrow_right: The aim is to move an image to a designated box. Once the image is in the box, it snaps into place. By clicking a reset button, the image will return to its starting spot and is able to be dragged + snapped into the destination again.

Below is my code. Apologies if it’s confusing, I’ve tried my best to include explanations.

My code:

overBox = False 
locked = False
xOffset = 0.0
yOffset = 0.0
entered = False
reset = False 

def setup():
    size(640, 360)
    global bx, by, box1
    bx = width / 2
    by = height / 2
    box1 = loadImage("drag.png")

def draw():
    global bx, by, overBox
    background(0)
    
    rect(20, 20, 200, 200) #the destination
    image(box1, bx, by) #the box to be dragged to the destination
    rect(400, 20, 100, 100) #the reset button
    
    if bx < mouseX < bx + 100 and by < mouseY < by + 100: #if mouse is over the box
        overBox = True
        if not locked:
            pass
    else:
        overBox = False
    
    if entered: #if the the box is inside the destination, snap it in place
        bx = 40
        by = 40
    
    if reset: #if the refresh button is clicked, reset the box to its original place
        bx = width / 2
        by = height / 2

def mousePressed():
    global locked, xOffset, yOffset, reset
    if overBox:
        locked = True
    else:
        locked = False
    xOffset = mouseX - bx
    yOffset = mouseY - by
    if mouseX > 400 and mouseX < 500 and mouseY > 20 and mouseY < 120: #mouse presses the reset button
        reset = True

def mouseDragged():
    global bx, by
    if locked:
        bx = mouseX - xOffset
        by = mouseY - yOffset

def mouseReleased():
    global locked, entered
    locked = False
    if bx + 100 < 220 and by + 100 < 220: #if the box is released in the destination
        entered = True

Right now, the code manages to return the box to its starting spot but my attempts to repeat the dragging+snapping code have failed.

I have tried doing something like this:

#setup stuff

def draw():
    background(0)
    resetFunction()

def resetFunction():
    global bx, by, overBox
    #code to make box drag and snap  
    if reset: 
        bx = width / 2
        by = height / 2
        resetFunction()

But I get a NullPointerException error message. I’ve also tried using a while loop but it also didn’t work.

Thank you in advance!

Hi @snakey, I think you need a state machine. Lots of info, go Googling. In simple terms declare a global integer, the value in it states what phase the game is, e.g. 0 = nothing, 1 = dragging, 2 = close to target and auto-moving in, 3 = on target and finished. The action, in draw or functions called by draw, chooses what to do depending on state. Depending on conditions the action can change the state.

To any people who might have the same problem, I moved my variables to the setup function, and called the function from mousePressed!

Example:

def setup():
     overBox = False 
     locked = False
     #etc...

def mousePressed()
     if mouseX > 100 and mouseX < 200 #etc...
     setup()