HTML5人物拼图游戏

Posted 书圈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTML5人物拼图游戏相关的知识,希望对你有一定的参考价值。


7.1  人物拼图游戏介绍


拼图游戏将一幅图片分割成若干拼块并将它们随机打乱顺序。当将所有拼块都放回原位置时,就完成了拼图(游戏结束)。


在“游戏”中,单击滑块选择游戏难易,“容易”为33列拼图游戏,中间为一个44列拼图游戏,“难”为55列拼图游戏。拼块以随机顺序排列,玩家用鼠标单击空白块四周的来交换它们位置,直到所有拼块都回到原位置。拼图游戏运行结果如图7-1

                           

HTML5人物拼图游戏


7.2  程序设计的思路


html5可以把图片整合到网页中。使用canvas元素可以在这个空白的画布上填充线条,载入图片文件,甚至动画效果。这里制作拼图游戏用来展示HTML5 canvas的图片处理能力。


游戏程序首先显示以正确顺序排列的图片缩略图,根据玩家设置的分割数,将图片分割成相应tileCount行列数的拼块,并按顺序编号。动态生成一个大小tileCount*tileCount的数组boardParts,存放用012tileCount*tileCount-1的数,每个数字代表一个拼块(例如4*4的游戏拼块编号如图7-2所示)。


游戏开始时,随机打乱这个数组boardParts,假如boardParts[0]5则在左上角显示编号是5的拼块。根据玩家用鼠标点击的拼块和空白块所在位置,来交换该boardParts数组对应元素,最后判断元素排列顺序来判断是否已经完成游戏。

HTML5人物拼图游戏


7.3  程序设计的步骤


1. 游戏页面


<!doctype html>

<html>

<head>

<title>拼图游戏</title>

<style>

  .picture {

    border:1px solid black;

  }

</style>

</head>

<body>

<div id="title">

<h2>拼图游戏</h2>

</div>

<div id="slider">

<form>

<label>容易</label>

<input type="range"id="scale" value="4" min="3" max="5"step="1">

<label></label>

<img id="source"width="120px" height="120px" >

</form>

<br>

</div>

<div id="main"class="main">

<canvas id="puzzle"width="480px" height="480px"></canvas>

</div>

<scriptsrc="sliding.js"></script>

</body>

</html>


在网页中使用canvas标记用来创建画板。


<canvas width="480px"height="480px"></canvas>


canvas的宽和高使用像素为单位。如果这两个属于没有被指定,它们的默认的宽度为:300px,高度为:150px


网页中<div id="slider">包括了另一个HTML5标记:range input,这个标记<inputtype="range">可以让用户拖放滑块选择一个数值。这里设置滑块最小值为3,最大值为5。滑块值为3表明拼图游戏是33列的,滑块值为4表明拼图游戏是44列的,滑块值为5表明拼图游戏是55列的。


<img id="source" width="120px"height="120px" >显示原图defa.jpg的缩小图供玩家参照移动拼块。


2. sliding.js文件


在页面上画图需要使用canvas的上下文环境,通过调用getContext()方法获取上下文环境。


var context =document.getElementById('puzzle').getContext('2d');


我们还需要一个和canvas相同大小的图片'defa.jpg'


var img = new Image();

img.src = 'defa.jpg';

img.addEventListener('load', drawTiles, false);                           

//load事件侦听,即图片加载完成事件


加入这个'load'事件是确保图片完成加载后,再把图片放入canvas中。drawTiles()函数绘制打乱的图块。


var boardSize =document.getElementById('puzzle').width;       

//获取画板(画布)的宽度

var tileCount =document.getElementById('scale').value;           

//获取滑块的值


boardSizecanvas的宽度,通过rangeinput设置拼图的数量tileCount,数据范围从35(几行几列)


var tileSize = boardSize / tileCount;                          

//计算出拼块的大小宽度


最后定义3变量,其中2Object对象变量,emptyLoc保存空白拼图的位置(emptyLoc.xemptyLoc.y),clickLoc记录用户单击的位置(clickLoc.xclickLoc.y)。而1bool变量solved是指拼图是否完成,所有的拼图都找到正确的位置后,设置它为true


var context =document.getElementById('puzzle').getContext('2d');

var img = new Image();

img.src = 'dimetrodon.jpg';

img.addEventListener('load', drawTiles, false);                           

//load事件侦听,即图片加载完成事件

var boardSize = document.getElementById('puzzle').width;       

//获取画板(画布)的宽度

var tileCount =document.getElementById('scale').value;           

//获取滑块的值

var tileSize = boardSize / tileCount;

var clickLoc = new Object();

clickLoc.x = 0;

clickLoc.y = 0;

var emptyLoc = new Object();

emptyLoc.x = 0;

emptyLoc.y = 0;

var solved = false;                                            

 //拼图是否完成,false为未完成


下面实现拼块的随机排列。


我们使用一个一维数组存储每个拼块的编号。每一个元素代表一个拼块,初始时元素的数组下标与拼块的编号相同,说明位置正确。所以需要打乱数组的元素顺序,实现拼块的随机排列。而数组的元素顺序打乱使用带有排序函数的Array.sort()方法实现。


var boardParts = new Object();

initBoard();                                                       

//初始化拼块,并随机排列

function initBoard() {

   boardParts = new Array(tileCount * tileCount);

    for (vari = 0; i < tileCount * tileCount; i++) {

       boardParts[i] = i;

    }

   shift();  //拼块的随机排列

}

function sortNumber(a,b) {//随机排序函数

    returnMath.random() > 0.5 ? -1 : 1;

}

