Zum Rätsel springen
Neulich kam mir eine Erinnerung an ein kleines Puzzlespielzeug aus meiner Kindheit in den Sinn, ein Schiebepuzzle, bei dem 15 quadratische Kacheln in einem Rahmen in einer 4 x 4-Anordnung von Zellen angeordnet sind, so dass ein freier Platz bleibt. Eine Reihe von Rippen und Rillen an den Kanten jeder Fliese und des Rahmens ermöglichen, dass die Fliesen aneinander vorbeigleiten und gleichzeitig die Fliesen im Rahmen halten. Zu jedem beliebigen Zeitpunkt kann jedes an das freie Feld angrenzende Plättchen in dieses Feld verschoben werden, andernfalls wird die Bewegung der Plättchen verhindert. Durch das Verschieben eines Plättchens in das freie Feld entsteht dort, wo das Plättchen herkam, ein neues freies Feld, und ein anderes Plättchen kann dann in dieses neue Feld verschoben werden. Die Idee besteht darin, durch wiederholtes Verschieben der Kacheln auf diese Weise die Kacheln in einer vorgegebenen Reihenfolge anzuordnen.
Anscheinend nennt man das „15er-Puzzle“ und es gibt es schon seit den 1870er Jahren. Beim Durchsuchen des Webs werden eine Reihe von Nachbildungen gefunden, die in verschiedenen Programmiersprachen geschrieben wurden, und tatsächlich gibt es hier auf dev.to mehrere Artikel, darunter https://dev.to/artydev/let-us-code-a-sliding-puzzle-9n , https://dev.to/xzanderzone/making-a-slider-puzzle-in-java-script-83m und https://dev.to/claurcia/slide-puzzle-5c55, alle in JavaScript und https:/ /dev.to/mfbmina/building-a-sliding-puzzle-with-go-3bnj in Go. Es stellt auch eine gute Einstiegsherausforderung für diejenigen dar, die JavaScript lernen.
Was mein Interesse jedoch geweckt hat, war die Idee, dass es im Web ganz ohne Programmiersprache nachbildbar sein sollte! Das heißt, eine Implementierung, die nur reines HTML und CSS verwendet. Deshalb stelle ich es unten vor. Der einzige Kompromiss, den ich eingehen musste, war, dass die 10 bereitgestellten Spiele feste, vorab gemischte Startpositionen haben.
Dafür ist die vorgegebene Reihenfolge, ein fertiges Bild zu zeigen.
Das Grundprinzip dieser Implementierung besteht darin, dass jede Kachel einen Zustandsdatensatz darüber speichert, wo sie sich innerhalb des Rahmens befindet. Es gibt nicht viele Möglichkeiten, den Status in HTML und CSS zu ändern und beizubehalten, aber die häufigste ist der „Checkbox-Hack“, und diese Implementierung nutzt ihn intensiv. Für alle, die mit dem Checkbox-Hack nicht vertraut sind: Wenn ein
Jede Kachel verfügt also über ein Paar Optionsfeldgruppen mit jeweils vier Optionsfeldern. Eine dieser Gruppen behält die Position der Kachel auf der X-Achse und die andere ihre Position auf der Y-Achse. (Oder horizontale bzw. vertikale Position, wenn Sie möchten.) Den fünfzehn Kacheln wird zunächst über ihre Optionsfelder eine andere Kombination aus X- und Y-Koordinaten zugewiesen, sodass jede Kachel eine andere Zelle im Rahmen einnimmt.
Die Kacheln werden zunächst in der oberen, linken Zelle des Rahmens platziert und dann innerhalb des Rahmens verschoben, indem CSS den Zustand der Optionsfelder misst, indem eine Übersetzungstransformation auf sie angewendet wird:
/* "X" refers to the X-axis cell positions, "Y" to the Y-axis cell positions. * 0, 1, 2, 3 refers to the position on that axis, * 0 = left and top, 3 = right and bottom respectively. */ .tile:has(.X0:checked~.Y0:checked) { transform: translate(0%, 0%); } .tile:has(.X0:checked~.Y1:checked) { transform: translate(0%, 100%); } .tile:has(.X0:checked~.Y2:checked) { transform: translate(0%, 200%); } .tile:has(.X0:checked~.Y3:checked) { transform: translate(0%, 300%); } .tile:has(.X1:checked~.Y0:checked) { transform: translate(100%, 0%); } /* and so on for the remainder of the sixteen combinations */
Die Kachel enthält dann auch acht Beschriftungselemente, entsprechend den acht Optionsfeldern. Jedes Etikett liegt absolut übereinander und füllt die Kachel vollständig aus. Die Beschriftungen sind transparent und zunächst so eingerichtet, dass sie nicht auf Klicks und Tippen reagieren, indem für alle Zeigerereignisse festgelegt werden: keine.
Der nächste Schritt besteht darin, dass die CSS-Selektoren identifizieren, wo sich die leere Zelle befindet. Dies erfolgt durch Eliminierung. Es handelt sich um die Zelle, deren X- und Y-Koordinaten nicht durch das Optionsfeldgruppenpaar einer der fünfzehn Kacheln dargestellt werden.
Zum Beispiel, wenn dies zutrifft:
.frame:not(:has(.tile .X0:checked~.Y0:checked)) { .... }
Dann muss sich die leere Zelle derzeit in der oberen linken Eckzelle befinden. Wiederholen Sie dies für jede der sechzehn Zellen und genau eine davon wird übereinstimmen.
Sobald dies erledigt ist, können die Zellen neben der leeren Zelle identifiziert werden. Befindet sich die leere Zelle in einer Ecke, können genau zwei Kacheln in diese Zelle verschoben werden. Wenn sich die leere Zelle andernfalls an einer der Seiten des Rahmens befindet, können drei Kacheln in die Zelle verschoben werden, andernfalls die leere Die Zelle muss eine der vier mittleren Zellen sein und es gibt vier Kacheln, die dorthin verschoben werden können. Für jede dieser Kacheln aktiviert genau eine der acht Beschriftungen der Kacheln das richtige Optionsfeld, das zum Verschieben der Kachel in die leere Zelle erforderlich ist. Diese Bezeichnung wird aktiviert, indem der Wert von itspointer-events wieder auf auto gesetzt wird. Also als Beispiele:
/* Top, left corner */ .frame:not(:has(.tile .X0:checked ~ .Y0:checked)) { :is( .tile:has(.X0:checked ~ .Y1:checked) label.Y0, .tile:has(.X1:checked ~ .Y0:checked) label.X0 ) { pointer-events: auto; } } /* right most cell of row two */ .frame:not(:has(.tile .X1:checked ~ .Y3:checked)) { :is( .tile:has(.X1:checked ~ .Y2:checked) label.Y3, .tile:has(.X0:checked ~ .Y3:checked) label.X1, .tile:has(.X2:checked ~ .Y3:checked) label.X1 ) { pointer-events: auto; } } /* second cell from left on row three */ .frame:not(:has(.tile .X2:checked ~ .Y1:checked)) { :is( .tile:has(.X2:checked ~ .Y0:checked) label.Y1, .tile:has(.X2:checked ~ .Y2:checked) label.Y1, .tile:has(.X1:checked ~ .Y1:checked) label.X2, .tile:has(.X3:checked ~ .Y1:checked) label.X2 ) { pointer-events: auto; } }
The last step of the game is to identify when the puzzle is solved. This is simply a case of checking that the 15 tiles all have their expected X and Y axis radio buttons set to their "solved" position.
/* Each tile is assigned a letter "a" to "o". * The puzzle is solved when the tiles are in alphabetical order * reading left to right and top to bottom */ .frame:has(.a .X0:checked ~ .Y0:checked):has(.b .X1:checked ~ .Y0:checked):has( .c .X2:checked ~ .Y0:checked ):has(.d .X3:checked ~ .Y0:checked):has(.e .X0:checked ~ .Y1:checked):has( .f .X1:checked ~ .Y1:checked ):has(.g .X2:checked ~ .Y1:checked):has(.h .X3:checked ~ .Y1:checked):has( .i .X0:checked ~ .Y2:checked ):has(.j .X1:checked ~ .Y2:checked):has(.k .X2:checked ~ .Y2:checked):has( .l .X3:checked ~ .Y2:checked ):has(.m .X0:checked ~ .Y3:checked):has(.n .X1:checked ~ .Y3:checked):has( .o .X2:checked ~ .Y3:checked ) ~ .options .success { display: block; }
The rest is cosmetic. The sliding is done with a simple transition of the transform described above
.tile { transition: 0.5s transform; @media (prefers-reduced-motion) { transition: none; } }
and each tile shows a portion of the game's image using background-size and background-position
.tile { background-size: 400%; } #board1 .tile { background-image: url("https://alohci.net/image/dev.to/slidergame/mullermarc-k7bQqdUf954-unsplash.webp"); } .a { background-position: 0% 0%; } .b { background-position: 33.333% 0%; } .c { background-position: 66.667% 0%; } .d { background-position: 100% 0%; } .e { background-position: 0% 33.333%; } /* and so on for the remaining tiles */
and there's a single set of radio buttons to choose which of the ten games to play.
To play the game, simply click or tap on the tile you want to slide to the empty cell.
I've also provided a "barebones" mode to show the tile letters and radio buttons which might help with the understanding of how the HTML and CSS works.
So here's the completed puzzle game. Please let me know any feedback you have.
Das obige ist der detaillierte Inhalt von„Puzzle'-Slider-Spiel in HTML und CSS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!