Image resetting after moving

Hi everyone,
I’ve been creating a map with a 2d array, and now i’m trying to get it to move (since the map is bigger than the screen), but I’m having some trouble with getting the field to stay where it is. The idea behind the code is to compare the mouseX/Y to the point where you started dragging, and forcing that point towards the mouseX/Y to make them align, moving the map in the process.

the code is:

int Xmovement;
int Ymovement;
int pointX;
int pointY;
boolean firstpos;

void draw() {
  background(0);

  for (int x = 0; x < map.length; x++) {
    for (int y = 0; y < map[x].length; y++) {
      float posX = (x * scaleX) + Xmovement;
      float posY = (y * scaleY) + Ymovement;
      if (map[x][y] == 0) {
        image(ED, posX, posY, scaleX, scaleY);

void mouseDragged() {
  if (mouseButton == LEFT) {
    if (firstpos == false) {
      pointX = mouseX;
      pointY = mouseY;
      firstpos = true;
    }
    if (firstpos == true) {
      if ((pointX != mouseX) || (pointY != mouseY) || ((pointX != mouseX) && (pointY != mouseY))) {
        Xmovement = mouseX - pointX;
        Ymovement = mouseY - pointY;
        firstpos = false;
      }
    }
  }
}

The problem is (at least from what i understand) the image resetting, since if you don’t move the mouse for one second while keeping it pressed, the pointX and pointY will reset, making the X and Ymovement 0 and thus the posX and Y return to their original state. Does anybody have tips/ideas to make the system better (my thought was either a different approach for the posX/Y or change the mouseDragged loop entirely)? Thanks in advance!

(ps. the complete array is 76x78 and the image is the same except for the comparison, so I thought I’d leave that out :slight_smile: )

Hi !

Alright, so there are a few things that from my point of view seem wrong here.

  • For one check your syntax, a few brackets are missing.
  • Another quick fix, this line :
    if ((pointX != mouseX) || (pointY != mouseY) || ((pointX != mouseX) && (pointY != mouseY)))
    is equivalent to this one :
    if ((pointX != mouseX) || (pointY != mouseY))
    Since if pointX != mouseX AND pointY != mouseY, then pointX != mouseX OR pointY != mouseY. This just helps to keep your code clearer.
  • Another thing : when checking the truth value of a boolean, don’t do if(firstpos == false) and if(firstpos == true), but if(!firstpos) and if(firstpos)
  • And final one : MouseDragged is only called when the mouse is moved if a button is pressed, and therefore the line if ((pointX != mouseX) || (pointY != mouseY)) is actually unnecessary.

Now onto the actual issue. The way I see it, here you are constantly swiching from two if statements. The bulk of your code can be simplified as :

void mouseDragged() {
  if (mouseButton == LEFT) {
    if (firstpos == false) {
      pointX = mouseX;
      pointY = mouseY;
      firstpos = true;
    }
    if (firstpos == true) {
      if ((pointX != mouseX) || (pointY != mouseY)) {
        firstpos = false;
      }
    }
  }
}

So, forgetting about XMovement, on one call firstpos will be false and you’ll be in case 1, and then firstpos will become true, and if the mouse has been moved, then you’ll go onto the second case and firstpos will switch again. I’m note sure what you’re trying to do, but logically and going from your variable names, I think replacing this function with :

void mouseDragged() {
  if (mouseButton == LEFT) {
    if (firstpos == false) {
      pointX = mouseX;
      pointY = mouseY;
    }
    if (firstpos == true) {
      if (pointX != mouseX || pointY != mouseY) {
        Xmovement = mouseX - pointX;
        Ymovement = mouseY - pointY;
        firstpos = false;
      }
    }
  }
}

Has a better chance at working one time. The issue would then be that after this one time, firstpos will be false and moving again would be compromised. I recommend using the mousePressed function (it would also allow to get rid of firstpos) this way :

void mousePressed(){
  if (mouseButton == LEFT) {
      pointX = mouseX;
      pointY = mouseY;
  }
}

void mouseDragged() {
  if (mouseButton == LEFT) {
     if (pointX != mouseX || pointY != mouseY) {
       Xmovement = mouseX - pointX;
       Ymovement = mouseY - pointY;
     }
  }
}

Finally, when checking on my computer, the way this is coded doesn’t seem to work. The way I usually do it is that I store (for example in the variables pointX and pointY) the position on the map at which the cursor was initially clicked (since the mouse should stay over this spot while dragging). Try using the following code :

void mousePressed() {
  if (mouseButton == LEFT) {
    pointX = mouseX - Xmovement;
    pointY = mouseY - Ymovement;
  }
}

void mouseDragged() {
  if (mouseButton == LEFT) {
    Xmovement = mouseX - pointX;
    Ymovement = mouseY - pointY;
  }
}

Note that pointX and pointY now represents the position on the map at which the cursor was clicked. This code seemed to work on my computer.

Hope this helped :slight_smile:

2 Likes

Thanks for the quick answer!
The code seems to work flawlessly, just a bit of lag when dragging the map around, but I guess that’s just processing itself.

The missing brackets were from copy pasting the start of draw, but forgetting the end :sweat_smile: and the ((pointX != mouseX) && (pointY != mouseY)) was mostly a failsafe, I’ve had code break for those kind of silly reasons (if X moves or Y moves, but if both move it breaks).
And thanks for the tip about (!firstpos) and (firstpos), never actually knew that!

1 Like