为了进一步熟悉html、css、js,做个一个小游戏加深对相关知识的理解。界面略显粗糙。

目录

环境:

相关文件:

游戏效果:

如何得到特定像素的图片

步骤:

1.pic.html文件

2.pic.css文件

3.pic.js文件


环境:

Visual Studio Code

相关文件:

pic.html、pic.css、pic.js、600.jpg(该图片大小为600px * 600px)、200.jpg

游戏效果:

javascript拼图游戏教程 html拼图游戏_i++

如何得到特定像素的图片

使用windows自带的“画图”对图片进行大小调整

javascript拼图游戏教程 html拼图游戏_html_02

javascript拼图游戏教程 html拼图游戏_i++_03

步骤:

1.编写pic.html文件设计大体框架

2.编写pic.css文件对pic.html文件进行渲染

3.编写pic.js文件实现相关的功能函数

1.pic.html文件

javascript拼图游戏教程 html拼图游戏_javascript拼图游戏教程_04

编写html文件设计大体框架

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel = "stylesheet" type = "text/css" href="pic.css">
    <script type="text/javascript" language="javascript" src="pic.js"></script>
    <title>拼图游戏</title>
</head>
<body>
    <div id="Frame">   <!--大的框Frame-->
        
        <div id="gameFrame"> <!--游戏框gameFrame-->
            <div id="block1" onclick="move(1)"></div>
            <div id="block2" onclick="move(2)"></div>
            <div id="block3" onclick="move(3)"></div>
            <div id="block4" onclick="move(4)"></div>
            <div id="block5" onclick="move(5)"></div>
            <div id="block6" onclick="move(6)"></div>
            <div id="block7" onclick="move(7)"></div>
            <div id="block8" onclick="move(8)"></div>
            <!--可移动方块block 1~8-->
        </div>
        <div id="controlFrame"> <!--控制框controlFrame-->
            <p>
              <rowspan id="timeText">总用时:</rowspan>
              <rowspan id="timer"></rowspan>
            </p>
            <p>
              <rowspan id="start" onclick="start()">开始</rowspan>
              <rowspan id="reset" onclick="reset()">重来</rowspan>
            </p>
        </div>
        <div id="picture"> <!--图片-->

        </div>
    </div>
</body>
</html>

2.pic.css文件

编写css文件对html文件进行渲染

*{
    padding: 0;
    margin: 0;
    border: 0;
}
body{
    width: 100%;
    height: 100%;
}
 /*大的框架设置像素,宽600px,高800px,边框2px,居中显示*/
#Frame{
    position: relative;
    width: 600px;
    height: 700px;
    margin: 0 auto;
    margin-top: 0px;
} 

#gameFrame{
    position: relative;
    width: 600px;
    height: 600px;
    display: inline-block;
    background-color: azure;


}
#gameFrame div{
    background-image: url(600.jpg);    /*图片设置为同一张图*/
    background-repeat: no-repeat;
    position: absolute;
    width:199px;                        /*为了使图片之间有小空隙,所以大小小于200px*/
    height: 199px;
    background-color: aquamarine;
    box-shadow: 1px 1px 2px white;
    text-align: center;
    font-size: 200px;
    color: rgba(255, 255, 255, 0);
    line-height: 200px;
    cursor: pointer;
    -webkit-transition: all 0.3s;
    -moz-transition: all 0.3s;
    -ms-transition: all 0.3s;
    -o-transition: all 0.3s;
    transition: all 0.3s;

}

/*控制框*/
#controlFrame{
    position: relative;
    width: 300px;
    height: 100px;
    display: inline-block;

}
/*图片*/
#picture{
    position: relative;
    background-image: url(200.jpg);
    float:right;
    width: 100px;
    height: 100px;
}

/*让元素rowspan重来和开始变成块状*/
#start{
    display: inline-block;
    background-color: aqua;
    text-align: center;
    color: brown;
    cursor: pointer;
}
#reset{
    display: inline-block;
    background-color: aqua;
    text-align: center;
    color: brown;
    cursor: pointer;
}
#block1{
    left: 0px;
    background-position: -0px 0px;   /*通过设置该属性取得图片不同位置的图片*/
}
#block2{
    left: 200px;
    background-position: -200px 0px;
}
#block3{
    left: 400px;
    background-position: -400px 0px;
}
#block4{
    top: 200px;
    left: 0px;
    background-position: 0px -200px;
}
#block5{
    top: 200px;
    left: 200px;
    background-position: -200px -200px;
}
#block6{
    top: 200px;
    left: 400px;
    background-position: -400px -200px;   
}
#block7{
    top: 400px;
    left: 0px;
    background-position: 0px -400px;
}
#block8{
    top: 400px;
    left: 200px;
    background-position: -200px -400px;
}

渲染的目的是设置各个div块的位置、背景颜色和大小。

为了使block方块之间有小间隙,所以block方块大小为199px * 199px,小于200px * 200px,

在设置游戏块(gameFrame div)block的背景图片时,将block的背景图都设置为同一张图片。

通过设置background-position取得图片的不同部分。

3.pic.js文件

编写js实现相关的功能函数

var time = 0; //计时时间
var pause = true; //暂停标志  pause为ture,游戏暂停.
var setTimer; //定时函数,用于显示游戏计时
var Block = new Array(10);  //Block是游戏框gameFrame 9等分后的区域;里面记录着存放的方块

