1. 程式人生 > >html+css+js實現網頁拼圖遊戲

html+css+js實現網頁拼圖遊戲

拒絕 ini 定位 start 每次 網頁 global append 打亂數組

代碼地址如下:
http://www.demodashi.com/demo/14449.html

項目描述

使用 html+js+css 實現一個網頁拼圖遊戲,可支持簡單,中等,困難三種難度。

演示效果

技術分享圖片

在瀏覽器直接打開網頁即可運行,有三種難度可以選擇, 完成拼圖會顯示所用的時間和步數。

項目結構

Puzzle
├── chilian.jpg
├── fifteen.css
├── fifteen.html
└── fifteen.js

文件夾中只有四個文件,拼圖所用的原圖以及3個代碼文件。

項目實現

1. 顯示拼圖

拼圖的大小是4x4,總共16格,其中有一格是空的,用於移動。html的主體代碼如下,拼圖區域只需要使用一個div,後續再在js裏使用循環構建16個小方塊

<body>
   <h1>拼圖遊戲</h1>
   <div id="statu">
      <img src="chilian.jpg" id="smallPic"><br/>
      <label>時間: </label><span id="time">00:00</span>
      <label>步數: </label><span id="step">0</span><br/>
      <select>
        <option selected="selected" value="1">簡單模式</option>
        <option value="2">中等模式</option>
        <option value="3">困難模式</option>
     </select>
   </div>
   <div id="fifteen"></div>
   <button id="restart">重新開始</button>
</body>

使用js創建小方塊後再插入到fifteen的div中,先將16個存在DocumentFragment中, 最後再一次性添加到html中,頁面只需渲染一次, 提高性能

// 創建 4x4 的拼圖
function createPuzzle() {
      // 先將16個小div存在DocumentFragment, 頁面只需渲染一次, 提高性能
      var frag = document.createDocumentFragment();
      for (var i = 1; i <= 4; ++i) {
            for (var j = 1; j <= 4; ++j) {
                  if (i == 4 && j == 4) {
                        var empty = document.createElement("div");
                        empty.setAttribute('id', 'empty');
                        empty.setAttribute('class', 'row4 col4');
                        frag.appendChild(empty);
                        break;
                  }
                  var pic = document.createElement("div");
                  pic.setAttribute("id", "pic" + ((i - 1) * 4 + j));
                  pic.setAttribute("class", "row" + i + " col" + j);
                  frag.appendChild(pic);
            }
      }
      document.getElementById("fifteen").appendChild(frag);
}

最後生成小方塊的html如下:

<div id="fifteen">
      <div id="pic1" class="row1 col1"></div>
      <div id="pic2" class="row1 col2"></div>
      <div id="pic3" class="row1 col3"></div>
      <div id="pic4" class="row1 col4"></div>
      <div id="pic5" class="row2 col1"></div>
      <div id="pic6" class="row2 col2"></div>
      <div id="pic7" class="row2 col3"></div>
      <div id="pic8" class="row2 col4"></div>
      <div id="pic9" class="row3 col1"></div>
      <div id="pic10" class="row3 col2"></div>
      <div id="pic11" class="row3 col3"></div>
      <div id="pic12" class="row3 col4"></div>
      <div id="pic13" class="row4 col1"></div>
      <div id="pic14" class="row4 col2"></div>
      <div id="pic15" class="row4 col3"></div>
      <div id="empty" class="row4 col4"></div>
</div>

有個小方塊之後,怎樣每格顯示不同的圖片,有一種方法是可以將大圖片等分切割成16張小圖篇,但這種方法很麻煩,需要切圖,而且代碼文件夾裏就需要使用到16張圖片,這裏使用css實現切圖,所有的小圖都是同一張圖片,不需要切割。
因為使用到的圖片大小是352x352,所以16等分後是88x88,將小方塊的大小設置為86x86,每張小圖間剛好多出一條2px的間隔,不會顯得太緊湊。每個小方塊使用絕對定位,背景圖片都是大圖,通過設置每個方塊的背景圖片偏移量,顯示出一副完整的圖片。

