视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
2小时完成HTML5拼图小游戏代码图文介绍
2020-11-27 15:12:12 责编:小采
文档


上面我给出的getRandomBlockList里的代码就是在实现打乱算法和检测是否可还原算法。

还有一种打乱方式,大家可以尝试尝试:和复原拼图一样,将空白块一步一步地与周围的拼图随机交换顺序。这个打乱算法较上一种而言,不会出现无法复原的现象,而且可以根据打乱的步数设定游戏难度。

在完成打乱拼图块后,如期而至的是显示拼图块:

function showBlock() {
 for (var i = 0, l = blockList.length; i < l; i++) {
 var b = blockList[i];

 /** 根据序号计算拼图块位置 */
 var y = (i / 3) >>> 0, x = i % 3;

 b.setLocation(x, y);

 gameLayer.addChild(b);
 }
}

显示了拼图块后,我们要做的就是添加操作拼图块的功能。于是需要拓展Block类,为其添加事件onClick方法:

Block.prototype.onClick = function (e) {
 var self = e.currentTarget;

 if (isGameOver) {
 return;
 }

 var checkList = new Array();

 /** 判断右侧是否有方块 */
 if (self.locationX > 0) {
 checkList.push(Block.getBlock(self.locationX - 1, self.locationY));
 }

 /** 判断左侧是否有方块 */
 if (self.locationX < 2) {
 checkList.push(Block.getBlock(self.locationX + 1, self.locationY));
 }

 /** 判断上方是否有方块 */
 if (self.locationY > 0) {
 checkList.push(Block.getBlock(self.locationX, self.locationY - 1));
 }

 /** 判断下方是否有方块 */
 if (self.locationY < 2) {
 checkList.push(Block.getBlock(self.locationX, self.locationY + 1));
 }

 for (var i = 0, l = checkList.length; i < l; i++) {
 var checkO = checkList[i];

 /** 判断是否是空白拼图块 */
 if (checkO.index == 8) {
 steps++;
 updateStepsTxt();

 Block.exchangePosition(self, checkO);

 break;
 }
 }
};

首先,我们在这里看到了isGameOver全局变量的作用,即在游戏结束后,阻断点击拼图块后的操作。

在点击了拼图块后,我们先获取该拼图块周围的拼图块,并将它们装入checkList,再遍历checkList,当判断到周围有空白拼图块后,即周围有index属性等于8的拼图块后,先更新操作步数,然后将这两个拼图块交换位置。具体交换拼图块位置的方法详见如下代码:

Block.exchangePosition = function (b1, b2) {
 var b1x = b1.locationX, b1y = b1.locationY,
 b2x = b2.locationX, b2y = b2.locationY,
 b1Index = b1y * 3 + b1x,
 b2Index = b2y * 3 + b2x;

 /** 在地图块数组中交换两者位置 */
 blockList.splice(b1Index, 1, b2);
 blockList.splice(b2Index, 1, b1);

 /** 交换两者显示位置 */
 b1.setLocation(b2x, b2y);
 b2.setLocation(b1x, b1y);

 /** 判断游戏是否结束 */
 Block.isGameOver();
};

还有就是Block.getBlock静态方法,用于获取给定的“数组位置”下的拼图块:

Block.getBlock = function (x, y) {
 return blockList[y * 3 + x];
};

Block.exchangePosition中,我们通过Block.isGameOver判断玩家是否已将拼图复原:

Block.isGameOver = function () {
 var reductionAmount = 0, l = blockList.length;

 /** 计算还原度 */
 for (var i = 0; i < l; i++) {
 var b = blockList[i];

 if (b.index == i) {
 reductionAmount++;
 }
 }

 /** 计算是否完全还原 */
 if (reductionAmount == l) {
 /** 游戏结束 */
 gameOver();
 } 
};

到这里,我们就实现了打乱和操作拼图块部分。

90~120min

最后30min用于细枝末节上的处理,如显示拼图缩略图、显示&更新时间和步数,以及添加游戏结束画面,这些就交给如下冗长而简单的代码来完成吧:

function showThumbnail() {
 var thumbnail = new LBitmap(imgBmpd);
 thumbnail.scaleX = 130 / imgBmpd.width;
 thumbnail.scaleY = 130 / imgBmpd.height;
 thumbnail.x = (LGlobal.width - 100) /2;
 thumbnail.y = 410;
 overLayer.addChild(thumbnail);
}