//区域内方块初始化
Block[0] = 0;    //元素0不用
Block[1] = 1;      //表示区域1放着方块1;
Block[2] = 2;
Block[3] = 3;
Block[4] = 4;
Block[5] = 5;
Block[6] = 6;
Block[7] = 7;
Block[8] = 8;
Block[9] = 0;  //这里表示区域没有方块

var BlockCanTo = new Array(   //这是游戏框gameFrame 9等分后的各个区域可移动的位置
    [0], //第一个元素不用
    [2,4],  //区域1可以移动到区域2和区域4
    [1,3,5],
    [2,6],
    [1,5,7],
    [2,4,6,8],
    [3,5,9],
    [4,8],
    [5,7,9],
    [6,8]
);
 //游戏框gameFrame 9等分后的区域左上角的坐标
var BlockPostion = new Array(
    [0], //元素0不用
    [0,0], //区域1左上角的坐标
    [200,0],
    [400,0],
    [0,200],
    [200,200],
    [400,200],
    [0,400],
    [200,400],
    [400,400]
);

function timer(){  //显示时间的函数
    time +=1;
    var min = parseInt(time /60);
    var sec = time%60;
    document.getElementById("timer").innerHTML = min + "分" + sec + "秒";
    //显示时间
}
function start(){ //开始函数
    if(pause){   //pause为true,此时游戏为暂停状态,文本显示为""开始"
        document.getElementById("start").innerHTML= "暂停"; //将文本显示为"暂停""
        set_timer = setInterval(timer,1000);//开始计时

    }else{
        document.getElementById("start").innerHTML = "开始";
        clearInterval(setTimer); //游戏暂停,计时器停止计时
    }
    pause = !pause;
}

function randomBlock(){ //方块打乱
    for(var i = 9; i > 1; i--){
        var temp = parseInt(Math.random()* (i - 1) + 1);
        //区域i和区域 1~(i-1)中的一个进行方块交换
        if(Block[i] !=0){ //将区域i中的方块放到区域temp
            document.getElementById("block" + Block[i]).style.left = Block_postion[temp][0] + "px";
            document.getElementById("block" + Block[i]).style.top = Block_postion[temp][1] + "px";
        }
        if(Block[temp]!=0){   //将区域temp中的方块放到区域i
            document.getElementById("block" + Block[temp]).style.left = Block_postion[i][0] + "px";
            document.getElementById("block" + Block[temp]).style.top = Block_postion[i][1] + "px";
        }
        //区域temp和区域i的方块交换
        var t = Block[temp];
        Block[temp] = Block[i];
        Block[i] = t;
    }
    if(!ifRight())
        randomBlock();
}
function ifRight(){ //判断拼图是否可还原
    //可以通过计算这个排列的逆序数个数加空格位置的行列号,最终得到的数的奇偶性判断,偶数可还原
    var count = 0;
    var m,n;
    for(var i = 1; i <= 8; i++){
        var a = Block[i];

        if(a == 0){
     
            m = parseInt((i - 1) / 3) + 1;
            n = parseInt((i - 1) % 3) + 1;
        }
        for(var j = i + 1; j <= 9; j ++){
            if(Block[j] < a)
                count ++;
        }
    }
    count += m;
    count += n;
    return count % 2 == 0;
}

function move(id){   //方块id移动
    var i;
    for(i = 1;i <= 9; i++){    //看看方块id放在哪个区域内
        if(Block[i] == id)
            break;
    }
    var nextPostion = NextPosition(i); //找到不放方块的区域.
    
    if(nextPostion != 0){
        Block[i] = 0;    //id所在区域方块清空.
        Block[nextPostion] = id; //没有方块的区域放置方块id.
        //将方块id移动至  没有方块的区域
        document.getElementById("block" + id).style.left = Block_postion[nextPostion][0] + "px";
        document.getElementById("block" + id).style.top = Block_postion[nextPostion][1] + "px";   
    }
    //判断拼图是否完成
    var finishFlag = true;  //游戏是否完成标志   
    for(var j = 1; j <= 8; j++){
        if(Block[j] != j){
            finishFlag = false;   //如果区域j放的不是方块j,则游戏未完成
            break;
        }
            
    }
    if(finishFlag){
        alert("finished");
        if(!pause){
            start(); //暂停计时
        }
        
    }else{
        if(pause)
            start();  //如果游戏未完成,此时又点击,开始计时
    }

    
}

function NextPosition(b){ // 找到 没有方块的区域
    var ret = 0;
    for(var i = 0; i < BlockCanTo[b].length; i++){
        if(Block[BlockCanTo[b][i]] == 0){
            ret = BlockCanTo[b][i];
            break;
        }
    }
    return ret; 

}

function reset(){    //重新开始
    time = 0;
    if(pause){ 
        start();
    }
    randomBlock();
    
}

window.onload = function(){
    this.reset();
}

对于方块的打乱函数randomBlock:

游戏框gameFrame划分成9个区域,从最后一个区域开始遍历。让区域与之前的区域交换方块block。

在交换完方块后,判断方块是否可还原.如果不可还原,则继续打乱,直到方块可还原为止。

 

方块的移动函数move:

先找到方块所在的区域Block。区域Bolck附近没有放方块的区域,就是方块可以移动到的区域。

 

判断拼图是否可还原的函数ifRight:

在此3*3拼图中,若逆序数+ 没有方块的区域的行号+没有方块的区域的列号  是偶数,则可还原。