Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
你畫像素畫原創(chuàng)教程
HTML5(以下簡(jiǎn)稱H5)干掉了Flash,H5游戲占領(lǐng)了瀏覽器。如果你想開發(fā)H5游戲,選擇一款好用的開源H5引擎非常有必要。
GDevelop
GDevelop是一款2D H5游戲引擎,專為初學(xué)者和專業(yè)開發(fā)者設(shè)計(jì)。強(qiáng)大的事件系統(tǒng),可以在不了解編程語言的情況下開發(fā)H5跨平臺(tái)游戲。詳細(xì)的官方教程幫助你快速上手。
下載地址:https://gdevelop-app.com/download/
Phaser
Phaser是一款2DH5游戲引擎,開發(fā)環(huán)境類似Flash。由開源開發(fā)者社區(qū)提供支持。它可以創(chuàng)建基于手機(jī)和桌面瀏覽器的游戲。有兩個(gè)主要版本,即Phaser CE和Phaser 3. Phaser CE是舊版本,Phaser 3是最新的穩(wěn)定版本。
下載地址:https://github.com/photonstorm/phaser
PixiJS
PixiJS是一種2D WebGL渲染器。當(dāng)開發(fā)者專注于游戲開發(fā)時(shí),引擎會(huì)自動(dòng)解決設(shè)備兼容性。如果想要?jiǎng)?chuàng)建跨平臺(tái)的游戲和應(yīng)用,它是不錯(cuò)的選擇。
下載地址:https://github.com/pixijs/pixi.js
Babylon.js
Babylon.js是一款3D H5游戲引擎。利用WebGL API渲染游戲。它還有一個(gè)在線沙盒,允許測(cè)試引擎API。毫無疑問,它是最好的開源HTML5和JavaScript游戲引擎之一。
下載地址:https://github.com/BabylonJS/Babylon.js
Crafty JS
Crafty JS是最好的開源H5游戲引擎之一。它的主要功能包括事件綁定,組件和實(shí)體,不需要自定義繪圖或DOM操作。它還擁有一個(gè)競(jìng)爭(zhēng)激烈的高素質(zhì)開源開發(fā)者社區(qū),他們隨時(shí)可以提供幫助。
下載地址:https://github.com/craftyjs/Crafty
melonJS
melonJS是一款H5游戲輕量級(jí)引擎。這個(gè)JS庫(kù)的好處是沒有任何依賴性,只需要一個(gè)能夠支持H5的Web瀏覽器。主要功能是跨平臺(tái),支持加速度和設(shè)備運(yùn)動(dòng),補(bǔ)間效果,對(duì)象池,基本動(dòng)畫管理,鼠標(biāo)和觸摸設(shè)備支持等。
下載地址:https://github.com/melonjs/melonJS
PlayCanvas WebGL
PlayCanvas是開源3D H5游戲引擎,可以創(chuàng)建一些非常漂亮的3D游戲和交互式動(dòng)畫。使用它的公司有Facebook,三星,迪士尼,Miniclip,Mozilla,King,ARM,Zynga等。
下載地址:https://github.com/playcanvas/engine
完。
oqups
Moqups是一款免費(fèi)的HTML5在線應(yīng)用,可創(chuàng)建線框圖、實(shí)體模型和UI概念。該程序使用起來非常簡(jiǎn)單,并且有內(nèi)置的模板可以直接使用(模板包括單選按鈕、鏈接、圖像占位符、文本框以及滑塊等)。
Stitches
Stitches是一個(gè)HTML5 sprite sheet生成器。用戶只需要經(jīng)過簡(jiǎn)單的拖拽圖片文件到空白處,然后點(diǎn)擊“Generate”就可以生成一個(gè)圖像圖標(biāo)和樣式表了。
HTML5 Maker
HTML5 Maker是一個(gè)在線的動(dòng)畫制作工具/服務(wù),可通過HTML, HTML5, CSS和JavaScript創(chuàng)建動(dòng)畫和交互式內(nèi)容。
Initializr
Initializr是一款HTML5模板生成器,幫助你快速啟動(dòng)基于HTML5模板的新項(xiàng)目。總之,Initializr 是制作 HTML5 網(wǎng)站最好的入門輔助開發(fā)工具,你可以使用提供的特色模板快速生成網(wǎng)站,也可以自定義,Initializr 會(huì)為你生成代碼簡(jiǎn)潔的可定制的網(wǎng)頁(yè)模板。
Sprite Box
Sprite Box是一款WYSIWYG工具,可幫組Web開發(fā)人員輕松、快速地創(chuàng)建CSS類和ID。它是基于使用背景位置屬性原則來調(diào)整插入到網(wǎng)頁(yè)塊元素中的精靈小圖像。這款工具是使用 JQuery,HTMl5 和 CSS3 組合來運(yùn)轉(zhuǎn)的,而且是一款完全免費(fèi)的工具。
Liveweave
Liveweave在HTML4/HTML5、CSS2/CSS3中含有內(nèi)置的自動(dòng)完成上下文特性,讓你工作起來更加輕松。你只需輸入HTML5和CSS3 標(biāo)簽/元素即可,就是這么簡(jiǎn)單。
Literally Canvas
Literally Canvas是一款開源的HTML5部件,可以被集成到任何頁(yè)面。它配備了一套簡(jiǎn)單的工具,包括繪圖、擦除、顏色選擇器、撤銷、恢復(fù)、平移以及縮放。該工具利用jQuery+和Underscore.js創(chuàng)建而來,利用API定義背景色、工具以及尺寸。
HTML5 Demos
HTML5 Demos能夠讓你立即知道Firefox是否支持HTML5 Canvas,Safari能否運(yùn)行HTML5 聊天客戶端。
HTML5 Visual Cheat Sheet
HTML5 Visual Cheat Sheet是專為Web設(shè)計(jì)師和開發(fā)者設(shè)計(jì)的一款速查表。這份速查表包含了HTML tag列表以及支持HTML4.01/5版本的相關(guān)屬性。
Switch to HTML5
Switch to HTML5是一款高效的模板生成器。如果你開始一個(gè)新的項(xiàng)目,記住一定要訪問該網(wǎng)站。各種各樣的HTML5網(wǎng)站模板將會(huì)呈現(xiàn)在你的眼前。
Online SVG to HTML5 Canvas Tool
這款工具可以將SVG轉(zhuǎn)換成HTML5 Canvas JavaScript函數(shù)。它幾乎可以運(yùn)行在任何主機(jī)上,幫助用戶去嘗試使用Canvas,可以導(dǎo)出大量的矢量藝術(shù)包(Illustrator,Inkscape)。
HTML5 Test
利用HTML5 test可以測(cè)試你的瀏覽器支持即將推出HTML5 標(biāo)準(zhǔn)和相關(guān)規(guī)范的得分情況。盡管該規(guī)范還沒有最終敲定,但是所有主流瀏覽器廠商都在為未來做好準(zhǔn)備。
你可以查看瀏覽器支持HTML5 哪些部分并與其他瀏覽器進(jìn)行對(duì)比。
Patternizer
Patternizer是用來創(chuàng)建條紋圖案的生成器。
Lime JS
LimeJS 是一個(gè) JavaScript 游戲開發(fā)框架,允許開發(fā)者創(chuàng)建基于 HTML5 的游戲,支持主流瀏覽器包括iOS。
HTML5 Reset
HTML5 Reset是(HTML,CSS等)一套設(shè)計(jì)組件,旨在幫助用戶節(jié)省大量的時(shí)間,創(chuàng)建更加高效的項(xiàng)目。
HTML5 Tracker
HTML5 Tracker能夠用于跟蹤HTML5相關(guān)的最新修訂信息。
Cross browser HTML5 forms
表單是一個(gè)網(wǎng)站非常重要的一部分。 HTML5的特性日歷,色彩板,滑動(dòng)部件,客戶端驗(yàn)證等這些都是非常強(qiáng)大的工具,但現(xiàn)實(shí)的情況就是,大多數(shù)的瀏覽器不支持所有的功能。這是一個(gè)很大的問題,剛好Cross browser HTML5能夠幫您如何輕松創(chuàng)建一個(gè)跨瀏覽器的表單。
學(xué)lufylegend.js之日,我用lufylegend.js開發(fā)了第一個(gè)HTML5小游戲——拼圖游戲,還寫了篇博文來炫耀一下:HTML5小游戲《智力大拼圖》發(fā)布,挑戰(zhàn)你的思維風(fēng)暴。不過當(dāng)時(shí)初學(xué)游戲開發(fā),經(jīng)驗(yàn)淺薄,所以沒有好好專研游戲里的算法和代碼的缺陷,導(dǎo)致游戲出現(xiàn)了很多bug,甚至拼圖打亂后很可能無法復(fù)原。最近經(jīng)常有朋友問起這個(gè)游戲,希望我能把代碼里的bug改一下方便初學(xué)者學(xué)習(xí),順便我也打算測(cè)試一下自己寫這種小游戲的速度,所以就抽出了一些時(shí)間將這個(gè)游戲從頭到尾重新寫了一遍,計(jì)算了一下用時(shí),從準(zhǔn)備、修改素材到最后完成游戲,一共用了大約2h的時(shí)間。
以下是游戲地址:
由于頭條禁止在文章頁(yè)面加入鏈接,大家私信我“拼圖”即可獲取下載地址。
這是我的游戲記錄,歡迎各位挑戰(zhàn):
接下來就來講講如何開發(fā)完成這款游戲的。(按“編年體”)
準(zhǔn)備lufylegend游戲引擎,大家可以去官方網(wǎng)站下載:
由于頭條禁止在文章頁(yè)面加入鏈接,大家私信我“拼圖”即可獲取下載地址。
引擎文檔地址:
由于頭條禁止在文章頁(yè)面加入鏈接,大家私信我“拼圖”即可獲取下載地址。
可以說,如果沒有強(qiáng)大的lufylegend引擎,這種html5小游戲用原生canvas制作,少說要一天呢。
準(zhǔn)備素材(10min) + 修改素材(20min)。由于在下實(shí)在手殘,不善于P圖,修改圖片用了大約20min,囧……
開發(fā)開始界面。游戲不能沒有開始界面所以我們首先實(shí)現(xiàn)這部分代碼。在此之前是index.html里的代碼,代碼如下:
<!DOCTYPE html>
<html>
<head>
<title>Puzzle</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<script type="text/javascript" src="./lib/lufylegend-1.10.1.simple.min.js"></script>
<script type="text/javascript" src="./js/Main.js"></script>
</head>
<body style="margin: 0px; font-size: 0px; background: #F2F2F2;">
<div id="mygame"></div>
</body>
</html>
主要是引入一些js文件,不多說。然后準(zhǔn)備一個(gè)Main.js文件,在這個(gè)文件里添加初始化界面和加載資源的代碼:
/** 初始化游戲 */
LInit(60, "mygame", 390, 580, main);
var imgBmpd;
/** 游戲?qū)?*/
var stageLayer, gameLayer, overLayer;
/** 拼圖塊列表 */
var blockList;
/** 是否游戲結(jié)束 */
var isGameOver;
/** 用時(shí) */
var startTime, time, timeTxt;
/** 步數(shù) */
var steps, stepsTxt;
function main () {
/** 全屏設(shè)置 */
if (LGlobal.mobile) {
LGlobal.stageScale=LStageScaleMode.SHOW_ALL;
}
LGlobal.screen(LGlobal.FULL_SCREEN);
/** 添加加載提示 */
var loadingHint=new LTextField();
loadingHint.text="資源加載中……";
loadingHint.size=20;
loadingHint.x=(LGlobal.width - loadingHint.getWidth()) / 2;
loadingHint.y=(LGlobal.height - loadingHint.getHeight()) / 2;
addChild(loadingHint);
/** 加載圖片 */
LLoadManage.load(
[
{path : "./js/Block.js"},
{name : "img", path : "./images/img.jpg"}
],
null,
function (result) {
/** 移除加載提示 */
loadingHint.remove();
/** 保存位圖數(shù)據(jù),方便后續(xù)使用 */
imgBmpd=new LBitmapData(result["img"]);
gameInit();
}
);
}
function gameInit (e) {
/** 初始化舞臺(tái)層 */
stageLayer=new LSprite();
stageLayer.graphics.drawRect(0, "", [0, 0, LGlobal.width, LGlobal.height], true, "#EFEFEF");
addChild(stageLayer);
/** 初始化游戲?qū)?*/
gameLayer=new LSprite();
stageLayer.addChild(gameLayer);
/** 初始化最上層 */
overLayer=new LSprite();
stageLayer.addChild(overLayer);
/** 添加開始界面 */
addBeginningUI();
}
以上代碼有詳細(xì)注釋,大家可以對(duì)照引擎文檔和注釋進(jìn)行閱讀。有些全局變量會(huì)在以后的代碼中使用,大家可以先忽略。接下來是addBeginningUI函數(shù)里的代碼,用于實(shí)現(xiàn)開始界面:
function addBeginningUI () {
var beginningLayer=new LSprite();
beginningLayer.graphics.drawRect(0, "", [0, 0, LGlobal.width, LGlobal.height], true, "#EDEDED");
stageLayer.addChild(beginningLayer);
/** 游戲標(biāo)題 */
var title=new LTextField();
title.text="拼圖游戲";
title.size=50;
title.weight="bold";
title.x=(LGlobal.width - title.getWidth()) / 2;
title.y=160;
title.color="#FFFFFF";
title.lineWidth=5;
title.lineColor="#000000";
title.stroke=true;
beginningLayer.addChild(title);
/** 開始游戲提示 */
var hint=new LTextField();
hint.text="- 點(diǎn)擊屏幕開始游戲 -";
hint.size=25;
hint.x=(LGlobal.width - hint.getWidth()) / 2;
hint.y=370;
beginningLayer.addChild(hint);
/** 開始游戲 */
beginningLayer.addEventListener(LMouseEvent.MOUSE_UP, function () {
beginningLayer.remove();
startGame();
});
}
到此,運(yùn)行代碼,得到我們的開始界面:
看到這個(gè)畫面,其實(shí)我自己都想吐槽一下實(shí)在是太“樸素”了,囧……
不過我這次圖個(gè)制作速度,所以還望各位看官海量。
這40分鐘的時(shí)間,是最關(guān)鍵時(shí)期,期間我們要完成整個(gè)游戲的主體部分。首先,我們需要用代碼來實(shí)現(xiàn)以下過程:
初始化游戲界面數(shù)據(jù)(如游戲時(shí)間、所用步數(shù))和顯示一些UI部件(如圖樣)
|
-> 獲取隨機(jī)的拼圖塊位置
|
-> 顯示打亂后的拼圖塊
我們將這些步驟做成一個(gè)個(gè)的函數(shù)方便我們統(tǒng)一調(diào)用:
function startGame () {
isGameOver=false;
/** 初始化時(shí)間和步數(shù) */
startTime=(new Date()).getTime();
time=0;
steps=0;
/** 初始化拼圖塊列表 */
initBlockList();
/** 打亂拼圖 */
getRandomBlockList();
/** 顯示拼圖 */
showBlock();
/** 顯示縮略圖 */
showThumbnail();
/** 顯示時(shí)間 */
addTimeTxt();
/** 顯示步數(shù) */
addStepsTxt();
stageLayer.addEventListener(LEvent.ENTER_FRAME, onFrame);
}
函數(shù)一開始,我們把isGameOver變量設(shè)定為false代表游戲未結(jié)束,在后期的代碼里,我們會(huì)看到這個(gè)變量的作用。接著我們初始化了用于表示時(shí)間和步數(shù)的time和steps這兩個(gè)全局變量,另外初始化變量startTime的值用于后面計(jì)算游戲時(shí)間。
接下來,我們就要開始初始化拼圖塊了。見initBlockList里的代碼:
function initBlockList () {
blockList=new Array();
for (var i=0; i < 9; i++) {
/** 根據(jù)序號(hào)計(jì)算拼圖塊圖片顯示位置 */
var y=(i / 3) >>> 0, x=i % 3;
blockList.push(new Block(i, x, y));
}
}
這里我們使用了一個(gè)Block類,這個(gè)類用于顯示拼圖塊和儲(chǔ)存拼圖塊的數(shù)據(jù),并提供了一些方法來操控拼圖塊,下面是其構(gòu)造器的代碼:
function Block (index, x, y) {
LExtends(this, LSprite, []);
var bmpd=imgBmpd.clone();
bmpd.setProperties(x * 130, y * 130, 130, 130);
this.bmp=new LBitmap(bmpd);
this.addChild(this.bmp);
var border=new LShape();
border.graphics.drawRect(3, "#CCCCCC", [0, 0, 130, 130]);
this.addChild(border);
this.index=index;
this.addEventListener(LMouseEvent.MOUSE_UP, this.onClick);
}
Block類繼承自LSprite,屬于一個(gè)顯示對(duì)象,所以我們?cè)谶@個(gè)類中添加了一個(gè)位圖對(duì)象用于顯示拼圖塊對(duì)應(yīng)的圖片。除此之外,我們還為拼圖塊添加了一個(gè)邊框,在顯示時(shí)用于隔開周圍的拼圖塊。Block類有一個(gè)index屬性,代表拼圖塊在拼圖塊列表blockList中的正確位置。最后,我們?yōu)榇祟愄砑恿艘粋€(gè)鼠標(biāo)按下事件,用于處理鼠標(biāo)按下后移動(dòng)圖塊操作。
接下來我們還要介紹這個(gè)類的一個(gè)方法setLocation:
Block.prototype.setLocation=function (x, y) {
this.locationX=x;
this.locationY=y;
this.x=x * 130;
this.y=y * 130;
};
這個(gè)方法用于設(shè)置拼圖塊對(duì)象的顯示位置以及保存拼圖塊的“數(shù)組位置”。什么是“數(shù)組位置”呢?各位看官可以通過下面的圖片加以了解:
可以看到,“數(shù)組位置”就類似于二維數(shù)組中的元素下標(biāo)。儲(chǔ)存這個(gè)位置的作用在于可以很方便地從blockList中獲取到附近的其他拼圖塊。這個(gè)方法在我們顯示拼圖時(shí)有調(diào)用到,在顯示拼圖之前,我們得先打亂拼圖,見如下代碼:
function getRandomBlockList () {
/** 隨機(jī)打亂拼圖 */
blockList.sort(function () {
return 0.5 - Math.random();
});
/** 計(jì)算逆序和 */
var reverseAmount=0;
for (var i=0, l=blockList.length; i < l; i++) {
var currentBlock=blockList[i];
for (var j=i + 1; j < l; j++) {
var comparedBlock=blockList[j];
if (comparedBlock.index < currentBlock.index) {
reverseAmount++;
}
}
}
/** 檢測(cè)打亂后是否可還原 */
if (reverseAmount % 2 !=0) {
/** 不合格,重新打亂 */
getRandomBlockList();
}
}
打亂拼圖部分直接用數(shù)組的sort方法進(jìn)行隨機(jī)打亂:
blockList.sort(function () {
return 0.5 - Math.random();
});
其實(shí)打亂算法有很多種,我這里采用最粗暴的方法,也就是隨機(jī)打亂。這種算法簡(jiǎn)單是簡(jiǎn)單,壞在可能出現(xiàn)無法復(fù)原的現(xiàn)象。針對(duì)這個(gè)問題,就有配套的檢測(cè)打亂后是否可還原的算法,具體的算法理論我借用lufy大神的評(píng)論:
此類游戲能否還原關(guān)鍵是看它打亂后的逆序次數(shù)之和是否為偶數(shù)
假設(shè)你打亂后的數(shù)組中的每一個(gè)小圖塊為obj0,obj1,obj2,…它們打亂之前的序號(hào)分別為obj0.num,obj1.num…
接下來循環(huán)數(shù)組,如果前面元素的序號(hào)比此元素后某個(gè)元素的序號(hào)大,如obj0.num > obj1.num或者obj2.num > obj4.num就表示一個(gè)逆序
當(dāng)全部的逆序之和為奇數(shù)時(shí)表示不可還原,重新打亂即可,打亂后重新檢測(cè),直到逆序之和為偶數(shù)為止
舉個(gè)例子,如果有一個(gè)數(shù)組為[3, 4, 2, 1],那么里面3 2, 3 1, 2 4, 4 1, 2 1是逆序的,所以逆序數(shù)是5。
上面我給出的getRandomBlockList里的代碼就是在實(shí)現(xiàn)打亂算法和檢測(cè)是否可還原算法。
還有一種打亂方式,大家可以嘗試嘗試:和復(fù)原拼圖一樣,將空白塊一步一步地與周圍的拼圖隨機(jī)交換順序。這個(gè)打亂算法較上一種而言,不會(huì)出現(xiàn)無法復(fù)原的現(xiàn)象,而且可以根據(jù)打亂的步數(shù)設(shè)定游戲難度。
在完成打亂拼圖塊后,如期而至的是顯示拼圖塊:
function showBlock() {
for (var i=0, l=blockList.length; i < l; i++) {
var b=blockList[i];
/** 根據(jù)序號(hào)計(jì)算拼圖塊位置 */
var y=(i / 3) >>> 0, x=i % 3;
b.setLocation(x, y);
gameLayer.addChild(b);
}
}
顯示了拼圖塊后,我們要做的就是添加操作拼圖塊的功能。于是需要拓展Block類,為其添加事件監(jiān)聽器onClick方法:
Block.prototype.onClick=function (e) {
var self=e.currentTarget;
if (isGameOver) {
return;
}
var checkList=new Array();
/** 判斷右側(cè)是否有方塊 */
if (self.locationX > 0) {
checkList.push(Block.getBlock(self.locationX - 1, self.locationY));
}
/** 判斷左側(cè)是否有方塊 */
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;
}
}
};
首先,我們?cè)谶@里看到了isGameOver全局變量的作用,即在游戲結(jié)束后,阻斷點(diǎn)擊拼圖塊后的操作。
在點(diǎn)擊了拼圖塊后,我們先獲取該拼圖塊周圍的拼圖塊,并將它們裝入checkList,再遍歷checkList,當(dāng)判斷到周圍有空白拼圖塊后,即周圍有index屬性等于8的拼圖塊后,先更新操作步數(shù),然后將這兩個(gè)拼圖塊交換位置。具體交換拼圖塊位置的方法詳見如下代碼:
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;
/** 在地圖塊數(shù)組中交換兩者位置 */
blockList.splice(b1Index, 1, b2);
blockList.splice(b2Index, 1, b1);
/** 交換兩者顯示位置 */
b1.setLocation(b2x, b2y);
b2.setLocation(b1x, b1y);
/** 判斷游戲是否結(jié)束 */
Block.isGameOver();
};
還有就是Block.getBlock靜態(tài)方法,用于獲取給定的“數(shù)組位置”下的拼圖塊:
Block.getBlock=function (x, y) {
return blockList[y * 3 + x];
};
在Block.exchangePosition中,我們通過Block.isGameOver判斷玩家是否已將拼圖復(fù)原:
Block.isGameOver=function () {
var reductionAmount=0, l=blockList.length;
/** 計(jì)算還原度 */
for (var i=0; i < l; i++) {
var b=blockList[i];
if (b.index==i) {
reductionAmount++;
}
}
/** 計(jì)算是否完全還原 */
if (reductionAmount==l) {
/** 游戲結(jié)束 */
gameOver();
}
};
到這里,我們就實(shí)現(xiàn)了打亂和操作拼圖塊部分。
最后30min用于細(xì)枝末節(jié)上的處理,如顯示拼圖縮略圖、顯示&更新時(shí)間和步數(shù),以及添加游戲結(jié)束畫面,這些就交給如下冗長(zhǎng)而簡(jiǎn)單的代碼來完成吧:
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="時(shí)間:" + 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="步數(shù):" + steps;
stepsTxt.x=LGlobal.width - stepsTxt.getWidth() - 20;
}
function onFrame () {
if (isGameOver) {
return;
}
/** 獲取當(dāng)前時(shí)間 */
var currentTime=(new Date()).getTime();
/** 計(jì)算使用的時(shí)間并更新時(shí)間顯示 */
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="游戲通關(guān)"
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="游戲用時(shí):" + 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="所用步數(shù):" + 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="- 點(diǎn)擊屏幕重新開始 -";
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 () {
/** 點(diǎn)擊界面重新開始游戲 */
stageLayer.addEventListener(LMouseEvent.MOUSE_UP, function () {
gameLayer.removeAllChild();
overLayer.removeAllChild();
stageLayer.removeAllEventListener();
startGame();
});
}
});
}
Ok,2h下來,整個(gè)游戲就搞定咯~不得不表?yè)P(yáng)一下lufylegend這個(gè)游戲引擎,實(shí)在是可以大幅提升開發(fā)效率。
最后奉上源代碼:
由于頭條禁止在文章頁(yè)面加入鏈接,大家私信我“拼圖”即可獲取下載地址。
這篇博文在最初寫成的時(shí)候,我沒有對(duì)逆序算法進(jìn)行深入研究,再加上我的測(cè)試不仔細(xì),我沒有發(fā)現(xiàn)算法的錯(cuò)誤之處。因此,在博文發(fā)布后,不少讀者發(fā)現(xiàn)游戲無解現(xiàn)象并將此問題反饋給了我,經(jīng)過網(wǎng)友熱心幫助,我才找到了問題所在,并更正了算法。在此對(duì)這些熱心的網(wǎng)友表示真心的感謝,也為我學(xué)習(xí)不深入,以及誤導(dǎo)了不少讀者而感到十分內(nèi)疚自責(zé)。
如果大家對(duì)本文有任何意見或不解,歡迎留言~
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。