function addTimeTxt () {
 timeTxt = new LTextField();
 timeTxt.stroke = true;
 timeTxt.lineWidth = 3;
 timeTxt.lineColor = "#54D9EF";
 timeTxt.color = "#FFFFFF";
 timeTxt.size = 18;
 timeTxt.x = 20;
 timeTxt.y = 450;
 overLayer.addChild(timeTxt);

 updateTimeTxt();
}

function updateTimeTxt () {
 timeTxt.text = "时间:" + getTimeTxt(time);
}

function getTimeTxt () {
 var d = new Date(time);

 return d.getMinutes() + " : " + d.getSeconds();
};

function addStepsTxt () {
 stepsTxt = new LTextField();
 stepsTxt.stroke = true;
 stepsTxt.lineWidth = 3;
 stepsTxt.lineColor = "#54D9EF";
 stepsTxt.color = "#FFFFFF";
 stepsTxt.size = 18;
 stepsTxt.y = 450;
 overLayer.addChild(stepsTxt);

 updateStepsTxt();
}

function updateStepsTxt () {
 stepsTxt.text = "步数:" + steps;

 stepsTxt.x = LGlobal.width - stepsTxt.getWidth() - 20;
}

function onFrame () {
 if (isGameOver) {
 return;
 }

 /** 获取当前时间 */
 var currentTime = (new Date()).getTime();

 /** 计算使用的时间并更新时间显示 */
 time = currentTime - startTime;
 updateTimeTxt();
}

function gameOver () {
 isGameOver = true;

 var resultLayer = new LSprite();
 resultLayer.filters = [new LDropShadowFilter()];
 resultLayer.graphics.drawRoundRect(3, "#BBBBBB", [0, 0, 350, 350, 5], true,"#DDDDDD");
 resultLayer.x = (LGlobal.width - resultLayer.getWidth()) / 2;
 resultLayer.y = LGlobal.height / 2;
 resultLayer.alpha = 0;
 overLayer.addChild(resultLayer);

 var title = new LTextField();
 title.text = "游戏通关"
 title.weight = "bold";
 title.stroke = true;
 title.lineWidth = 3;
 title.lineColor = "#555555";
 title.size = 30;
 title.color = "#FFFFFF";
 title.x = (resultLayer.getWidth() - title.getWidth()) / 2;
 title.y = 30;
 resultLayer.addChild(title);

 var usedTimeTxt = new LTextField();
 usedTimeTxt.text = "游戏用时:" + getTimeTxt(time);
 usedTimeTxt.size = 20;
 usedTimeTxt.stroke = true;
 usedTimeTxt.lineWidth = 2;
 usedTimeTxt.lineColor = "#555555";
 usedTimeTxt.color = "#FFFFFF";
 usedTimeTxt.x = (resultLayer.getWidth() - usedTimeTxt.getWidth()) / 2;
 usedTimeTxt.y = 130;
 resultLayer.addChild(usedTimeTxt);

 var usedStepsTxt = new LTextField();
 usedStepsTxt.text = "所用步数:" + steps;
 usedStepsTxt.size = 20;
 usedStepsTxt.stroke = true;
 usedStepsTxt.lineWidth = 2;
 usedStepsTxt.lineColor = "#555555";
 usedStepsTxt.color = "#FFFFFF";
 usedStepsTxt.x = usedTimeTxt.x;
 usedStepsTxt.y = 180;
 resultLayer.addChild(usedStepsTxt);

 var hintTxt = new LTextField();
 hintTxt.text = "- 点击屏幕重新开始 -";
 hintTxt.size = 23;
 hintTxt.stroke = true;
 hintTxt.lineWidth = 2;
 hintTxt.lineColor = "#888888";
 hintTxt.color = "#FFFFFF";
 hintTxt.x = (resultLayer.getWidth() - hintTxt.getWidth()) / 2;
 hintTxt.y = 260;
 resultLayer.addChild(hintTxt);

 LTweenLite.to(resultLayer, 0.5, {
 alpha : 0.7,
 y : (LGlobal.height - resultLayer.getHeight()) / 2,
 onComplete : function () {
 /** 点击界面重新开始游戏 */
 stageLayer.addEventListener(LMouseEvent.MOUSE_UP, function () {
 gameLayer.removeAllChild();
 overLayer.removeAllChild();

 stageLayer.removeAllEventListener();

 startGame();
 });
 }
 });
}

Ok,2h下来,整个游戏就搞定咯~不得不表扬一下lufylegend这个游戏引擎,实在是可以大幅提升开发效率。

下载本文
显示全文
专题