javascript - 如何让这个图片 slider 拼图开始洗牌而无需按下按钮?

标签 javascript

Goodday Coders,我正在努力解决这个谜题脚本,我想将其用于网站的“与团队见面”页面。

我希望谜题在页面加载时打乱,而不必按随机播放按钮。 如果人们按下“Wie ben ik”按钮,谜题就会解决,就像现在一样。

不知何故,我无法让它工作,如果有人能帮助我,那就太好了。

这是代码笔链接:

https://codepen.io/verberne/pen/WNxyprV

// Begin game once DOM loaded
document.addEventListener("DOMContentLoaded", game);
// document.addEventListener("DOMContentLoaded", shuffleTimeouts);

function game() {

  // Data structure to hold positions of tiles
  var parentX = document.querySelector(".sliding-puzzle").clientHeight;
  var baseDistance = 38;
  var tileMap = {
    1: {
      tileNumber: 1,
      position: 1,
      top: 0,
      left: 0
    },
    2: {
      tileNumber: 2,
      position: 2,
      top: 0,
      left: baseDistance * 1
    },
    3: {
      tileNumber: 3,
      position: 3,
      top: 0,
      left: baseDistance * 2
    },
    4: {
      tileNumber: 4,
      position: 4,
      top: baseDistance,
      left: 0
    },
    5: {
      tileNumber: 5,
      position: 5,
      top: baseDistance,
      left: baseDistance
    },
    6: {
      tileNumber: 6,
      position: 6,
      top: baseDistance,
      left: baseDistance * 2
    },
    7: {
      tileNumber: 7,
      position: 7,
      top: baseDistance * 2,
      left: 0
    },
    8: {
      tileNumber: 8,
      position: 8,
      top: baseDistance * 2,
      left: baseDistance
    },
    empty: {
      position: 9,
      top: baseDistance * 2,
      left: baseDistance * 2
    }
  }

  // Array of tileNumbers in order of last moved
  var history = [];

  // Movement map
  function movementMap(position) {
    if (position == 9) return [6, 8];
    if (position == 8) return [5, 7, 9];
    if (position == 7) return [4, 8];
    if (position == 6) return [3, 5, 9];
    if (position == 5) return [2, 4, 6, 8];
    if (position == 4) return [1, 5, 7];
    if (position == 3) return [2, 6];
    if (position == 2) return [1, 3, 5];
    if (position == 1) return [2, 4];
  }

  // Board setup according to the tileMap
  document.querySelector('#shuffle').addEventListener('click', shuffle, true);
  document.querySelector('#solve').addEventListener('click', solve, true);
  var tiles = document.querySelectorAll('.tile');
  var delay = -50;
  for (var i = 0; i < tiles.length; i++) {
    tiles[i].addEventListener('click', tileClicked, true);

    var tileId = tiles[i].innerHTML;
    delay += 50;
    setTimeout(setup, delay, tiles[i]);
  }

  function setup(tile) {
    var tileId = tile.innerHTML;
    // tile.style.left = tileMap[tileId].left + '%';
    // tile.style.top = tileMap[tileId].top + '%';
    var xMovement = parentX * (tileMap[tileId].left / 100);
    var yMovement = parentX * (tileMap[tileId].top / 100);
    var translateString = "translateX(" + xMovement + "px) " + "translateY(" + yMovement + "px)"
    tile.style.webkitTransform = translateString;
    recolorTile(tile, tileId);
  }

  function tileClicked(event) {
    var tileNumber = event.target.innerHTML;
    moveTile(event.target);

    if (checkSolution()) {
      console.log("You win!");
    }
  }

  // Moves tile to empty spot
  // Returns error message if tile cannot be moved
  function moveTile(tile, recordHistory = true) {
    // Check if Tile can be moved 
    // (must be touching empty tile)
    // (must be directly perpendicular to empty tile)
    var tileNumber = tile.innerHTML;
    if (!tileMovable(tileNumber)) {
      console.log("Tile " + tileNumber + " can't be moved.");
      return;
    }

    // Push to history
    if (recordHistory == true) {

      if (history.length >= 3) {
        if (history[history.length - 1] != history[history.length - 3]) history.push(tileNumber);
      } else {
        history.push(tileNumber);
      }
    }

    // Swap tile with empty tile
    var emptyTop = tileMap.empty.top;
    var emptyLeft = tileMap.empty.left;
    var emptyPosition = tileMap.empty.position;
    tileMap.empty.top = tileMap[tileNumber].top;
    tileMap.empty.left = tileMap[tileNumber].left;
    tileMap.empty.position = tileMap[tileNumber].position;

    // tile.style.top = emptyTop  + '%'; 
    // tile.style.left = emptyLeft  + '%';

    var xMovement = parentX * (emptyLeft / 100);
    var yMovement = parentX * (emptyTop / 100);
    var translateString = "translateX(" + xMovement + "px) " + "translateY(" + yMovement + "px)"
    tile.style.webkitTransform = translateString;

    tileMap[tileNumber].top = emptyTop;
    tileMap[tileNumber].left = emptyLeft;
    tileMap[tileNumber].position = emptyPosition;

    recolorTile(tile, tileNumber);
  }


  // Determines whether a given tile can be moved
  function tileMovable(tileNumber) {
    var selectedTile = tileMap[tileNumber];
    var emptyTile = tileMap.empty;
    var movableTiles = movementMap(emptyTile.position);

    if (movableTiles.includes(selectedTile.position)) {
      return true;
    } else {
      return false;
    }



  }

  // Returns true/false based on if the puzzle has been solved
  function checkSolution() {
    if (tileMap.empty.position !== 9) return false;

    for (var key in tileMap) {
      if ((key != 1) && (key != "empty")) {
        if (tileMap[key].position < tileMap[key - 1].position) return false;
      }
    }

    // Clear history if solved
    history = [];
    return true;
  }

  // Check if tile is in correct place!
  function recolorTile(tile, tileId) {
    if (tileId == tileMap[tileId].position) {
      tile.classList.remove("error");
    } else {
      tile.classList.add("error");
    }
  }


  // Shuffles the current tiles
  shuffleTimeouts = [];

  function shuffle() {
    clearTimers(solveTimeouts);
    var boardTiles = document.querySelectorAll('.tile');
    var shuffleDelay = 200;
    shuffleLoop();

    var shuffleCounter = 0;
    while (shuffleCounter < 20) {
      shuffleDelay += 200;
      shuffleTimeouts.push(setTimeout(shuffleLoop, shuffleDelay));
      shuffleCounter++;
    }
  }

  var lastShuffled;

  function shuffleLoop() {
    var emptyPosition = tileMap.empty.position;
    var shuffleTiles = movementMap(emptyPosition);
    var tilePosition = shuffleTiles[Math.floor(Math.floor(Math.random() * shuffleTiles.length))];
    var locatedTile;
    for (var i = 1; i <= 8; i++) {
      if (tileMap[i].position == tilePosition) {
        var locatedTileNumber = tileMap[i].tileNumber;
        locatedTile = tiles[locatedTileNumber - 1];
      }
    }
    if (lastShuffled != locatedTileNumber) {
      moveTile(locatedTile);
      lastShuffled = locatedTileNumber;
    } else {
      shuffleLoop();
    }

  }


  function clearTimers(timeoutArray) {
    for (var i = 0; i < timeoutArray.length; i++) {
      clearTimeout(timeoutArray[i])
    }
  }

  // Temporary function for solving puzzle.
  // To be reimplemented with a more sophisticated algorithm
  solveTimeouts = []

  function solve() {
    clearTimers(shuffleTimeouts);


    repeater = history.length;

    for (var i = 0; i < repeater; i++) {
      console.log("started");
      solveTimeouts.push(setTimeout(moveTile, i * 100, tiles[history.pop() - 1], false));
    }
  }



}
body {
  font-family: 'Roboto Condensed', sans-serif;
  font-weight: 700;
  font-size: 24px;
  background-color: #ECF0F1;
  -webkit-tap-highlight-color: transparent;
  khtml-tap-highlight-color: transparent;
}

