Strona główna » Po Godzinach » Gry » Puzzle - Kod źródłowy
 

Puzzle - Kod źródłowy

· Gra · Kod źródłowy ·

Wstęp

Gra Puzzle została napisana przy wykorzystaniu języka JavaScript. Kod nie wymaga żadnych zewnętrznych bibliotek, aby działać. Widoczna plansza to obiekty HTML, a nad ułożeniem wszystkiego na stronie czuwa CSS.

Implementacja

Zmienne globalne

Skrypt korzysta z trzech zmiennych globalnych. Pierwsza z nich obj_clicked przechowuje informacje o aktualnie wybranym polu. Następna maxn określa maksymalną ilość elementów w pojedynczym wierszu. Ostatnia last_url przechowuje informacje o ścieżce dostępu do wyświetlanego obrazku.

  1. var obj_clicked = null;
  2. var maxn = 5;
  3. var last_url = 'http://mattomatti.com/PGES/g17/img00.jpg';

W celu zmiany wartości zmiennej maxn należy posłużyć się funkcją setMaxn() i przekazać jej jako paramatr nową wartość zmiennej. Funkcja wymusi zrestartowanie gry.

  1. function setMaxn(data){
  2.  maxn = data;
  3.  restartGame();
  4. }

Restartowanie gry polega na utworzeniu nowej gry. Jako parametr url należy podać zmienną last_url. W ten sposób nowa gra będzie miała te same ustawienia co poprzednia.

  1. function restartGame(){
  2.  createGame(last_url);
  3. }

Pole gry

Plansza do gry są to obiekty div, które mają ten sam rozmiar. Różnica tkwi jednak w sposobie wyświetlania tła. Mianowicie każdy obiekt w zależności od pozycji ma obliczony wektor przesunięcia lewego górnego rogu obrazku tła. Każdy obiekt jest klasy game_el, która odpowiada za ustalenie rozmiaru pól oraz ich wstępnego sformatowania. Dodatkowo każde pole ma argument pos, który określa gdzie powinno znajdować się dane pole.

Do tworzenia pól wykorzystywana jest funkcja pomocnicza getElement(), która na podstawie rozmiaru size, pozycji x i y oraz numeru pozycji początkowej pos tworzy odpowiedni obiekt div.

  1. function getElement(size,x,y,pos){
  2.  return '<div class="game_el" pos="'+pos+'" onclick="on_click(this);" style="background-position:-'+(x*size)+'px -'+(y*size)+'px"></div>';
  3. }

Przygotowanie planszy

Program pozwala na załadowanie obrazka z dowolnego źródła. Funkcja createGame() przyjmuje jeden argument url, który określa źródło pliku.

  1. function createGame(url) {
  2.  last_url = url;
  3.  var img = document.createElement("img");
  4.  img.src = url;
  5.  img.onload = function() {
  6.   var obj_game = document.getElementById("game");
  7.   var size = getSize(this.width, this.height, 700, 500);
  8.   var docw = size*(Math.floor(700/size));
  9.   var doch = size*(Math.floor(500/size));
  10.   obj_game.innerHTML = getStyle(size,url,docw,doch);
  11.   var i = 0;
  12.   for(var y = 0; (y + 1) * size <= doch; y++) {
  13.    for(var x = 0; (x + 1) * size <= docw; x++) {
  14.     obj_game.innerHTML += getElement(size,x,y,i++);
  15.    }
  16.    obj_game.innerHTML += '<div style="clear:both"></div>';
  17.   }
  18.   randomList(document.getElementsByClassName("game_el"));
  19.   checkWin();
  20.  }
  21. }

(2.) Zapamiętaj wczytany url. (3.) Utwórz wirtualny obiekt img i (4.) załaduj obrazek. (5.) Po załadowaniu: (6.) znajdź pole gry, (7.) ustal rozmiar pól i oblicz (8.) szerokość oraz (9.) wysokość dokumentu wyjściowego. (10.) Na podstawie wyliczonych wartości pobierz styl planszy przy pomocy funkcji getStyle(). Następnie (11. - 17.) utwórz docw·doch pól i (18.) wymieszaj kolejność. (19.) Niestety losowość może zwrócić ustawienie początkowe, dlatego warto sprawdzić w funkcji tworzącej czy gra nie została zakończona.

