javascript - 如何在不按下按钮的情况下让这个图片滑块拼图开始洗牌?
问题描述
Goodday Coders,我正在为这个拼图脚本而苦苦挣扎,我想将它用于网站的“与团队会面”页面。
我希望拼图在页面加载时打乱,而不必按下随机播放按钮。如果人们按下“Wie ben ik”按钮,谜题应该会解决,就像现在一样。
不知怎的,我无法让它工作,如果有人可以帮助我,那就太好了。
这是codepen链接:
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 | <a id="shuffle">Shuffle</a> | <a id="solve">Wie ben ik</a>
</figcaption>
</figure>
解决方案
您在加载时调用游戏,删除 shuffle 点击,然后在 game() 结束时调用 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 | <a id="solve">Wie ben ik</a>
</figcaption>
</figure>
推荐阅读
- python - 如何在 python 中将字符串数据帧转换为 csv?
- pip - 无法安装最新版本的python包
- c++ - C++:声明一个在头文件中返回字符串的函数?
- angular-material - 如何在 mat-grid-tile-footer 中居中对齐按钮
- php - 用 '!' 传递参数 用 bash
- c++ - 将文件中的多个输入分成偶数或奇数
- c++ - C++ std::string::compare() 与字符串上的运算符之间的不一致
- jquery - Ajax 调用不调用服务器 Laravel
- node.js - 尝试创建角度组件时出错
- python - 使用 LDA 的主题建模(Denisim)可视化