溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用Cocos2d-JS制作類神經貓的游戲

發布時間:2021-07-28 21:29:29 來源:億速云 閱讀:210 作者:chen 欄目:移動開發

這篇文章主要講解了“怎么用Cocos2d-JS制作類神經貓的游戲”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么用Cocos2d-JS制作類神經貓的游戲”吧!

一夜之間,微信上一款叫《圍住神經貓》的小游戲火了。它的玩法很簡單,用最少的步數把一只神經兮兮的貓圍死。 7月22號上線以來,3天、500萬用戶和1億訪問,想必各位程序猿都按耐不住了,想實現自己的神經貓游戲。

在這篇教程里,我會教大家如何用Cocos2d-JS來實現一個神經貓這樣的游戲。 讓我們先看下游戲***完成了的效果圖:

怎么用Cocos2d-JS制作類神經貓的游戲

你可能注意到了,神經貓換成了可愛的小羊駝:)

在線游戲地址:http://app9.download.anzhuoshangdian.com/xyt/?from=singlemessage&isappinstalled=0

源碼地址:https://github.com/chukong/cocos-docs/blob/master/tutorial/framework/html5/how-to-make-a-cat-game/res/Catnorris-master.zip

游戲分析

三個界面基本上就是整個游戲的全部內容:

1.左邊的是主界面,展示游戲名稱以及主角,讓玩家對游戲的整體畫風有個大概的印象。

2.中間的是游戲界面,點擊空格防止橙色六邊形磚塊來圍堵小羊駝。

3.右邊的是游戲成功或失敗的界面。

整個游戲的主邏輯都在游戲界面中完成。

玩法是這樣:

1.游戲初始化開始,小羊駝始終是站在地圖中間,在地圖的其他區域隨機生產一些位置隨機的磚塊。

2.玩家點擊一個空白區域,放置一個磚塊來圍堵羊駝。

3.羊駝AI尋路移動一步。

