原生Javascript实现拼图游戏

使用Javascript实现多功能的拼图游戏

一、结果展示

游戏界面

二、游戏功能介绍

  1. 可更换游戏图片;
  2. 可选择游戏难度;
  3. 可记录操作次数;
  4. 可给玩家以提示;
  5. 可支持键盘操作(四个方向键)和鼠标点击;
  6. 当游戏结束时,给出提示;

三、代码设计说明

  1. html 文件用于整个游戏界面的布局;整个布局分为两个部分,一个是游戏菜单部分,就是最上面蓝色背景部分;另一部分是游戏内容区域,包含左右两个部分,左边是进行游戏的区域,右边是提示图片;
  2. 整个html文件采用flex布局,所以css文件里需要使用flex布局实现html文件的界面需求;总体布局采用列方向排列子元素;然后每一列中采用行方向排列子元素;总体布局示意图如下:
    这里写图片描述
  3. 进行游戏的区域中内容通过JS动态生成;JS代码负责实现游戏的各项功能要求,其中主要的功能点有:
    1. 小方块中的图片的填充;
    2. 判断游戏是否结束;
    3. 判断点击事件和键盘按键事件是否会引起图片的交换;即判断点击的小方块周围是否是空的小方块;
    4. 交换两个小方块(可交换的)的图像;
    5. 初始化游戏;

四、实现细节说明

  1. 关于更换游戏图片的实现

    因为要动态更换图片,所以我们需要一个全局变量来记录我们当前用到的图片,在js中我们用到了image对象以及imagePath这两个变量。image对象在动态计算小方格的宽度和高度时需要用到;而imagePath则是为了在更换图片事件发生时,重新修改image对象的属性;具体功能由onChooseImage()函数实现;

  2. 关于难度选择的实现

    难度选择主要会影响到游戏内容区域的绘制,我们通过image的宽度和高度除以难度值来计算每一个小方格的宽度和高度,并计算填充小方块时图片的偏移量;具体功能由onChooseDifficulty()来实现;

  3. 关于记录操作次数的实现

    这个比较简单,因为我们同时要支持鼠标和键盘操作,但是不管用户的操作是怎样传递给我们的,我们都需要交换两个小方块的数据(即背景图像的位置信息),所以只需要在这个函数里更新一个score全局变量即可;这个函数是doExchange(item);即将item的相关内容同emptyBlock(空方块)交换;

  4. 小方块的填充

    小方块的填充算是一个难点,因为有些拼图游戏的实现中使用的是已经切割好的图片,但是由于要实现难度选择和更换图片等功能,所以我们不能使用切割好的图片,只能从完整的图片上选择我们需要的部分来填充小方块;这里我使用的是为动态创建的div设置如下格式的背景:url(imagePath) x方向的图片偏移A y方向的图片偏移B 来实现填充;这里需要注意的是坐标系的理解:以图片和div的左上角为原点,右方向为x正方向,下方向为y正方向;现在假设图片的原点和div的原点是重合的,上面指定的background格式意味着,向右移动图片A个单位,向下移动B个单位(如果A或者B为负,则反向),然后使用图片和div重合的部分来填充div。理解这一点很重要。也就是说,我们想要图片中坐标为(10px,20px)宽高均为10px的部分来填充div,我们需要的图片偏移为(-10px,-20px);这是因为我们选取(10px,20px)这一区域的方法实际上是在移动div的原点到此位置,但是语法规则中需要移动的是图片,所以只能取负处理!JS实现中,使用singleWidth和singleHeight这两个变量来屏蔽“负号”。singleWidth=-1*image.width/difficulty。此时如果我们需要逻辑坐标为(2,2)的图片来填充小方块,只需singleWidth*2即可得到设置背景图的数据;

  5. 判断游戏结束的方法

    要判断游戏结束,首先要将“游戏结束”这一抽象概念转变为对应的程序语言。我们都知道,当所有小方块都在它原来的位置上时,拼图游戏结束;这句话指出了我们需要的两个数据:第一是该小方块本来的位置,第二是该小方块现在的位置。为了方便,我们使用前面提到的坐标系,这样方便由逻辑坐标得到所需要的图片;我们可以使用一个[difficulty][difficulty]的二维数组来管理小方块;比如[2][2]表示该小方块使用坐标为(-2*singleWidth,-2*singleHeight)处,长宽分别为-singleWidht和-singleHeight的图片;于是我把[2][2]记为图片坐标。表示它使用的图片的位置;我们同样需要记录当前它在游戏中的坐标,我把它叫做物理坐标。这样,我们只需要比较所有小方块的物理坐标和图片坐标是否一致就可以判断是否所有的小方块均已归位,即游戏是否结束;

    扫描二维码关注公众号,回复: 2394833 查看本文章
  6. 交换小方块图片的实现

    其实交换小方块只是修改了小方块的背景图片,造成小方块移动的错觉。修改小方块的背景图片伴随着修改小方块的图片坐标;所以,交换小方块设计两部分操作:1为修改背景图片;2为修改小方块的图片坐标;

  7. 至于判断小方块是否可以移动,就比较简单了:通过鼠标点击小方块A时,只需要看A的四周是否有空块(比较两个坐标是否相邻分为四种情况,上、下、左、右,当然不能越界哦),有就交换他们,没有就算了呗;键盘操作也是同理,只不过是响应键盘按键事件罢了。

  8. 关于数据的存储,我使用了Position这个对象来记录各种位置,每一个position对象有x属性和y属性;然后将该对象转换为字符串后存到div的dataset中。当触发事件是就可以获得div的imagePosition和physicalPosition。

  9. 重新开局功能的实现:在js文件里,opening()函数负责初始化数据,包括重新计算各个小方块的图片位置、填充各个小方块的图片坐标等。值得注意的是,openning函数使用getOpeningPositions()函数返回一个二维position对象数组C,其中C[x][y]表示物理坐标为(x,y)的小方块的图片位置信息。然后根据singleWidth和singleHeight设置div的背景。getOpeningPositons函数首先产生没有打乱的坐标,然后利用随机数,模拟用户操作,不断交换空方块和其周围的小方块以实现开局功能;

  10. 关于提示功能:提示功能其实算不上真正意义上的提示,但是它确实会引导你完成游戏。在getOpeningPosition()函数里模拟用户操作交换小方块时,如果空块向左移动,那么我们就将一个使空块向右移动的函数emptyMoveRIght对象压入操作栈,即把用户操作的反动作压入操作栈;当用户产生操作时,我们就接着把对应的反动作压入操作栈。当用户点击提示时,我们从操作栈弹出一个函数对象并执行,当栈空时,自然游戏场景被还原,即游戏结束。这种方法不高明,但也有效吧.

项目源码CSDN下载

猜你喜欢

转载自blog.csdn.net/slx3320612540/article/details/80727423