.sliding-puzzle-figure {
  margin: auto;
  height: 360px;
  width: 360px;
  padding-bottom: 50vh;
  padding-top: 10vh;
}

.sliding-puzzle-figure a {
  cursor: pointer;
}

.sliding-puzzle-figure a#shuffle {
  color: #E74C3C;
}

.sliding-puzzle-figure a#solve {
  color: #3498DB;
}

.sliding-puzzle-figure .sliding-puzzle {
  list-style-type: none;
  position: relative;
  margin-left: 0;
  margin-right: 00;
  width: 360px;
  height: 360px;
  box-sizing: border-box;
  background-clip: border-box;
  /* Firefox 4, Safari 5, Opera 10, IE 9 */
  border: 18px solid #2C3E50;
  border-radius: 10px;
  background-color: #2C3E50;
}

.sliding-puzzle-figure .sliding-puzzle .tile {
  position: absolute;
  background: url(https://simonwiddowson.typepad.com/files/countryside360x360.jpg);
  border-radius: 2px;
  cursor: pointer;
  width: 120px;
  height: 120px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 0px;
  left: 0%;
  top: 0%;
  transition: all 0.5s linear;
  transition-timing-function: ease;
  box-sizing: border-box;
}

.sliding-puzzle-figure .sliding-puzzle .tile.error {
  background-color: #F0867D;
}

#tile1 {
  background-position: left top;
}

