拼圖遊戲

學習前端也有一段時間了,今天做一個前端的綜合小遊戲–拼圖遊戲。
首先展示下已完成的效果圖:
在這裏插入圖片描述

下方有兩個按鈕,分別是用於選擇本地圖片和打亂圖片開始遊戲。
這裏給出可體驗的網址:拼圖遊戲
開始正式寫代碼之前,首先得明白此案例需要實現哪些功能。
需要實現的功能:

  1. 兩個按鈕的功能
  2. 鼠標拖拽的功能
  3. 拖拽後可以交換的功能
  4. 檢驗是否成功完成遊戲的功能

明確了需要實現的功能代碼實現就簡單多了。
HTML代碼:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="puzzle.css">
</head>

<body>
    <table>
        <tr>
            <td>
                <!-- 便於拖拽 -->
                <div id="f-1">
                    <div class="picture" id="z-1"></div>
                </div>
            </td>
            <td>
                <div id="f-2">
                    <div class="picture" id="z-2"></div>
                </div>
            </td>
            <td>
                <div id="f-3">
                    <div class="picture" id="z-3"></div>
                </div>
            </td>
        </tr>
        <tr>
            <td>
                <div id="f-4">
                    <div class="picture" id="z-4"></div>
                </div>
            </td>
            <td>
                <div id="f-5">
                    <div class="picture" id="z-5"></div>
                </div>
            </td>
            <td>
                <div id="f-6">
                    <div class="picture" id="z-6"></div>
                </div>
            </td>
        </tr>
        <tr>
            <td>
                <div id="f-7">
                    <div class="picture" id="z-7"></div>
                </div>
            </td>
            <td>
                <div id="f-8">
                    <div class="picture" id="z-8"></div>
                </div>
            </td>
            <td>
                <div id="f-9">
                    <div class="picture" id="z-9"></div>
                </div>
            </td>
        </tr>
    </table>
    <form name="form0" id="form0">
        <a href="javascript:;" class="file">選擇圖片<input type="file" name="file0" id="file0"/></a>
    </form>
    <input type="button" value="開始遊戲" onclick="disorder()" class="start">
    <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
    <script src="puzzle.js"></script>
</body>

</html>

CSS代碼:

table{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
}
table,tr,td{
    border: 1px solid rgb(6, 213, 228);
}
div{
    width: 100px;
    height: 100px;
}

.picture{
    background-size: 300px 300px;/* 改變原背景圖片大小 */
}

form{ 
    position: absolute;
    top: 72%;
    left: 47%;
    margin-left: -113px;
    margin-top: 15px;
}
/* 美化按鈕 */
.file {
    position: relative;
    display: inline-block;
    background: #D0EEFF;
    border: 1px solid #99D3F5;
    border-radius: 4px;
    padding: 4px 12px;
    overflow: hidden;
    color: #1E88C7;
    text-decoration: none;
    text-indent: 0;
    line-height: 20px;
}
.file input {
    position: absolute;
    font-size: 100px;
    cursor: pointer;
    right: 0;
    top: 0;
    opacity: 0;
}
.file:hover {
    background: #AADFFD;
    border-color: #78C3F3;
    color: #004974;
    text-decoration: none;
}

.start{
    width: 85px;
    height: 30px;
    font-size: 15px;
    line-height: 30px;
    border: 1px solid #99D3F5;
    border-radius: 4px;
    background-color: #D0EEFF;
    color: #1E88C7;
    position: absolute;
    top: 72%;
    left: 68%;
    margin-left: -200px;
    margin-top: 14px;
    cursor: pointer;
}
.start:hover {
    background: #AADFFD;
    border-color: #78C3F3;
    color: #004974;
}

