2D图片拼图游戏开发入门

本文旨在为初学者提供一个简单的入门指南,介绍如何使用HTML、CSS和JavaScript开发网页上的2D游戏。将通过创建一个图片拼图游戏来展示这个过程,玩家可以通过拖放图片碎片来交换和重新排列它们,以形成完整的图片。此外,还在GitHub上提供了这个游戏的纯JavaScript版本。可以通过以下链接在线试玩这个游戏。

游戏规则非常简单:只需要拖放破碎的图片碎片来交换它们。需要以一种方式交换它们,使其形成正确的图片。拖放图片碎片的步骤将会被计数,所以可能希望思考并尝试用尽可能少的步骤完成。正确的图片会在右侧提供给作为参考。

游戏界面如下所示:

代码解析

要理解代码,可以将其分为三个部分:HTMLCSSJavaScript。HTML部分包含简单的标签来形成游戏的布局。CSS提供了一些响应式设计,而JavaScript部分包含了游戏的主要逻辑。以下是游戏的一些重要步骤:

为了使图片看起来像是被分割成了n*n不同的部分,其中n是每边的碎片数量,在ul中使用了n*n个li元素。每个li的display属性被设置为inline-block,以便它看起来像是一个网格。每个li的背景图片被设置为只显示图片的1/(n*n)部分,并且背景图片的位置也被相应地设置。每个li都被分配了data-value属性,以识别碎片的索引。

JavaScript中,定义了一个setImage函数,它接受图片数组和网格大小作为参数。如果没有传递网格大小,或者网格大小为null,则默认为4。然后,计算出每个图片碎片应该显示的背景图片的百分比位置,并创建li元素,设置其背景图片和位置。最后,使用randomize方法将图片碎片随机化。

function setImage(images, gridSize) { console.log(gridSize); gridSize = gridSize || 4; var percentage = 100 / (gridSize - 1); var image = images[Math.floor(Math.random() * images.length)]; $('#imgTitle').html(image.title); $('#actualImage').attr('src', image.src); $('#sortable').empty(); for (var i = 0; i < gridSize * gridSize; i++) { var xpos = (percentage * (i % gridSize)) + '%'; var ypos = (percentage * Math.floor(i / gridSize)) + '%'; var li = $('').css({ 'background-image': 'url(' + image.src + ')', 'background-size': (gridSize * 100) + '%', 'background-position': xpos + ' ' + ypos, 'width': 400 / gridSize, 'height': 400 / gridSize }); $('#sortable').append(li); } $('#sortable').randomize(); }

在上述代码片段中,可以看到,通过使用background-image和background-position样式,实现了图片的破碎效果。在设置好图片的破碎部分后,使用randomize方法将碎片随机化。在游戏过程中,用户需要重新排列这些碎片以形成完整的图片。

在设置好图片的破碎部分后,如上一个代码块的最后一行所示,使用randomize方法来随机化破碎的图片。为此,创建了一个小型的通用randomize函数来随机化任何jQuery元素集合。

$.fn.randomize = function(selector) { var $elems = selector ? $(this).find(selector) : $(this).children(), $parents = $elems.parent(); $parents.each(function() { $(this).children(selector).sort(function() { return Math.round(Math.random()) - 0.5; }).remove().appendTo(this); }); return this; };

在这里,简单地遍历给定选择器的每个子元素,并根据一个随机数改变其位置。随机数应该在0和集合中的元素数量之间。

为了使每个破碎的图片可以拖动,使用了jQuery的draggable功能。请确保页面中包含了jquery-ui.js,以实现可拖动/可放置的功能。

function enableSwapping(elem) { $(elem).draggable({ snap: '#droppable', snapMode: 'outer', revert: "invalid", helper: "clone" }); $(elem).droppable({ drop: function(event, ui) { var $dragElem = $(ui.draggable).clone().replaceAll(this); $(this).replaceAll(ui.draggable); currentList = $('#sortable > li').map(function(i, el) { return $(el).attr('data-value'); }); if (isSorted(currentList)) $('#actualImageBox').empty().html($('#gameOver').html()); imagePuzzle.enableSwapping(this); imagePuzzle.enableSwapping($dragElem); } }); }

如上代码片段所示,在每次放置后,都会调用isSorted函数来检查图片碎片是否已排序。每个碎片的排序是基于包含的li元素的data-value属性来检查的。如果碎片已排序,这意味着图片已经完成。

为了便于理解,使用了非常少的CSS。使用的CSS允许页面具有响应性,也可以在平板电脑或手机上玩游戏。没有使用第三方CSS库,以便可以更容易地理解原生CSS样式。

计数步骤或任何用户操作是任何游戏中最常见的部分。在这里,它也通过一个简单的步骤来实现。在每次放置后,它会检查图片是否已经形成。如果是,游戏结束;如果不是,将stepCount变量增加1。然后,使用jQuery在UI中更新stepCount。

计时器也是大多数游戏中的一个重要部分。根据读者提供的反馈,实现了一个基本的计时器来检查完成拼图所需的秒数。计时器在游戏开始时启动,并每秒调用tick方法来更新计时器。tick方法一次从start方法调用,然后每秒(使用JavaScript的SetTimeout)递归调用自身,并使用JQuery更新UI中的时间。当图片完成时,即游戏结束时,最终用时会被计算出来并显示在输出中。

function tick() { var now = new Date().getTime(); var elapsedTime = parseInt((now - imagePuzzle.startTime) / 1000, 10); $('#timerPanel').text(elapsedTime); timerFunction = setTimeout(imagePuzzle.tick, 1000); }

请注意,getTime()方法给出了自1970年1月1日以来经过的毫秒数。如果有更好的方法来计算两个DateTime之间的时间,会很乐意听取建议。不想依赖于1000毫秒的间隔来增加到1秒。

根据用户的反馈,在游戏中增加了3个难度级别:简单、中等和困难。在示例中,选择简单将拼图设置为3x3矩阵,中等为4x4矩阵,困难设置为5x5矩阵。

为了避免使用HTML5或CSS3,以便它可以在大多数浏览器中工作,这个游戏可能不会在IE11以下的旧版浏览器中工作。如果希望这个游戏也能在旧版浏览器中使用,可以简单地将脚本引用替换为旧版的JQuery版本(1.9或更早)。最新版本的JQuery不支持旧版浏览器。附带的示例代码应该可以在大多数最新浏览器中工作。在IE 11和Google Chrome中进行了测试。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485