#tile2 {
  background-position: center top;
}

#tile3 {
  background-position: right top;
}

#tile4 {
  background-position: left center;
}

#tile5 {
  background-position: center center;
}

#tile6 {
  background-position: right center;
}

#tile7 {
  background-position: left bottom;
}

#tile8 {
  background-position: center bottom;
}

@media only screen and (max-width: 650px) {
  .sliding-puzzle-figure {
    width: 90vw;
    height: 90vw;
    max-height: 100vh;
  }
  .sliding-puzzle-figure .sliding-puzzle {
    border-width: 10px;
    border-radius: 14px;
  }
  .sliding-puzzle-figure .tile {
    font-size: 1em;
  }
}


/*# sourceMappingURL=style.css.map */
<link href="https://fonts.googleapis.com/css?family=Roboto+Condensed:400,700" rel="stylesheet">


<figure class="sliding-puzzle-figure">

  <div class="sliding-puzzle">
    <div class="tile" id="tile1">1</div>
    <div class="tile" id="tile2">2</div>
    <div class="tile" id="tile3">3</div>
    <div class="tile" id="tile4">4</div>
    <div class="tile" id="tile5">5</div>
    <div class="tile" id="tile6">6</div>
    <div class="tile" id="tile7">7</div>
    <div class="tile" id="tile8">8</div>
  </div>

  <figcaption><br><br> Barry Paling&nbsp; | <a id="shuffle">Shuffle</a> | <a id="solve">Wie ben ik</a>
  </figcaption>
</figure>

最佳答案

您在加载时调用游戏,删除随机播放点击,然后在游戏结束时调用 shuffle() () :

window.addEventListener("load",game);
function game() {
  ...
  shuffle();
}

window.addEventListener("load",game);