function shift() {  //拼块的随机排列

   boardParts.sort(sortNumber);

   emptyLoc.x = 0;

   emptyLoc.y = 0;

    solved =false;

}


以上就实现拼块的随机放置。但是真正显示拼块在屏幕上是drawTiles()函数。drawTiles()函数显示各个拼块。这个函数判断是否是空白拼图的位置(emptyLoc.xemptyLoc.y),不是则调用drawImage()绘制相应图块。


drawImage()最常用的是传入三个参数:image对象,以及图片相对于画布的x,y坐标。drawImage(image, x, y);


还可以加入两个参数用于设置图片的宽和高:


drawImage(image, x, y, width, height);


最复杂的drawImage函数有9个参数,按顺序分别为:图片对象,图片x坐标,图片y坐标,图片宽,图片高,目标x坐标,目标y坐标,目标宽和目标高。后四个参数主要是为了截取原图部分用来显示。这里把boardParts记录的拼块显示在(i*tileSize,j*tileSize)处。


//绘制所有拼块

function drawTiles() {

   context.clearRect(0, 0, boardSize, boardSize);

    for (vari = 0; i < tileCount; i++) {

        for(var j = 0; j < tileCount; j++) {

           var n = boardParts[i * tileCount + j];

           //计算出编号为n的拼块在原图的位置坐标(行列号)

           var x = parseInt(n / tileCount); 

           //丢弃小数部分, 保留整数部分

           var y = n % tileCount;

           console.log(x + ":" + Math.floor(n / tileCount) +":" + y);

           if (i!= emptyLoc.x||j!= emptyLoc.y||solved==true) {

           //不是空白拼图的位置且游戏未结束

           //或者if( !(i==emptyLoc.x&&j== emptyLoc.y&&solved==false))可能更容易明白

               //将编号为n的拼块显示在(i * tileSize, j * tileSize)处

               context.drawImage(img, x * tileSize, y * tileSize, tileSize, tileSize,

                    i * tileSize, j * tileSize, tileSize, tileSize);

            }

        }

    }

}


以下是事件定义。


首先为滑块定义触发事件,当它改变了,我们要重新计算拼块的数量和大小。滑块被移动时触发onchange事件,事件中计算拼块宽度大小,重新初始化画布,显示各个拼块。


document.getElementById('scale').onchange =function() {

  tileCount =this.value;

  tileSize =boardSize / tileCount;//计算拼块宽度大小

initBoard();//重新初始化拼块,并随机排列

 drawTiles();//显示各个拼块

};


还要追踪鼠标经过的拼块以及哪个拼块被单击。画板中移动鼠标的onmousemove事件中,计算出鼠标所在网格坐标clickLoc.xclickLoc.y


document.getElementById('puzzle').onmousemove =function(e) {

  clickLoc.x= Math.floor((e.pageX - this.offsetLeft) / tileSize);

  clickLoc.y= Math.floor((e.pageY - this.offsetTop) / tileSize);

};


画布中单击鼠标的onmousemove事件中,计算出鼠标所在网格坐标clickLoc.xclickLoc.y与空块位置间隔,如果间距为1则移动被单击的拼块。


document.getElementById('puzzle').onclick =function() {

  if(distance(clickLoc.x, clickLoc.y, emptyLoc.x, emptyLoc.y) == 1) {

 slideTile(emptyLoc, clickLoc);//交换被单击的拼块与空块位置

   drawTiles();//显示各个拼块

  }

  if (solved){//如果成功

   setTimeout(function() {alert("你成功了!");}, 500);

  }

};

function distance(x1, y1, x2, y2) {

  returnMath.abs(x1 - x2) + Math.abs(y1 - y2);

}


注意有一些浏览器会在重画画布之前弹出对话框,为了防止它的发生,一定要用延迟。


setTimeout(function() {alert("你成功了!");}, 500);


这句就是延迟0.5秒后,再弹出提示框"你成功了!"


slideTile(emptyLoc, clickLoc)是移动被单击的拼块clickLoc到空块位置emptyLoc。移动拼图的做法是:交换对应的boardParts元素,然后把单击位置设置成空块位置。


function slideTile(emptyLoc, clickLoc) {

    if(!solved) {

        vart;

        t=boardParts[emptyLoc.x * tileCount+emptyLoc.y];

       boardParts[emptyLoc.x*tileCount+emptyLoc.y]=boardParts[clickLoc.x*tileCount+clickLoc.y];

       boardParts[clickLoc.x * tileCount + clickLoc.y] = t;

       emptyLoc.x = clickLoc.x; //emptyLoc重新记录空白块位置

       emptyLoc.y = clickLoc.y;

        checkSolved();//检查是否成功

  }

}


一旦拼图移动了,我们还要检查一下拼图是否全部在正确的位置。checkSolved()检查是否成功。如果有一个拼块不正确函数就会返回false,否则返回true


function checkSolved() {

    var flag= true;

    for (vari = 0; i < tileCount * tileCount; i++) {

        if(boardParts[i] != i) //判断元素排列顺序

             flag = false;

    }

    solved =flag;

}


至此我们完成拼图游戏的设计。


-END-



HTML5人物拼图游戏



以上是关于HTML5人物拼图游戏的主要内容,如果未能解决你的问题,请参考以下文章

速度挑战 - 2小时完成HTML5拼图小游戏

python游戏制作拼图永不过时,这就是我这个年龄该玩的游戏~

积木拼图游戏-儿童游戏免费拼图3-6岁

拼图游戏 v1.1

拼图数量增加,拼图游戏中拼图大小增加

拼图游戏(数码还原游戏)的实现