2

I am currently working on making a grid of squares for a tile map. I have it set up so clicking on a tile changes its state to explored from unexplored. I am attempting to have it so that dragging with the mouse down will change the state of all underlying tiles, however I can't seem to get it to work.

I have tried using mousedown and mouseup events to set a down boolean value which I then check inside of a mouseover. I have tried going about this in several ways (i.e. the commented out code). The current code will work for clicking but I really want to be able to do a drag to change multiples feature.

var tableString;
var width = 35;
var height = 15;
var cells = [];
var localX;
var localY;


function cell(x, y, c) {
  positionX = x;
  positionY = y;
  category = c;
}

function createMap() {
  for (var i = 0; i < height; i++) {
    var row = [];
    for (var j = 0; j < width; j++) {
      let c = new cell();
      c.category = "unexplored";
      c.positionX = j;
      c.positionY = i;
      row.push(c);
    }
    cells.push(row);
  }
}

function drawMap() {
  tableString = "<table draggable='false'>";
  for (var i = 0; i < height; i++) {
    tableString += "<tr draggable='false'>";
    for (var j = 0; j < width; j++) {
      tableString += '<td draggable="false" class="' + cells[i][j].category + '" data-row="' + j + '" data-column="' + i + '"></td>';
    }
    tableString += "</tr>";
  }
  tableString += "</table>";
  $("#mainContainer").html(tableString);
  console.log("drew it");
}

function updateCellCategory(x, y, c) {
  cells[x][y].category = c;
  drawMap();
}


$(document).ready(function() {
  createMap();
  drawMap();


  // var down = false;
  // $(document,"td").mousedown(function () {
  //     down = true;
  // })
  // $(document,"td").mouseup(function () {
  //     down = false;
  // });

  // $(document,"td").on('mouseover','td',function () {
  //     if (down) {
  //         console.log("hovering and holding");
  //         localX = $(this).attr("data-row");
  //         localY = $(this).attr("data-column");
  //         updateCellCategory(localY, localX, "explored");
  //     }

  // });
});


// $(document).on('mousedown',"td, documen",(function () {
//     down = true;
//     console.log(down);
// }));
// $(document).on('mouseup',"*",(function () {
//     down = false;
//     console.log(down);
// }));

// $(document).on('mouseover','td',function () {
//     if (down) {
//         console.log("hovering and holding");
//         localX = $(this).attr("data-row");
//         localY = $(this).attr("data-column");
//         updateCellCategory(localY, localX, "explored");
//     }

// });

$("*").delegate('td', 'click', function() {
  localX = $(this).attr("data-row");
  localY = $(this).attr("data-column");
  updateCellCategory(localY, localX, "explored");
});
html,
body {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px;
}

#mainContainer {
  max-width: 100%;
  max-height: 90%;
  width: 100%;
  height: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
}

td {
  width: 25px;
  height: 25px;
  border: .05px solid black;
}

.explored {
  background-color: lightblue;
}

.unexplored {
  background-color: lightcoral;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
  <div id="mainContainer">

  </div>
</body>

</html>

The main issue I found when working on this is that some of the commented code works sometimes, but the second a drag event happens on a td the code breaks and the mouseup is not recognized causing the mouse cursur to continue affecting tiles even though the mouse was not held down.

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
  • `delegate` is deprecated. You'd be best to update your code. Also, if you post some of your HTML we might be able to get the above into a working demo. – Lee Taylor Sep 18 '19 at 22:16
  • 1
    I just made it into a codepen https://codepen.io/JoelSchmidt/pen/VwZEGON – Joel Schmidt Sep 18 '19 at 22:23
  • You don't need to use codepen here. In fact, you'll probably get more help if you insert a code snippet. I've changed your question. – Lee Taylor Sep 18 '19 at 22:26
  • 1
    I appreciate it! – Joel Schmidt Sep 18 '19 at 22:27
  • See my answer. Please add any comments to that. Is that close to what you want? – Lee Taylor Sep 18 '19 at 22:33
  • I have uncommented a section of your code and it is working for me in Firefox perfectly. Here is the forked code pen. https://codepen.io/ianroskow/pen/WNeaaeR Look at this post that is using a similar approach, they talk about browser issues. https://stackoverflow.com/questions/322378/javascript-check-if-mouse-button-down – Roskow Sep 18 '19 at 22:35

2 Answers2

1

OK. Using the click event is not what you want, since that involves pressing the mouse and releasing it.

Instead use, the mousemove, mousedown and mouseup events. Also, keep track of whether the mouse is down or not using a variable.

var tableString;
var width = 35;
var height = 15;
var cells = [];
var localX;
var localY;
var mouseDown = false;

function cell(x, y, c) {
  positionX = x;
  positionY = y;
  category = c;
}

function createMap() {
  for (var i = 0; i < height; i++) {
    var row = [];
    for (var j = 0; j < width; j++) {
      let c = new cell();
      c.category = "unexplored";
      c.positionX = j;
      c.positionY = i;
      row.push(c);
    }
    cells.push(row);
  }
}

function drawMap() {
  tableString = "<table draggable='false'>";
  for (var i = 0; i < height; i++) {
    tableString += "<tr draggable='false'>";
    for (var j = 0; j < width; j++) {
      tableString += '<td draggable="false" class="' + cells[i][j].category + '" data-row="' + j + '" data-column="' + i + '"></td>';
    }
    tableString += "</tr>";
  }
  tableString += "</table>";
  $("#mainContainer").html(tableString);
  //console.log("drew it");
}

function updateCellCategory(x, y, c) {
  cells[x][y].category = c;
  drawMap();
}

$(document).ready(function() {
  createMap();
  drawMap();
});

$("*").on("mousedown", 'td',  function() 
{
  mouseDown = true;
});

$(document).on("mouseup", function() 
{
  mouseDown = false;
});

$("*").on("mousemove", 'td',  function() 
{
  if(!mouseDown)
    return;

  localX = $(this).attr("data-row");
  localY = $(this).attr("data-column");
  updateCellCategory(localY, localX, "explored");
});
html,
body {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px;
}

#mainContainer {
  max-width: 100%;
  max-height: 90%;
  width: 100%;
  height: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
}

