Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Terrorcell on Tue 05/06/2012 17:19:49

Title: [SOLVED]Snapping Object to Grid
Post by: Terrorcell on Tue 05/06/2012 17:19:49
I have a grid made up of tiles (15 x 15 pixels) that I would like an object to snap to (the object is 15 x 15 pixels). The problem is that the object has to follow the cursor, snapping to the grid as it moves. I've tried a few different methods to get this to work but they've turned out a bit ugly. For example, at the moment, my script checks which direction the cursor is moving and whether its position is divisible by 15 before setting the position of the object. But once the cursor starts to move in a bit of a diagonal fashion, the object doesn't quite snap to the grid.

Code (AGS) Select

    // in global space of the room script
    bool isDragging = false; // used to stop mouseX and mouseY from being continuously set to the cursor's current position
    int mouseX, mouseY; // used to hold the position of where the mouse used to be before it moved
    int tileSize = 15;

    // ...
    // in room_RepExec()
    if (!isDragging)
    {
      mouseX = mouse.x;
      mouseY = mouse.y;
      isDragging = true;
    }
   
    if (mouseX > mouse.x) // mouse is moving left
    {
      int i = 0;
      while (i < tileSize)
      {
        if ((mouse.x + i) % tileSize == 0)
        {
          oPlaceHold.SetPosition(mouse.x + i + 5, mouse.y); // oPlaceHold is the object
          i = tileSize;                                     // also, +5 because the grid is 5 pixels away from the left and top of the screen
        }
        i++;
      }
      isDragging = false;
    }
    else if (mouseX < mouse.x) // mouse is moving right
    {
      int i = 0;
      while (i < tileSize)
      {
        if ((mouse.x - i) % tileSize == 0)
        {
          oPlaceHold.SetPosition(mouse.x - i + 5, mouse.y);
          i = tileSize;
        }
        i++;
      }
      isDragging = false;
    }
    if (mouseY > mouse.y) // mouse is moving up
    {
      int i = 0;
      while (i < tileSize)
      {
        if ((mouse.y + i) % tileSize == 0)
        {
          oPlaceHold.SetPosition(mouse.x, mouse.y + i + 5);
          i = tileSize;
        }
        i++;
      }
      isDragging = false;
    }
    else if (mouseY < mouse.y) // mouse is moving down
    {
      int i = 0;
      while (i < tileSize)
      {
        if ((mouse.y - i) % tileSize == 0)
        {
          oPlaceHold.SetPosition(mouse.x, mouse.y - i + 5);
          i = tileSize;
        }
        i++;
      }
      isDragging = false;
    }


I'm very sure that this code could be more efficient and that there is a better way, but I'm stumped, so any ideas would be great.
Cheers, Terrorcell.
Title: Re: Snapping Object to Grid
Post by: Snarky on Tue 05/06/2012 18:19:26
Code (AGS) Select

int tileSize = 15;
int x_offset = 5;
int y_offset = 5;
int gridX;
int gridY;

function room_RepExec()
{
  ...
  gridX = (mouse.x - x_offset)/tileSize;
  gridY = (mouse.y - y_offset)/tileSize;
  oPlaceHold.SetPosition(gridX*tileSize + x_offset, gridY*tileSize + y_offset);
}
Title: Re: Snapping Object to Grid
Post by: Terrorcell on Tue 05/06/2012 18:35:25
My god, that just destroyed my post :tongue: I don't know why that wasn't the first thing I thought of.
Thanks Snarky.
Title: Re: [SOLVED]Snapping Object to Grid
Post by: Snarky on Wed 06/06/2012 11:46:46
Happy to help. It's easy to get stuck in the wrong way of thinking about a problem so that you overlook the "obvious" solution. The trick is usually to have experience doing similar problems several times before, which helps you spot the approach you should take.