<ignore_js_op> <ignore_js_op> html <ignore_js_op>node <ignore_js_op>源碼下載:http://code.662p.com/view/8582.htmlios 你可能注意到了,神經貓換成了可愛的小羊駝:)在線遊戲地址:http://app9.download.anzhuoshang ... ge&isappinstalled=0 遊戲分析 三個界面基本上就是整個遊戲的所有內容: 1.左邊的是主界面,展現遊戲名稱以及主角,讓玩家對遊戲的總體畫風有個大概的印象。 2.中間的是遊戲界面,點擊空格防止橙色六邊形磚塊來圍堵小羊駝。 3.右邊的是遊戲成功或失敗的界面。 整個遊戲的主邏輯都在遊戲界面中完成。 玩法是這樣: 1.遊戲初始化開始,小羊駝始終是站在地圖中間,在地圖的其餘區域隨機生產一些位置隨機的磚塊。 2.玩家點擊一個空白區域,放置一個磚塊來圍堵羊駝。 3.羊駝AI尋路移動一步。 4.循環2和3,直到羊駝被圍堵在一個圈裏面(遊戲成功),或羊駝到達地圖邊界(遊戲失敗) 整個遊戲的思路理清楚了,接下來咱們開始進入編碼階段。 開發環境與新建項目 本教程開發基於當前最新的Download v3.0RC1 . 下載引擎並解壓到磁盤的某個目錄。 打開控制檯,輸入下面的命令來新建項目。 $cd cocos2d-js-v3.0-rc1/tools/cocos2d-console/bin $./cocos new -l js --no- native $cd MyJSGame/ $../cocos run -p web 環境搭建並非這篇文章的重點,更詳細的信息能夠參考:《搭建 Cocos2d-JS 開發環境》 主界面實現 遊戲的入口代碼在main.js中,用編輯器打開並修改成下面的代碼。 cc.game.onStart = function (){ // 1. cc.view.adjustViewPort( true ); // 2. if (cc.sys.isMobile) cc.view.setDesignResolutionSize(320,500,cc.ResolutionPolicy.FIXED_WIDTH); else cc.view.setDesignResolutionSize(320,480,cc.ResolutionPolicy.SHOW_ALL); cc.view.resizeWithBrowserSize( true ); // 3. cc.LoaderScene.preload(resources, function () { // 4. gameScene = new GameScene(); cc.director.runScene(gameScene); }, this ); }; cc.game.run(); 關鍵點解析以下: 1.設置瀏覽器meta來適配屏幕,引擎內部會根據屏幕大小來設置meta的viewport值,會達到更好的屏幕適配效果。 2.針對手機瀏覽器和PC瀏覽器啓用不一樣的分辨率適配策略。 3.預加載圖片聲音等資源。 cc.LoaderScene.preload會生成一個「加載中 x%」的界面,等待資源加載結束後,調用第二個參數傳入的匿名函數。 對於基於html的遊戲,頁面是放在服務器端供瀏覽器下載的,爲了得到流暢的用戶體驗,cc.LoaderScene.preload讓瀏覽器先把遠程服務器的資源緩存到本地。須要預加載的資源定義在src/Resources.js文件中。 4.啓動遊戲的第一個場景。 主界面的由兩個層實現: 1.GameLayer層,遊戲主邏輯層,在未初始化地圖矩陣時,它只顯示背景地圖。 2.StartUI層,顯示logo圖片和開始遊戲按鈕。 GameScene的初始化代碼以下: var GameScene = cc.Scene.extend({ onEnter : function () { this ._super(); var bg = new cc.Sprite(res.bg); bg.attr({ anchorX : 0.5, anchorY : 0.5, x : cc.winSize.width/2, y : cc.winSize.height/2 }); this .addChild(bg); layers.game = new GameLayer(); this .addChild(layers.game); layers.startUI = new StartUI(); this .addChild(layers.startUI); layers.winUI = new ResultUI( true ); layers.loseUI = new ResultUI( false ); layers.shareUI = new ShareUI(); } }); 由引擎提供的cc.Scene.extend方法,讓js能實現高級面嚮對象語言的繼承特性。 onEnter方法是場景初始化完成即將展現的消息回調,在onEnter中必須調用this._super();來確保Scene被正確的初始化。 整個遊戲的設計只有一個scene,界面之間的切換由layer來實現,這可能不是一個最優的設計,但也提供另外一種思路。 爲了用layer來實現切換,全局變量layers存儲了各層的一個實例。 GameLayer咱們在下一章節中詳細講解。 StartUI的實現以下: var StartUI = cc.Layer.extend({ ctor : function () { this ._super(); var start = new cc.Sprite(res.start); start.x = cc.winSize.width/2; start.y = cc.winSize.height/2 + 20; this .addChild(start); }, onEnter : function () { this ._super(); cc.eventManager.addListener({ event: cc.EventListener.TOUCH_ALL_AT_ONCE, onTouchesEnded: function (touches, event) { var touch = touches[0]; var pos = touch.getLocation(); if (pos.y < cc.winSize.height/3) { layers.game.initGame(); layers.startUI.removeFromParent(); } } }, this ); } }); cc.Layer.extend做用同cc.Scene.extend同樣,只不過是一個擴展Scene,一個擴展Layer。ctor是Cocos2d-JS中的構造函數,在ctor中必須調用this._super();以確保正確的初始化。 在onEnter中,咱們爲StartUI層綁定事件監聽,判斷觸摸點的位置座標來觸發scene切換。 細心的讀者可能要問,爲何不用Menu控件? 當前的Cocos2d-JS版本已實現模塊化,能夠選擇只加載遊戲中用到的模塊,已減小最終打包size。 爲了避免加入Menu模塊,這裏使用了最簡單的觸摸點座標判斷來實現通用的事情。 遊戲界面的實現 橙色塊的初始化 遊戲地圖區域是由9*9的六邊形方塊組成的,首先用InActive的圖片初始化一邊矩陣。相關代碼以下: var ox = x = y = 0, odd = false , block, tex = this .batch.texture; for ( var r = 0; r < ROW; r++) { y = BLOCK_YREGION * r; ox = odd * OFFSET_ODD; for ( var c = 0; c < COL; c++) { x = ox + BLOCK_XREGION * c; block = new cc.Sprite(tex, BLOCK2_RECT); block.attr({ anchorX : 0, anchorY : 0, x : x, y : y, width : BLOCK_W, height : BLOCK_H }); this .batch.addChild(block); } odd = !odd; } 每次循環odd改變,已實現上下錯位的排布。 attr是Node基類的新方法,能夠方便的一次性設置多個屬性。 橙色方塊的初始化是由initGame函數來完成。 先來看initGame的實現: initGame : function () { if ( this .inited) return ; this .player_c = this .player_r = 4; this .step = 0; // 1. for ( var i = 0, l = this .active_nodes.length; i < l; i++) { this .active_nodes.removeFromParent(); } this .active_nodes = []; for ( var r = 0; r < ROW; r++) { for ( var c = 0; c < COL; c++) { this .active_blocks[r][c] = false ; } } // 2. this .randomBlocks(); // 3. this .player.attr({ anchorX : 0.5, anchorY : 0, x : OFFSET_X + BLOCK_XREGION * this .player_c + BLOCK_W/2, y : OFFSET_Y + BLOCK_YREGION * this .player_r - 5 }); this .player.stopAllActions(); this .player.runAction( this .moving_action); this .inited = true ; }, |