td {
  width: 25px;
  height: 25px;
  border: .05px solid black;
}

.explored {
  background-color: lightblue;
}

.unexplored {
  background-color: lightcoral;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
  <div id="mainContainer">

  </div>
</body>

</html>
Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
0

You can check whether or not the mouse is down using the event parameter of the event handler. Look at the last few lines of the snippet.

var tableString;
var width = 35;
var height = 15;
var cells = [];
var localX;
var localY;


function cell(x, y, c) {
  positionX = x;
  positionY = y;
  category = c;
}

function createMap() {
  for (var i = 0; i < height; i++) {
    var row = [];
    for (var j = 0; j < width; j++) {
      let c = new cell();
      c.category = "unexplored";
      c.positionX = j;
      c.positionY = i;
      row.push(c);
    }
    cells.push(row);
  }
}

function drawMap() {
  tableString = "<table draggable='false'>";
  for (var i = 0; i < height; i++) {
    tableString += "<tr draggable='false'>";
    for (var j = 0; j < width; j++) {
      tableString += '<td draggable="false" class="' + cells[i][j].category + '" data-row="' + j + '" data-column="' + i + '"></td>';
    }
    tableString += "</tr>";
  }
  tableString += "</table>";
  $("#mainContainer").html(tableString);
  console.log("drew it");
}

function updateCellCategory(x, y, c) {
  cells[x][y].category = c;
  drawMap();
}


$(document).ready(function() {
  createMap();
  drawMap();


  // var down = false;
  // $(document,"td").mousedown(function () {
  //     down = true;
  // })
  // $(document,"td").mouseup(function () {
  //     down = false;
  // });

  // $(document,"td").on('mouseover','td',function () {
  //     if (down) {
  //         console.log("hovering and holding");
  //         localX = $(this).attr("data-row");
  //         localY = $(this).attr("data-column");
  //         updateCellCategory(localY, localX, "explored");
  //     }

  // });
});


// $(document).on('mousedown',"td, documen",(function () {
//     down = true;
//     console.log(down);
// }));
// $(document).on('mouseup',"*",(function () {
//     down = false;
//     console.log(down);
// }));

// $(document).on('mouseover','td',function () {
//     if (down) {
//         console.log("hovering and holding");
//         localX = $(this).attr("data-row");
//         localY = $(this).attr("data-column");
//         updateCellCategory(localY, localX, "explored");
//     }

// });

$("*").delegate('td', 'mousedown', function() {
  localX = $(this).attr("data-row");
  localY = $(this).attr("data-column");
  updateCellCategory(localY, localX, "explored");
});

$("*").delegate('td', 'mouseenter', function(event) {
  if (event.buttons) {
    localX = $(this).attr("data-row");
    localY = $(this).attr("data-column");
    updateCellCategory(localY, localX, "explored");
  }
  event.stopPropagation();
});
html,
body {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px;
}

#mainContainer {
  max-width: 100%;
  max-height: 90%;
  width: 100%;
  height: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
}

td {
  width: 25px;
  height: 25px;
  border: .05px solid black;
}

.explored {
  background-color: lightblue;
}

.unexplored {
  background-color: lightcoral;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
  <div id="mainContainer">

  </div>
</body>

</html>
Skylar
  • 928
  • 5
  • 18