在瀏覽器上實現自動引導(五),瀏覽器實現引導
上接我的新手引導系列部落格文章。
在遊戲開發中新手引導的設計、代碼編寫、測試需要花費較多的時間和精力,特別是測實驗證,在反反覆複的引導流程中點來點去,會讓人有一種要崩潰的感覺。因此在想能否實現讓電腦根據我們的新手引導配置,自動去跑我們的引導呢?
答案是肯定的,請看下在的示範:
手工執行引導,注意滑鼠指標的移動。
自動執行引導,注意滑鼠指標沒有移動。
在sz.Guide中開始自動引導
只需要在你的引導配置中加入開啟開關
guideConfig = { tasks:{...}, //引導任務 fingerImage:'res/finger.png', //手型圖片 isShowMask: false, //是否開啟遮罩 isAutoGuide: true //是否自動引導}
isAutoGuide: true 即可開啟自動引導,非常的簡單。你可以在你的遊戲過種中隨時開啟和關閉,對於測試非常有用。
自動引導的實現
目前sz.Guide只實現了在瀏覽器上的自動引導功能,實現的思路就是根據引導配置中的節點名字,在遊戲渲染中定位節點,並類比滑鼠動作,觸發節點控制項的事件來完成的。
瀏覽器中類比滑鼠事件
使用javascript在瀏覽器上類比滑鼠事件是非常方便的,可以使用initMouseEvent函數來完成:
initMouseEvent( type, //string類型 :要觸發的事件類型,例如‘click'。 bubbles,// Boolean類型:表示事件是否應該冒泡,針對滑鼠事件類比,該值應該被設定為true。 cancelable,// bool類型:表示該事件是否能夠被取消,針對滑鼠事件類比,該值應該被設定為true。 view,// 抽象視圖:事件授予的視圖,這個值幾乎全是document.defaultView. detail,// int類型:附加的事件資訊這個初始化時一般應該預設為0。 screenX,// int類型 : 事件距離螢幕左邊的X座標 screenY,// int類型 : 事件距離螢幕上邊的y座標 clientX,// int類型 : 事件距離可視地區左邊的X座標 clientY,// int類型 : 事件距離可視地區上邊的y座標 ctrlKey,// Boolean類型 : 代表ctrol鍵是否被按下,預設為false。 altKey,// Boolean類型 : 代表alt鍵是否被按下,預設為false。 shiftKey,// Boolean類型 : 代表shif鍵是否被按下,預設為false。 metaKey,// Boolean類型: 代表meta key 是否被按下,預設是false。 button,// int類型: 表示被按下的滑鼠鍵,預設是零. relatedTarget// (object) : 事件的關聯對象.只有在類比mouseover 和 mouseout時用到。 )
initMouseEvent函數非常之多,但對與我們這裡來說只需要類比touchBegan和touchEnded,對應的滑鼠事件類型為mousedown和mouseup,我們還需要關心的就是想要點擊的控制項的位置x和y。僅需要這些參數就能完成我們的任務了。
產生了滑鼠事件,還需要將事件指派到document的節點中, cocos2d-js預設的canvas節點名為gameCanvas,我們需要將事件投遞給它。
//擷取gameCanvasvar pt = ...//通過座標轉換計算位置 var canvas = document.getElementById("gameCanvas");//初始化滑鼠事件var mousedown = document.createEvent("MouseEvent");mousedown.initMouseEvent("mousedown", true, true, window, 0, 0, 0, pt.x, pt.y, true, false, false, false, 0, null);//將滑鼠事件指派到canvas中canvas.dispatchEvent(mousedown);
座標系統
使用過cococs2d的都知道座標原點為左下角(x=0,y=0), 而在dom元素中座標原點為左上方(x=0, y= 0),關於cocos2d座標系的學習請參見關東升老師的文章《Cocos2d-JS 座標系》。
節點座標
我們通過引導定位器,獲得到了節點對象,通過node.getPosition()函數擷取節點所在父節點中的相對位置。
全局座標
手型精靈在引導層上,引導層為整個螢幕大小。要讓手型精靈正確指向定位到的節點,還需要將節點座標轉換為cocos2d中的全局座標。通過父點節的轉換函式,轉換一個點為全局座標點:
var point = locateNode.getParent().convertToWorldSpace(locateNode.getPosition());
cocos2d全局座標轉換到canvas座標
目前最後一步就是將遊戲中的座標轉換為canvas座標,然後去執行滑鼠類比函數,點擊我們定位的控制項。
1.擷取canvas矩形資訊
function getHTMLElementPosition(element) { var docElem = document.documentElement; var win = window; var box = null; if (cc.isFunction(element.getBoundingClientRect)) { box = element.getBoundingClientRect(); } else { if (element instanceof HTMLCanvasElement) { box = { left: 0, top: 0, width: element.width, height: element.height }; } else { box = { left: 0, top: 0, width: parseInt(element.style.width), height: parseInt(element.style.height) }; } } return { left: box.left + win.pageXOffset - docElem.clientLeft, top: box.top + win.pageYOffset - docElem.clientTop, width: box.width, height: box.height };}
上面這段代碼擷取一個dom節點的矩形資訊,其實不用自己編寫這個方法,你可以直接調用cc.inputManager.getHTMLElementPosition(),引擎已經有這個方法了。
2.座標轉換
canvas矩形的left對應遊戲世界x座標,滑鼠位置即x上位移rect.left
x + rect.left
canvas矩形的top與遊戲異界y座標相反,rect.top + rect.height為遊戲世界對應瀏覽器的底部,遊戲中y座標越大,對應canvas的中的y越小:
rect.top + rect.height - y
具體請看下面代碼:
mouseSimulation: function(x, y) { var canvas = document.getElementById("gameCanvas"); var rect = cc.inputManager.getHTMLElementPosition(canvas);//getHTMLElementPosition(canvas); var pt = cc.p(x + rect.left, rect.top + rect.height - y); var mousedown = document.createEvent("MouseEvent"); mousedown.initMouseEvent("mousedown", true, true, window, 0, 0, 0, pt.x, pt.y, true, false, false, false, 0, null); canvas.dispatchEvent(mousedown); setTimeout(function () { var mouseup = document.createEvent("MouseEvent"); mouseup.initMouseEvent("mouseup", true, true, window, 0, 0, 0, pt.x, pt.y, true, false, false, false, 0, null); canvas.dispatchEvent(mouseup); }, 100);}
至此所有的問題都已解決,將mouseSimulation函數插入引導流程中體驗一下自動引導的爽快吧!
自動執行,注意滑鼠指標沒有移動,引導提示在移動