Sliding Puzzle - Arrays or Objects?

edited May 2014 in How To...

Hey im gonna try to create a sliding puzzle. So a game where i have a grid of some sort, and square pieces on top that can be moved around the grid. But only in the up,down,left,right directions. Ive already created something similar by using a 2d array which stores the state of every cell in the grid. so if i change the value of a specific entry in the array it reflects on the grid by drawing a rectangle there. however using this method, if i move the rectangle it just jumps from one position to the next, if that makes sense. it doesn't animate from say left to right instead it just jumps left, seeing as im just making the entry at the current position 0 and then putting the entry in a different position in the array.

Would using object be better in this situation or can i work away around it with the arrays?

i hope this makes sense...

Tagged:

Answers

  • edited May 2014 Answer ✓

    1st of all, arrays are objects too! Any datatype which doesn't belong to the 8 primitive types are reference types! ;)

    2nd, your issue doesn't have anything to do w/ data structures. Like you said, you wanna animate a transition.
    That is, from a previous state to the new current state.

    You have to create a method which that makes the sliding effect.
    While at the same time, refuse user input while the animation takes place!

  • Answer ✓

    yeah, stick with the 2D-grid

    this 2D array contains objects (cell)

    when making a move just draw the animation above the grid. You don't have to use the grid data for it. Remember that the animation and the data don't need to be the same or connected.

    • just paint the grid. Copy the image of the source cell to an image.
    • set the cell to empty
    • move the image (don't allow input).
    • once it reached the target cell, set the target cell to the image.
  • ok thanks guys i think i understand what youve mentioned. ill try it out now, ill see how it goes. Also can you point me in the right direction how i would go about loading an image and then splitting it into say 9 or 16 pieces, that are then all seperate images? i havent worked much with images so far. thanks

  • edited May 2014

    when you load the image you can make a double for-loop that fills your 2D-grid with the tiles according to the sections of the image

    grid[ i][ j].image = img1.get(i*sectionWidth, j*sectionHeight, sectionWidth, sectionHeight);
    

    http://www.processing.org/reference/PImage_get_.html

  • I've got an online example. It's still a lil' buggy. But at least it's a start: 8-X
    http://studio.processingtogether.com/sp/pad/export/ro.9$MTikWt80-9w/latest

  • aight ill try that later thanks Chrisir. GoToLoop thats cool, i had a brief look at it but im busy this weekend with study for a uni test ill have a closer look how you did that during the week. thanks anyway.

  • Finally got some time to do this. This is what i ended up with after a bit. could be improved but works really well in the moment so i dont see the need. could use a proper start screen of something like that though, tell me what you think or if i could improve it anywhere.

    PImage picture;
    int newW, newH;
    
    int gridX = 3; //number of tiles boxes along X
    int gridY = 3; //number of tiles boxes along Y
    int gridSize = gridX * gridY; //total number of tiles in game
    int tileWidth, tileHeight; //width and height of each tile
    int gapX, gapY; //X and Y position of the gap in the tiles, eg the free space used to move the ther tiles
    int mousePosX, mousePosY; //position of mouse in terms of the grid system
    int selectX = -1, selectY = -1; //x and y position of the currently selected tile
    
    IntList shuffleOrder = new IntList(); //used to shuffle the tiles in the tiles array
    PImage[] tiles = new PImage[gridSize]; //hold all the image tiles
    int[][] grid = new int[gridX][gridY]; //grid system that controls the movement of the tiles
    boolean selected = false; //keeps track of wether a tile is currently selected
    boolean gameStarted = false; //keeps track of wether the game has started or not
    
    int counter = 0; //used to count through the tiles array
    
    void setup() {
      picture = loadImage("background.jpg");
      newW = picture.width; //canvas size is always equal to the picture that is being used
      newH = picture.height;
      size(newW, newH);
    
      tileWidth = newW/gridX; //tile width is an integer an therefore sometimes the is space at the bottom or right side that is not being used
      tileHeight = newH/gridY; //although techincally the picture would still go on there, but theres not tiles there..
    
      for (int i = 0; i < gridSize; i++) {
        shuffleOrder.append(i); //fill the shuffle array with the numbers 1,2,3,4... each on being assigned to one tile of the big image
      }
      for (int y = 0; y < gridY; y++) {
        for (int x = 0; x < gridX; x++) {
          tiles[counter] = picture.get(x*tileWidth, y*tileHeight, tileWidth, tileHeight); //fill the tiles array with the pieces of the image
          counter++;
        }
      }
      fillGrid(); //transfers the numbers from the so far un-shuffled IntList to the grid to display each piece in its original location
    }
    
    void draw() {
      background(255, 0, 0);
      mousePosX = int(mouseX/tileWidth); //constantly tracks the mouse's grid position
      mousePosY = int(mouseY/tileHeight);
    
      counter = 0;
      for (int y = 0; y < gridY; y++) {
        for (int x = 0; x < gridX; x++) {
          if (grid[x][y] != -1) //draw the images according to the number saved in the grid which is then looked up in the tiles array. -1 is the gap, so dont draw that specific tile
            image(tiles[grid[x][y]], x*tileWidth, y*tileHeight);
          counter++;
        }
      }
    
      if (nextToGap() && gameStarted) {
        outlineTile(mousePosX, mousePosY); //outline the tile if the mouse is over it and it is next to the gap (only N,E,S,W)
      }
    
      if (selectX != -1) {
        outlineTile(selectX, selectY); //also outline the currently selected tile
      }
    }
    
    void fillGrid() {
      counter = 0;
      for (int y = 0; y < gridY; y++) {
        for (int x = 0; x < gridX; x++) {
          grid[x][y] = shuffleOrder.get(counter); //places the integers from the shuffle IntList into the grid
          counter++;
        }
      }
    }
    
    void removeOne() {
      gapX = int(random(gridX));
      gapY = int(random(gridY));
      grid[gapX][gapY] = -1; //selectes a random piece and makes it the gap, aka invisible so that other pieces can be pushed over it
    }
    
    void outlineTile(int x, int y) {
      noFill();
      stroke(255);
      strokeWeight(2);
      rect(x*tileWidth, y*tileHeight, tileWidth, tileHeight);
    }
    
    boolean nextToGap() { //checks if the mouse is in a tile above, below or left, right of the current gap
      if (((mousePosX == gapX-1 || mousePosX == gapX+1) && mousePosY == gapY)|| ((mousePosY == gapY-1 || mousePosY == gapY+1) && mousePosX == gapX))
        return true;
      else
        return false;
    }
    
    void keyPressed() { //spacebar shuffles the Intlist which is then updated into the grid and one is removed as the gap
      if (key == ' ') {
        shuffleOrder.shuffle();
        fillGrid();
        removeOne();
        gameStarted = true;
      }
    }
    
    void mousePressed() {
      if (nextToGap()) {
        if (selected && mousePosX == selectX && mousePosY == selectY) { //if you click the selected tile again it becomes unselected
          selectX = -1;
          selectY = -1;
          selected = false;
        } 
        else { //if nothing is yet selected, select the tile that the mouse clicked on
          selectX = mousePosX;
          selectY = mousePosY;
          selected = true;
        }
      }
      if (selected && mousePosX == gapX && mousePosY == gapY) {
        grid[mousePosX][mousePosY] = grid[selectX][selectY];
        grid[selectX][selectY] = -1;  //if a tile is selected and the user clicks on the gap, the two are swapped,
        gapX = selectX; //so in other words the selected tile is moved to the previous gap location
        gapY = selectY;
        selectX = -1;
        selectY = -1;
        selected = false;
      }
    }
    
  • edited May 2014

    The IntList seems kinda un-necessary i think, but i didnt know if there was anything like the shuffle function i used on the IntList, that i could use on the PImage array.

  • edited May 2014

    The sort() method is an attractive addition for the new Processing's data structures. :D
    Although regular arrays got their own sort() function too among Processing's API: :-j
    http://processing.org/reference/sort_.html

  • edited May 2014

    not sure exactly what you mean, sorry. The reference says that sort() function is only for the other array types not PImage arrays. And also how would that help me get a shuffled order like i did in the code i posted with the use of the shuffled intlist? I guess the way i did it in the above code works fine but just seemed like it could be done more elegantly

  • edited May 2014

    Oh! My mistake. I've mixed up sort() & shuffle(). L8 at night now! X_X

  • only 3:30pm where i am ;)
    i think ill just leave it as is atm. zank u though

Sign In or Register to comment.