0

Im trying to create a 2 rows 3 columns puzzle using CSS and JavaScript. The idea is that the pieces of the puzzle will be all black cut in different shapes. The users has to drag the pieces to board to complete it.I wrote a javascript that creates the board and pieces. Made them draggable too but unable to proceed from here. Need help in changing the shape of pieces from square to other shapes.

var rows = 5;
var columns = 5;

var currTile;
var otherTile;

var turns = 0;

window.onload = function() {
  //initialize the 5x5 board
  for (let r = 0; r < rows; r++) {
    for (let c = 0; c < columns; c++) {
      //<img>
      let tile = document.createElement("img");
      tile.src = "blank.png";

      //DRAG FUNCTIONALITY
      tile.addEventListener("dragstart", dragStart); //click on image to drag
      tile.addEventListener("dragover", dragOver); //drag an image
      tile.addEventListener("dragenter", dragEnter); //dragging an image into another one
      tile.addEventListener("dragleave", dragLeave); //dragging an image away from another one
      tile.addEventListener("drop", dragDrop); //drop an image onto another one
      tile.addEventListener("dragend", dragEnd); //after you completed dragDrop

      document.getElementById("board").append(tile);
    }
  }

  //pieces
  let pieces = [];
  for (let i = 1; i <= rows * columns; i++) {
    pieces.push(i.toString()); //put "1" to "25" into the array (puzzle images names)
  }
  pieces.reverse();
  for (let i = 0; i < pieces.length; i++) {
    let j = Math.floor(Math.random() * pieces.length);

    //swap
    let tmp = pieces[i];
    pieces[i] = pieces[j];
    pieces[j] = tmp;
  }

  for (let i = 0; i < pieces.length; i++) {
    let tile = document.createElement("img");
    tile.src = "blank2.png";

    //DRAG FUNCTIONALITY
    tile.addEventListener("dragstart", dragStart); //click on image to drag
    tile.addEventListener("dragover", dragOver); //drag an image
    tile.addEventListener("dragenter", dragEnter); //dragging an image into another one
    tile.addEventListener("dragleave", dragLeave); //dragging an image away from another one
    tile.addEventListener("drop", dragDrop); //drop an image onto another one
    tile.addEventListener("dragend", dragEnd); //after you completed dragDrop

    document.getElementById("pieces").append(tile);
  }
}

//DRAG TILES
function dragStart() {
  currTile = this; //this refers to image that was clicked on for dragging
}

function dragOver(e) {
  e.preventDefault();
}

function dragEnter(e) {
  e.preventDefault();
}

function dragLeave() {

}

function dragDrop() {
  otherTile = this; //this refers to image that is being dropped on
}

function dragEnd() {
  if (currTile.src.includes("blank")) {
    return;
  }
  let currImg = currTile.src;
  let otherImg = otherTile.src;
  currTile.src = otherImg;
  otherTile.src = currImg;

  turns += 1;
  document.getElementById("turns").innerText = turns;
}
body {
  font-family: Arial, Helvetica, sans-serif;
  text-align: center;
}

#board {
  width: 400px;
  height: 400px;
  border: 2px solid purple;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
}

#board img {
  width: 79px;
  height: 79px;
  border: 0.5px solid lightblue;
}

#pieces {
  width: 1040px;
  height: 160px;
  border: 2px solid purple;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
}

#pieces img {
  width: 79px;
  height: 79px;
  border: 0.5px solid lightblue;
}
<body>
  <br>
  <div id="board"></div>
  <div id="pieces">
  </div>
</body>

6
  • Could you explain more what changing the shape from square means? Are they to look like squares until the user starts dragging one and then it changes (gradually?) to a certain shape or is the piece to be a certain shape to start with? Commented Jan 9, 2023 at 7:50
  • I want the puzzle piece not be in the shape of a square. More like the physical puzzles pieces we buy Commented Jan 9, 2023 at 10:06
  • You forgot tile.draggable=true; Commented Jan 9, 2023 at 15:33
  • To make the pieces different shapes, you either need to have transparent images shaped like you want, or make the whole thing use a canvas Commented Jan 9, 2023 at 15:33
  • Are you wanting jigsaw-shaped pieces which fit together? Commented Jan 9, 2023 at 17:18

1 Answer 1

1

now, you can add event lister to the puzzle to handle dragover event with preventDefault() method to allow the drop to occur. Then, in the event handler, you can retrieve the ID of the puzzle piece being dropped using getdata() method of the datatransfer object with following code:

boardElement.addEventListener("drop", e => {
  // Get the ID of the puzzle piece being dropped
  const id = e.dataTransfer.getData("text/plain");
  // Find the puzzle piece
  const piece = puzzlePieces.find(piece => piece.id === id);
  // Update the color of the puzzle piece
  piece.color = "black";
  // Render the puzzle board
  render();
});

Then, you can add event dragenter in drag-over class in boardelemennt and dragleave to release the drag.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.