本文旨在为初学者提供一个简单的入门指南,介绍如何使用HTML、CSS和JavaScript开发网页上的2D游戏。将通过创建一个图片拼图游戏来展示这个过程,玩家可以通过拖放图片碎片来交换和重新排列它们,以形成完整的图片。此外,还在GitHub上提供了这个游戏的纯JavaScript版本。可以通过以下链接在线试玩这个游戏。
游戏规则非常简单:只需要拖放破碎的图片碎片来交换它们。需要以一种方式交换它们,使其形成正确的图片。拖放图片碎片的步骤将会被计数,所以可能希望思考并尝试用尽可能少的步骤完成。正确的图片会在右侧提供给作为参考。
游戏界面如下所示:
要理解代码,可以将其分为三个部分:HTML、CSS和JavaScript。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中进行了测试。