#fifteen div{
   width: 86px;
   height: 86px;
   border: 1px solid #CCCCCC;
   margin: 1px;
   background-image: url(chilian.jpg);
   background-repeat: no-repeat;
   position: absolute;
   -webkit-transition: all 0.4s;
   -moz-transition: all 0.4s;
   -ms-transition: all 0.4s;
   -o-transition: all 0.4s;
   transition: all 0.4s;
}

.row1 {top: 0px;}
.row2 {top: 88px;}
.row3 {top: 176px;}
.row4 {top: 264px;}
.col1 {left: 0px;}
.col2 {left: 88px;}
.col3 {left: 176px;}
.col4 {left: 264px;}

#pic1 {background-position: -0px 0px;}
#pic2 {background-position: -88px 0px;}
#pic3 {background-position: -176px 0px;}
#pic4 {background-position: -264px 0px;}
#pic5 {background-position: 0px -88px;}
#pic6 {background-position: -88px -88px;}
#pic7 {background-position: -176px -88px;}
#pic8 {background-position: -264px -88px;}
#pic9 {background-position: 0px -176px;}
#pic10 {background-position: -88px -176px;}
#pic11 {background-position: -176px -176px;}
#pic12 {background-position: -264px -176px;}
#pic13 {background-position: 0px -264px;}
#pic14 {background-position: -88px -264px;}
#pic15 {background-position: -176px -264px;}
#fifteen #empty {border: none; background: none;}

2. 打亂拼圖

在生成打亂的拼圖時,隨機打亂的拼圖不一定可以還原,可能會出現無解的情況,有一種打亂的方法可以確保生成的拼圖永遠有解:每次交換3張圖片的位置, 最後的拼圖一定是可還原的,比如將ABC三張圖的位置交換為BCA,這算一次交換,可以選擇任意三張圖,交換任意次,最後生成的拼圖肯定都是有解可還原的。
在打亂拼圖的時候,分別打亂右下角的3張,8張,以及全部15張圖片,可以生成不同難度的拼圖,增加趣味性。

// 初始化圖片位置, 3 種不同難度
function initPos(difficulty) {
      var arr = [];
      if (difficulty == 1)
            arr = [10, 11, 14];
      else if (difficulty == 2)
            arr = [5, 6, 7, 9, 10, 11, 13, 14];
      else arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];

      // 隨機打亂數組
      arr.sort(function () {
            return Math.random() - 0.5;
      });

      // 每次交換3張圖片的位置, 最後的拼圖一定是可還原的
      // 難度越大, 交換的圖片數越多
      for (i = 0; i < difficulty * 3; i += 3) {
            var temp = global.pics[arr[i]].className;
            global.pics[arr[i]].className = global.pics[arr[i + 1]].className;
            global.pics[arr[i + 1]].className = global.pics[arr[i + 2]].className;
            global.pics[arr[i + 2]].className = temp;
      }
}

移動拼圖

只有點擊空白格相鄰的圖片才能進行移動,移動的時候,將點擊圖片的class和空白格的class進行交換,因為不同的class背景圖片不同,而且css中添加了動畫效果,因此交換class後頁面上看起來就是圖片發生了移動。

判斷拼圖是否完成時只有判斷每個div的class是否與一開始的對應,如果全部相同證明每張圖片都回到了起始位置,拼圖完成。

global.pics[i].onclick = function () {
        if (!global.start)  // 未開始遊戲, 不移動
                return;
        var clickPos = this.className.match(/[0-9]/g); // 被點擊的圖片坐標
        var emptyPos = empty.className.match(/[0-9]/g); // 空白格的坐標
        // 如果點擊圖片的坐標合法, 與空白格相鄰,和空白格交換
        if (isValid(clickPos, emptyPos)) {
            var temp = this.className;
            this.className = empty.className;
            global.empty.className = temp;
            ++global.step.innerHTML;
            // 判斷是否完成拼圖
            if (isDone())
                    success();
        }
    };

其他說明

完整實現請下載代碼,註釋清晰,推薦使用谷歌瀏覽器或火狐瀏覽器打開,有問題可以評論或聯系我html+css+js實現網頁拼圖遊戲

代碼地址如下:
http://www.demodashi.com/demo/14449.html

註:本文著作權歸作者,由demo大師代發,拒絕轉載,轉載需要作者授權

html+css+js實現網頁拼圖遊戲