4.循環2和3,直到羊駝被圍堵在一個圈里面(游戲成功),或羊駝到達地圖邊界(游戲失?。?/p>

整個游戲的思路理清楚了,接下來我們開始進入編碼階段。

開發環境與新建項目

本教程開發基于當前***的Download v3.0RC1.  (其他版本下載地址:http://cn.cocos2d-x.org/download/

下載引擎并解壓到磁盤的某個目錄。

打開控制臺,輸入下面的命令來新建項目。

$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[i].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; },

要點解析如下:

1.為了方便邏輯處理,這里用了active_nodes和active_blocks來記錄被激活的方塊。在初始化矩陣前,需要清理上一次游戲已生成的橙色方塊。active_nodes存儲精靈實例,active_blocks記錄精靈的矩陣坐標。

2.randomBlocks函數生成隨機橙色磚塊。 首先產生一個7-20的隨機數,也就是確定橙色塊的數量。然后循環確定每一個塊的位置坐標,當然位置坐標也是隨機確定的。

3.復位小羊駝的位置以及動畫。

響應觸摸事件

按照我們之前的分析,游戲界面初始化完成后,需要等待用戶指令才能進行下一步的游戲。

相關代碼如下:

// 1. cc.eventManager.addListener({     // 2.     event: cc.EventListener.TOUCH_ALL_AT_ONCE,     // 3.     onTouchesBegan: function (touches, event) {         var touch = touches[0];         var pos = touch.getLocation();         var target = event.getCurrentTarget();         if (!target.inited) return;           pos.y -= OFFSET_Y;         var r = Math.floor(pos.y / BLOCK_YREGION);         pos.x -= OFFSET_X + (r%2==1) * OFFSET_ODD;         var c = Math.floor(pos.x / BLOCK_XREGION);         if (c >= 0 && r >= 0 && c < COL && r < ROW) {             if (target.activateBlock(r, c)) {                 target.step ++;                 target.movePlayer();             }         }     } }, this);

1. cc.eventManager.addListener加入新的事件監聽。

2. 設置事件監聽模式為TOUCH_ALL_AT_ONCE。

3. 重寫onTouchesBegan方法,判斷觸摸點的坐標,確定是哪個塊被點擊,并做響應的處理。 activateBlock方法在對應的矩陣位置加入橙色塊,并更新狀態數組。然后調用movePlayer移動小羊駝。

羊駝的移動

整個邏輯的關鍵是AI.js中的getDistance函數,

getDistance有6個參數:

1.羊駝所在行號

2.羊駝所在列號

3.前進方向,l_choices、r_choices、t_choices或b_choices

4.激活塊的記錄數組

5.輔助記錄表,記錄在尋路算法中某個節點是不是已經被訪問過。

6.最短路徑

返回值有三種情況:

1.羊駝到達地圖邊界,返回羊駝坐標和最短路徑0

2.羊駝還在地圖中,返回羊駝的下一個坐標值和最短路徑cost

3. -1表示羊駝被圈住了,但可能可以移動。

getDistance的代碼實現如下:

var getDistance = function (r, c, dir_choices, activate_blocs, passed, cost) {     passed[r][c] = true;     if (r <= 0 || r >= ROW_MINUS_1 || c <= 0 || c >= COL_MINUS_1) {         return [r, c, cost];     }       var odd = (r % 2 == 1) ? 1 : 0;     var choices = dir_choices[odd];       var nextr, nextc, result;     for (var i = 0, l = choices.length; i < l; i++) {         nextr = r + choices[i][0];         nextc = c + choices[i][4];           if (!activate_blocs[nextr][nextc] && !passed[nextr][nextc]) {             cost ++;             result = getDistance(nextr, nextc, dir_choices, activate_blocs, passed, cost);             if (result != -1) {                 result[0] = nextr;                 result[1] = nextc;                 return result;             }         }     }     return -1; };

在羊駝移動函數movePlayer中,首先通過getDistance來判斷上下左右4個方向,來尋找***移動方向。根據getDistance的返回結果做相應的邏輯處理。

游戲結束界面

游戲結束的兩種情況,玩家勝利或失敗。

在ResultUI的構造函數中,加入參數win,用來標識是否勝利。而勝利和失敗僅僅是顯示文字的區別,下方的兩個按鈕均一樣。

在ctor中,根據是否勝利加載不同的圖片來顯示:

ctor : function (win) {      this._super();        this.win = win;      if (win) {          this.winPanel = new cc.Sprite(res.succeed);          this.winPanel.x = cc.winSize.width/2;          this.winPanel.anchorY = 0.2;          this.winPanel.y = cc.winSize.height/2;          this.addChild(this.winPanel);      }      else {          this.losePanel = new cc.Sprite(res.failed);          this.losePanel.x = cc.winSize.width/2;          this.losePanel.anchorY = 0.2;          this.losePanel.y = cc.winSize.height/2;          this.addChild(this.losePanel);      }  }

在onEnter中,根據是否勝利加載不同的文字描述:

if (this.win) {     this.winPanel.removeAllChildren();       var w = this.winPanel.width, h = this.winPanel.height;     var label = new cc.LabelTTF("繼續刷屏!\n"+step+"步推倒我的小羊駝\n打敗"+percent+"%朋友圈的人!\n你能超過我嗎?", "宋體", 20);     label.x = w/2;     label.y = h/4;     label.textAlign = cc.LabelTTF.TEXT_ALIGNMENT_CENTER;     //label.boundingWidth = w;     label.width = w;     label.color = cc.color(0, 0, 0);     this.winPanel.addChild(label); } else {     this.losePanel.removeAllChildren();     var w = this.losePanel.width, h = this.losePanel.height;     label = new cc.LabelTTF("我滴小羊駝呀它又跑掉了\nT_T 快幫我抓回來!", "宋體", 20);     label.x = w/2;     label.y = h/4+5;     label.textAlign = cc.LabelTTF.TEXT_ALIGNMENT_CENTER;     //label.boundingWidth = w;     label.width = w;     label.color = cc.color(0, 0, 0);     this.losePanel.addChild(label, 10); }

"通知好友"按鈕加載shareUI層,這個層其實是一個幫助指導界面,指示用戶點擊微信右上角的分享按鈕進行分享。

gameScene.addChild(layers.shareUI, 100); target.win ? share(1, step, percent) : share(2);

"再來一次"實現很簡單,調用initGame重新初始化矩陣,并移除ResultUI層。

layers.game.initGame(); target.win ? layers.winUI.removeFromParent() : layers.loseUI.removeFromParent();

分享指導界面

在游戲結束界面我們加入了分享按鈕?,F在我們就來實現分享界面。

分享界面由分享圖標和分享說明組成。這和前面的layer創建一樣。很簡單,唯一的區別是,分享界面是cc.LayerColor(cc.LayerColor支持設置層的顏色)的子類。下面是實現代碼:

ctor: function () {     this._super(cc.color(0, 0, 0, 188), cc.winSize.width, cc.winSize.height);       var arrow = new cc.Sprite(res.arrow);     arrow.anchorX = 1;     arrow.anchorY = 1;     arrow.x = cc.winSize.width - 15;     arrow.y = cc.winSize.height - 5;     this.addChild(arrow);       var label = new cc.LabelTTF("請點擊右上角的菜單按鈕\n再點\"分享到朋友圈\"\n讓好友們挑戰你的分數!", "宋體", 20, cc.size(cc.winSize.width*0.7, 250), cc.TEXT_ALIGNMENT_CENTER);     label.x = cc.winSize.width/2;     label.y = cc.winSize.height - 100;     label.anchorY = 1;     this.addChild(label); },

加入touch事件用于移除分享界面:

onEnter: function () {     this._super();     cc.eventManager.addListener({         event: cc.EventListener.TOUCH_ONE_BY_ONE,         onTouchBegan: function (touch, event) {             layers.shareUI.removeFromParent();         }     }, this); }

微信分享

我們需要的功能:

1.分享到微信朋友圈

2.分享給微信好友

3.分享到騰訊微博

4.關注指定用戶

實現方式

本功能已經有大神提供了完整的庫,地址是:https://github.com/zxlie/WeixinApi ,以下我們做一個簡單的使用分析。

注:除特殊說明外,本小節實現均在文件 WeixinApi.js中。

現在我們實現的分享有,發給指定朋友,分享到朋友圈,分享到騰訊微博。對于不同的分享方式,實現方式大同小異,我們主要以分享到朋友圈為例。

分享數據

我們分享的時候需要的數據有:appid,圖片,鏈接,標題,文字內容,例如:

怎么用Cocos2d-JS制作類神經貓的游戲

對應在代碼中就需要以下數據:

"appid":theData.appId ? theData.appId : '', "img_url":theData.imgUrl, "link":theData.link, "desc":theData.desc, "title":theData.title, // 注意這里要分享出去的內容是desc

數據來源

為了得到數據,我們需要在GameScene.js中實現ResultUI的時候,將以上數據生成出來。 比如勝利時,我們需要顯示:

var label = new cc.LabelTTF("繼續刷屏!\n"+step+"步推倒我的小羊駝\n打敗"+percent+"%朋友圈的人!\n你能超過我嗎?", "宋體", 20);

完成數據后,我們需要判斷勝利或失敗,并傳回ui中顯示:

target.win ? share(1, step, percent) : share(2);

分享回調

為了監測分享的狀態,無論分享成功與否我們回調都會上報狀態,以便程序處理,我們需要的狀態有:

1.用戶取消分享

2.分享失敗

3.分享成功 所以我們需要以下實現:

WeixinJSBridge.on('menu:share:timeline', function (argv) {     if (callbacks.async && callbacks.ready) {         window["_wx_loadedCb_"] = callbacks.dataLoaded || new Function();         if(window["_wx_loadedCb_"].toString().indexOf("_wx_loadedCb_") > 0) {             window["_wx_loadedCb_"] = new Function();         }         callbacks.dataLoaded = function (newData) {             window["_wx_loadedCb_"](newData);             shareTimeline(newData);         };         // 然后就緒         callbacks.ready && callbacks.ready(argv);     } else {         // 就緒狀態         callbacks.ready && callbacks.ready(argv);         shareTimeline(data);     } });

WeixinJSBridge

在微信上,通過公眾平臺推送給用戶的文章,是在微信內部直接打開的,用的無外乎就是一個UIWebView控件(IOS上,Android上也 差不多)。但特殊的是,微信官方在這里面加了一個默認的Js API--WeixinJSBridge,通過它,能直接在該頁面上做分享操作。  以下代碼,拿去玩吧:

WeixinJSBridge.on('menu:share:timeline', function (argv) {     if (callbacks.async && callbacks.ready) {         window["_wx_loadedCb_"] = callbacks.dataLoaded || new Function();         if(window["_wx_loadedCb_"].toString().indexOf("_wx_loadedCb_") > 0) {             window["_wx_loadedCb_"] = new Function();         }         callbacks.dataLoaded = function (newData) {             window["_wx_loadedCb_"](newData);             shareTimeline(newData);         };         // 然后就緒         callbacks.ready && callbacks.ready(argv);     } else {         // 就緒狀態         callbacks.ready && callbacks.ready(argv);         shareTimeline(data);     } });

感謝各位的閱讀,以上就是“怎么用Cocos2d-JS制作類神經貓的游戲”的內容了,經過本文的學習后,相信大家對怎么用Cocos2d-JS制作類神經貓的游戲這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女