function game() {
  // Data structure to hold positions of tiles
  var parentX = document.querySelector(".sliding-puzzle").clientHeight;
  var baseDistance = 38;
  var tileMap = {
    1: {
      tileNumber: 1,
      position: 1,
      top: 0,
      left: 0
    },
    2: {
      tileNumber: 2,
      position: 2,
      top: 0,
      left: baseDistance * 1
    },
    3: {
      tileNumber: 3,
      position: 3,
      top: 0,
      left: baseDistance * 2
    },
    4: {
      tileNumber: 4,
      position: 4,
      top: baseDistance,
      left: 0
    },
    5: {
      tileNumber: 5,
      position: 5,
      top: baseDistance,
      left: baseDistance
    },
    6: {
      tileNumber: 6,
      position: 6,
      top: baseDistance,
      left: baseDistance * 2
    },
    7: {
      tileNumber: 7,
      position: 7,
      top: baseDistance * 2,
      left: 0
    },
    8: {
      tileNumber: 8,
      position: 8,
      top: baseDistance * 2,
      left: baseDistance
    },
    empty: {
      position: 9,
      top: baseDistance * 2,
      left: baseDistance * 2
    }
  }

  // Array of tileNumbers in order of last moved
  var history = [];

  // Movement map
  function movementMap(position) {
    if (position == 9) return [6, 8];
    if (position == 8) return [5, 7, 9];
    if (position == 7) return [4, 8];
    if (position == 6) return [3, 5, 9];
    if (position == 5) return [2, 4, 6, 8];
    if (position == 4) return [1, 5, 7];
    if (position == 3) return [2, 6];
    if (position == 2) return [1, 3, 5];
    if (position == 1) return [2, 4];
  }

  // Board setup according to the tileMap
  document.querySelector('#solve').addEventListener('click', solve, true);
  var tiles = document.querySelectorAll('.tile');
  var delay = -50;
  for (var i = 0; i < tiles.length; i++) {
    tiles[i].addEventListener('click', tileClicked, true);

    var tileId = tiles[i].innerHTML;
    delay += 50;
    setTimeout(setup, delay, tiles[i]);
  }

  function setup(tile) {
    var tileId = tile.innerHTML;
    // tile.style.left = tileMap[tileId].left + '%';
    // tile.style.top = tileMap[tileId].top + '%';
    var xMovement = parentX * (tileMap[tileId].left / 100);
    var yMovement = parentX * (tileMap[tileId].top / 100);
    var translateString = "translateX(" + xMovement + "px) " + "translateY(" + yMovement + "px)"
    tile.style.webkitTransform = translateString;
    recolorTile(tile, tileId);
  }

  function tileClicked(event) {
    var tileNumber = event.target.innerHTML;
    moveTile(event.target);

    if (checkSolution()) {
      console.log("You win!");
    }
  }

  // Moves tile to empty spot
  // Returns error message if tile cannot be moved
  function moveTile(tile, recordHistory = true) {
    // Check if Tile can be moved 
    // (must be touching empty tile)
    // (must be directly perpendicular to empty tile)
    var tileNumber = tile.innerHTML;
    if (!tileMovable(tileNumber)) {
      console.log("Tile " + tileNumber + " can't be moved.");
      return;
    }

    // Push to history
    if (recordHistory == true) {

      if (history.length >= 3) {
        if (history[history.length - 1] != history[history.length - 3]) history.push(tileNumber);
      } else {
        history.push(tileNumber);
      }
    }

    // Swap tile with empty tile
    var emptyTop = tileMap.empty.top;
    var emptyLeft = tileMap.empty.left;
    var emptyPosition = tileMap.empty.position;
    tileMap.empty.top = tileMap[tileNumber].top;
    tileMap.empty.left = tileMap[tileNumber].left;
    tileMap.empty.position = tileMap[tileNumber].position;

    // tile.style.top = emptyTop  + '%'; 
    // tile.style.left = emptyLeft  + '%';

    var xMovement = parentX * (emptyLeft / 100);
    var yMovement = parentX * (emptyTop / 100);
    var translateString = "translateX(" + xMovement + "px) " + "translateY(" + yMovement + "px)"
    tile.style.webkitTransform = translateString;

    tileMap[tileNumber].top = emptyTop;
    tileMap[tileNumber].left = emptyLeft;
    tileMap[tileNumber].position = emptyPosition;

    recolorTile(tile, tileNumber);
  }


  // Determines whether a given tile can be moved
  function tileMovable(tileNumber) {
    var selectedTile = tileMap[tileNumber];
    var emptyTile = tileMap.empty;
    var movableTiles = movementMap(emptyTile.position);

    if (movableTiles.includes(selectedTile.position)) {
      return true;
    } else {
      return false;
    }



  }

  // Returns true/false based on if the puzzle has been solved
  function checkSolution() {
    if (tileMap.empty.position !== 9) return false;

    for (var key in tileMap) {
      if ((key != 1) && (key != "empty")) {
        if (tileMap[key].position < tileMap[key - 1].position) return false;
      }
    }

    // Clear history if solved
    history = [];
    return true;
  }

  // Check if tile is in correct place!
  function recolorTile(tile, tileId) {
    if (tileId == tileMap[tileId].position) {
      tile.classList.remove("error");
    } else {
      tile.classList.add("error");
    }
  }


  // Shuffles the current tiles
  shuffleTimeouts = [];

  function shuffle() {
    clearTimers(solveTimeouts);
    var boardTiles = document.querySelectorAll('.tile');
    var shuffleDelay = 200;
    shuffleLoop();

    var shuffleCounter = 0;
    while (shuffleCounter < 20) {
      shuffleDelay += 200;
      shuffleTimeouts.push(setTimeout(shuffleLoop, shuffleDelay));
      shuffleCounter++;
    }
  }

  var lastShuffled;

  function shuffleLoop() {
    var emptyPosition = tileMap.empty.position;
    var shuffleTiles = movementMap(emptyPosition);
    var tilePosition = shuffleTiles[Math.floor(Math.floor(Math.random() * shuffleTiles.length))];
    var locatedTile;
    for (var i = 1; i <= 8; i++) {
      if (tileMap[i].position == tilePosition) {
        var locatedTileNumber = tileMap[i].tileNumber;
        locatedTile = tiles[locatedTileNumber - 1];
      }
    }
    if (lastShuffled != locatedTileNumber) {
      moveTile(locatedTile);
      lastShuffled = locatedTileNumber;
    } else {
      shuffleLoop();
    }

  }


  function clearTimers(timeoutArray) {
    for (var i = 0; i < timeoutArray.length; i++) {
      clearTimeout(timeoutArray[i])
    }
  }

  // Temporary function for solving puzzle.
  // To be reimplemented with a more sophisticated algorithm
  solveTimeouts = []

  function solve() {
    clearTimers(shuffleTimeouts);


    repeater = history.length;

    for (var i = 0; i < repeater; i++) {
      solveTimeouts.push(setTimeout(moveTile, i * 100, tiles[history.pop() - 1], false));
    }
  }
  shuffle()  
}
body {
  font-family: 'Roboto Condensed', sans-serif;
  font-weight: 700;
  font-size: 24px;
  background-color: #ECF0F1;
  -webkit-tap-highlight-color: transparent;
  khtml-tap-highlight-color: transparent;
}