#z-1{
    background-position: 0 0;
}
#z-2{
    background-position: -100px 0;
}
#z-3{
    background-position: -200px 0;
}
#z-4{
    background-position: 0 -100px;
}
#z-5{
    background-position: -100px -100px;
}
#z-6{
    background-position: -200px -100px;
}
#z-7{
    background-position: 0 -200px;
}
#z-8{
    background-position: -100px -200px;
}
#z-9{
    background-position: -200px -200px;
}

js代碼:

function my$(id) {
    return document.getElementById(id);
}
function over(e) {
    e.preventDefault();
}
//抓起,記錄被抓起元素的id
function drag(e) {
    //獲取id
    var id = e.target.id;
    //傳輸數據
    e.dataTransfer.setData("id", id);
}

//放下
function drop(e) {
    //var ev = window.event;
    var dragId = e.dataTransfer.getData("id");
    var dropId = e.target.id;
    var dragE = document.getElementById(dragId);
    var dropE = document.getElementById(dropId);
    var dragParent = dragE.parentNode;
    var dropParent = dropE.parentNode;
    //互換
    dragParent.appendChild(dropE);
    dropParent.appendChild(dragE);
    checked();
}

function checked() {
    var count = 0;
    var pis = document.getElementsByClassName("picture");
    for (var i = 0; i < pis.length; i++) {
        var pi = pis[i];
        var fi = pi.parentNode;
        var piId = pi.getAttribute("id");
        var fiId = fi.getAttribute("id");
        if (piId.replace("z-", "") == fiId.replace("f-", "")) {
            count++;
        } else {
            return;
        }
        if (count == 9) {
            alert("congratulate you!");
        }
    }
}
// 一旦打亂後各個div的位置都變了,重新選擇文件後也是亂的
function disorder() {
    var pis = document.getElementsByClassName("picture");
    for (var i = 0; i < 100; i++) {
        var r1 = parseInt(Math.random() * 9);
        var r2 = parseInt(Math.random() * 9);
        //得到隨機父節點
        var pir1 = pis[r1].parentNode;
        var pir2 = pis[r2].parentNode;
        //互換
        pir1.appendChild(pis[r2]);
        pir2.appendChild(pis[r1]);
    }
}

//給父子div綁定相應的事件
var idf = [];
var idz = [];
// var idf = new Array(9);
// var idz = new Array(9);
for (var i = 0; i < 9; i++) {
    // idf[i] = "f-" + (1 + i);
    // idz[i] = "z-" + (1 + i);
    idf.push("f-" + (1 + i));
    idz.push("z-" + (1 + i));
}
for (var i = 0; i < 9; i++) {
    my$(idf[i]).ondrop = drop;
    my$(idf[i]).ondragover = over;
    my$(idz[i]).draggable = true;
    my$(idz[i]).ondragstart = drag;
}

//獲取被點擊的圖片的url
$("#file0").change(function () {
    var objUrl = getObjectURL(this.files[0]);//獲取文件信息  
    if (objUrl) {
        var pis = document.getElementsByClassName("picture");
        for (var i = 0; i < pis.length; i++) {
            pis[i].style.backgroundImage = "url(" + objUrl + ")";
        }
    }
});


function getObjectURL(file) {
    var url = null;
    if (window.createObjectURL != undefined) {
        url = window.createObjectURL(file);
    } else if (window.URL != undefined) { // mozilla(firefox)  
        url = window.URL.createObjectURL(file);
    } else if (window.webkitURL != undefined) { // webkit or chrome  
        url = window.webkitURL.createObjectURL(file);
    }
    return url;
};

有4個需要注意的地方:

  1. 此案例核心代碼的實現,我參考了B站鼻孔哥的視頻,鏈接:拼圖案例詳解
  2. 這個遊戲的的如此設計造成一個bug:由於每次交換的是div,所以一旦打亂後哪怕更換圖片,更新後的圖片也是亂的。
  3. 實現本地圖片上傳功能參考此博主的文章:圖片上傳
  4. 在CSS按鈕美化中,巧用覆蓋包裹的方式美化上傳圖片的input標籤,參考鏈接:美化input
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章