Styl rozgrywki

Funkcja getStyle() na podstawie rozmiaru pól size, adresu obrazka url oraz maskymalnych rozmiarów planszy, aby gra się zmieściła w przygotowanej przestrzeni zwraca styl pól: rozmiar, obrazek tła, marginesy oraz sposób ustawienia.

  1. function getStyle(size,url,maxsizew,maxsizeh){
  2.  return '<style>.game_el{width:'+size+'px; height:'+size+'px; background-size: '+maxsizew+'px '+maxsizeh+'px; background-repeat: no-repeat; background-image: url('+url+'); float: left; margin: 1px; border-width: 1px; border-style: outset} .btn{padding: 4px; line-height: 36px; border: 1px solid black; border-radius: 8px; text-decoration: none} .btn:hover{color: black}</style>';
  3. }

Rozmiar pól

Rozmiar pól jest określany na podstawie wysokości obrazka, a maksymalną szerokości i wysokością dokumentu docelowego. Ma to na celu możliwość załadowania obrazku dowolnego rozmiaru. Rozmiar ten jest wyliczany na podstawie poniższego algorytmu:

  1. function getSize(a,b,ma,mb){
  2.  if(mb > ma)
  3.   return getSize(mb,ma);
  4.  var sa = a / ma;
  5.  var sb = b / mb;
  6.  return (sa > sb) ? ma/maxn : mb/maxn;
  7. }

Zamiana pól

Zamiana pól polega na wskazaniu dwóch elementów el1 i el2, a następnie zamienieniu atrybutu dotyczącego ustawień tła oraz atrybutu pos.

  1. function swapElements(el1,el2){
  2.  var temp = el1.style.backgroundPosition;
  3.  el1.style.backgroundPosition = el2.style.backgroundPosition;
  4.  el2.style.backgroundPosition = temp;
  5.  temp = el1.getAttribute("pos");
  6.  el1.setAttribute("pos", el2.getAttribute("pos"));
  7.  el2.setAttribute("pos", temp);
  8. }

Losowanie rozmieszczanie

W celu losowego rozmieszczenia wystarczy zamienić i-ty element z dowolnym z listy, a następnie zmniejszać rozmiar listy o 1.

  1. function randomList(el) {
  2.  for(var i = 0; i + 1 < el.length; i++)
  3.   swapElements(el[i], el[Math.floor(Math.random() * el.length)]);
  4. }

Zamiana na kliknięcie

W celu zamiany dwóch wybranych pól należy sprawdzić czy zostało już wybrane pole. Jeśli nie to zapamiętujemy wybrane pole. Jeśli jest już wybrane pole to sprawdzamy czy wybrane pola są różne i dokonujemy zamiany przy pomocy funkcji swapElements() i sprawdzamy czy gra została zakończona. Warto zauważyć, że niezależnie od dokonania zamiany elementów wartość obj_clicked jest ustawiana na null. Pozwala to na odkliknięcie pola poprzez ponowne jego kliknięcie.

  1. function on_click(el) {
  2.  if(obj_clicked == null) {
  3.   obj_clicked = el;
  4.  } else {
  5.   if(el != obj_clicked) {
  6.    swapElements(el, obj_clicked);
  7.    checkWin();
  8.   }
  9.   obj_clicked = null;
  10.  }
  11. }

Warunek zwycięstwa

Warunek zwycięstwa jest bardzo prosty do sprawdzenia. Nalezy pobrać wszystkie elementy leżące na planszy, a następnie sprawdzeniu czy i-te pole ma argument o wartości i. Jeśli pętla nie zostanie przerwana to wystarczy np. pokazać komunikat.

  1. function checkWin() {
  2.  var obj_status = document.getElementById("game_status");
  3.  var children = document.getElementsByClassName("game_el");
  4.  for(var i = 0; i < children.length; i++){
  5.   if(children[i].getAttribute("pos") != "" + i) {
  6.    obj_status.innerHTML = "";
  7.    return;
  8.   }
  9.  }
  10.  obj_status.innerHTML = "<p><b>Gra została zakończona!</b></p>";
  11. }