.sliding-puzzle-figure {
  margin: auto;
  height: 360px;
  width: 360px;
  padding-bottom: 50vh;
  padding-top: 10vh;
}

.sliding-puzzle-figure a {
  cursor: pointer;
}

.sliding-puzzle-figure a#shuffle {
  color: #E74C3C;
}

.sliding-puzzle-figure a#solve {
  color: #3498DB;
}

.sliding-puzzle-figure .sliding-puzzle {
  list-style-type: none;
  position: relative;
  margin-left: 0;
  margin-right: 00;
  width: 360px;
  height: 360px;
  box-sizing: border-box;
  background-clip: border-box;
  /* Firefox 4, Safari 5, Opera 10, IE 9 */
  border: 18px solid #2C3E50;
  border-radius: 10px;
  background-color: #2C3E50;
}

.sliding-puzzle-figure .sliding-puzzle .tile {
  position: absolute;
  background: url(https://simonwiddowson.typepad.com/files/countryside360x360.jpg);
  border-radius: 2px;
  cursor: pointer;
  width: 120px;
  height: 120px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 0px;
  left: 0%;
  top: 0%;
  transition: all 0.5s linear;
  transition-timing-function: ease;
  box-sizing: border-box;
}

.sliding-puzzle-figure .sliding-puzzle .tile.error {
  background-color: #F0867D;
}

#tile1 {
  background-position: left top;
}

#tile2 {
  background-position: center top;
}

#tile3 {
  background-position: right top;
}

#tile4 {
  background-position: left center;
}

#tile5 {
  background-position: center center;
}

#tile6 {
  background-position: right center;
}

#tile7 {
  background-position: left bottom;
}

#tile8 {
  background-position: center bottom;
}

@media only screen and (max-width: 650px) {
  .sliding-puzzle-figure {
    width: 90vw;
    height: 90vw;
    max-height: 100vh;
  }
  .sliding-puzzle-figure .sliding-puzzle {
    border-width: 10px;
    border-radius: 14px;
  }
  .sliding-puzzle-figure .tile {
    font-size: 1em;
  }
}


/*# sourceMappingURL=style.css.map */
<link href="https://fonts.googleapis.com/css?family=Roboto+Condensed:400,700" rel="stylesheet">

<figure class="sliding-puzzle-figure">

  <div class="sliding-puzzle">
    <div class="tile" id="tile1">1</div>
    <div class="tile" id="tile2">2</div>
    <div class="tile" id="tile3">3</div>
    <div class="tile" id="tile4">4</div>
    <div class="tile" id="tile5">5</div>
    <div class="tile" id="tile6">6</div>
    <div class="tile" id="tile7">7</div>
    <div class="tile" id="tile8">8</div>
  </div>

  <figcaption><br><br> Barry Paling&nbsp; |  <a id="solve">Wie ben ik</a>
  </figcaption>
</figure>

关于javascript - 如何让这个图片 slider 拼图开始洗牌而无需按下按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64663198/

相关文章:

javascript - 计算百分比,有没有更优化的方法?

javascript - 指定路径的 Cookie 不是通过 javascript 设置的

javascript - 检查 Set 是否包含 Javascript 中的列表

javascript - 计算 javascript 中的百分比变化

javascript - 旋转整个谷歌图表

javascript - azure-mobile-apps-node 中的错误中间件

javascript - 如何将 Backbone 模型用于多个 View (在多个文件中)?

javascript - 如何让 VS Code 识别返回 React 的 HTML 语法

javascript - RxJs 重复事件链

javascript - 如何将 ViolentMokey userScript 制作成浏览器扩展?