• <nav id="yisao"><rt id="yisao"></rt></nav>
  • Cocos Creator 開發小游戲的實用技巧

    作者介紹:

    大家好,我是麒麟子, 開源棋牌《幼麟棋牌-四川麻將》(泄漏版叫 《達達麻將》)作者,成都幼麟科技創始人。

    自 09 年進入游戲行業以來,不知不覺已經度過了十個春秋。曾經我也血氣方剛,曾經我也青春年少。歲月如梭,光陰似箭,如今已是而立之年。退去了青澀懵懂,換來了滿身的意氣風發。希望在下一個十年,能夠用自己所學的經驗,浪跡這個充滿愛恨情仇的游戲江湖。

    麒麟子往期文章:

    Part I:「幼麟麻將」全套源碼講解

    Part II:服務端和網絡通訊知識解析

    Part III:偽3D渲染布局知識解析

    「幼麟麻將」全套源碼上線Cocos擴展商店!

    教程介紹:

    《麒麟子 Cocos Creator 實用技巧》為麒麟子的隨筆記錄,主要記錄一些麒麟子在使用 Cocos Creator 制作棋牌和微信小游戲的時候,遇到的問題的解決方案。希望能夠用自己所學,為遇到困難的同學帶來一定的幫助,為 Cocos 社區盡一份綿薄之力,為游戲教育行業注入一絲絲清流。

    截止今日,技巧系列共計更新了 5 則,包括:

    (1)如何正確地顯示微信頭像

    (2)微信名字截斷(支持表情)

    (3)微信小游戲中音效中斷問題處理

    (4)打包原生 App 截圖白屏解決方案

    (5)技能 CD 效果制作

    ……

    更多實用教程陸續更新中,歡迎感興趣的開發者關注論壇原貼。

    原貼地址:

    https://forum.cocos.com/t/cocos-creator/76914


    技巧一:如何正確地顯示微信頭像

    不管是游戲 APP,還是 H5,又或者是微信小游戲,但凡接入了微信登錄的應用,都可能需要顯示微信頭像。

    在 Cocos Creator 中,我們常見的顯示方法是像下面這樣:

    var headimg = ‘http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83erD6MOUwRKV9NyBAqnoFDTnltzAe2zWOkKxyDOFibVBb1ZV5CaATJwYAuNqZ5sXMBC4c8iacaHDf8RA/132’;

    cc.loader.load({url:headimg,type:’jpg’},function(err,tex){
    self.icon.spriteFrame = new cc.SpriteFrame(tex);
    });

    這樣做大部分情況下是沒有問題的,但容易踩到兩個坑:

    假如用戶在微信中上傳的頭像不是 JPG 格式,將會顯示為黑屏

    假如是 H5 中使用上述代碼,會提示跨域訪問

    而最近新出了一個奇怪的事情,就是 Android 系統 7.0+ 的機器,在 4G 網下無法正常顯示微信頭像,包括騰訊《歡樂斗地主》里的排行榜也顯示不出來。

    這個問題我猜測,是 4G 的 Android 7.0+ 的 HTTP 頭和其他環境下不一樣,導致騰訊拒絕了頭像訪問,應該是封殺某音的時候,誤傷。

    解決這個問題最直接的辦法,就是在自己的服務器上,配置一條 NGINX 轉發協議。

    server {
    listen 80;
    #server_name h5.ooxx.cn;

    root /root/wwwroot/;

    location /image {
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass $arg_url;
    }
    }

    假如,我們的外網IP或者域名是 h5.ooxx.cn, 端口是 80,或者其他的。我們修改上面的訪問方式為如下:

    var headimg = ‘http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83erD6MOUwRKV9NyBAqnoFDTnltzAe2zWOkKxyDOFibVBb1ZV5CaATJwYAuNqZ5sXMBC4c8iacaHDf8RA/132’;
    var url = ‘http://h5.ooxx.cn:port/image?url=’ + headimg + ‘&sb=213.jpg’;
    cc.loader.load(url,function(err,tex){
    self.icon.spriteFrame = new cc.SpriteFrame(tex);
    });

    這樣改的原因如下:

    1、假如你做的是 H5 項目,h5.ooxx.cn 域名剛好就是你的頁面加載域名,那么你將處于同域中,不再有跨域問題。

    2、當我們請求最后合成的 URL 時,NGINX 會將 URL 參數作為請求地址,轉發出去,并且將獲取到的信息,原路返回。而我們添加的 proxy_redirect off 將會抹去我們系統機型為我們添加的各種 HTTP HEADER,不會再出現 Android 7.0+ 4G 網加載不了的問題。

    3、添加 &sb=213.jpg 參數,是為了讓 cc.loader.load 函數識別到這是一個圖片加載,但由于不是強制的填寫 type,即使 PNG 也是可以正常顯示的。

    C 姐補充:微信頭像加載問題,我們在 Cocos Creator v2.0.10 和 v2.1.1 也會完善,到時候將會直接支持噢!


    技巧二:微信名字截斷(支持表情)

    在我們日常游戲開發中,經常會面臨將玩家名字截斷的需求。

    假如玩家是在我們游戲中創建的名字,那么可以簡單粗暴地禁止玩家使用手機表情輸入即可。

    但如果我們是第三方賬號登錄,且使用了第三方賬號的用戶昵稱,那么這個就不好保證了。

    因此,為了配合界面的顯示,我們通常需要在特定界面上進行名字截斷。

    舉一個例子,假如我的名字是 麒麟子???? ,我們一眼看過去,是 5 個字。

    但在計算機中可不是 5 個字,即使是全部用 UTF8 表示字符的 Javascript 中,console.log(‘麒麟子??哈??’.length) 也是8.

    也就是說表情符號占用了 4 個字符,如果我們按 UTF8 去截斷,必然會導致亂碼。

    因此我們定義以下規則:

    ascii 字符,算 1 個字符

    漢字,算 2 個字符

    手機系統表情,算2 個字符 (因為它們雖然占了 4 個字符,但是從顯示寬度上來看,依然是 2 個字符)。

    下面的函數 strClamp 可助你一臂之力, 這是麒麟子從《幼麟棋牌》最新 5.0 框架中摳出來的代碼,希望能夠幫助到大家。

    //str 需要截斷的字符串
    //maxChars 保留的漢字長度
    //suffix 添加的后綴 (注意,如果后綴不為null或者” ,則要占用一個漢字的位置,具體看下方的示例代碼)

    function strClamp(str, maxChars, suffix) {
    var toCodePoint = function(unicodeSurrogates) {
    var r = [], c = 0, p = 0, i = 0;
    while (i < unicodeSurrogates.length) { var pos = i; c = unicodeSurrogates.charCodeAt(i++);//返回位置的字符的 Unicode 編碼 if (c == 0xfe0f) { continue; } if (p) { var value = (0x10000 + ((p – 0xD800) << 10) + (c – 0xDC00)); r.push({ v: value, pos: pos, }); //計算4字節的unicode p = 0; } else if (0xD800 <= c && c <= 0xDBFF) { p = c; //如果unicode編碼在oxD800-0xDBff之間,則需要與后一個字符放在一起 } else { r.push({ v: c, pos: pos }); //如果是2字節,直接將碼點轉為對應的十六進制形式 } } return r; } suffix = suffix==null? ‘…’ : suffix; maxChars *= 2; var codeArr = toCodePoint(str); var numChar = 0; var index = 0; for (var i = 0; i < codeArr.length; ++i) { var code = codeArr[i].v; var add = 1; if (code >= 128) {
    add = 2;
    }

    //如果超過了限制,則按上一個為準
    if (numChar + add > maxChars){
    break;
    }

    index = i;

    //累加
    numChar += add;
    }

    if(codeArr.length – 1 == index){
    return str;
    }

    var more = suffix? 1:0;

    return str.substring(0, codeArr[index – more].pos + 1) + suffix;
    }
    //示例:

    var str = ‘麒麟子??哈??;
    strClamp(str,3,’…’) // 得到 麒麟…
    strClamp(str,3,”) // 得到 麒麟子


    技巧三:微信小游戲中音效中斷問題處理

    音效可謂是一個小游戲的靈魂了。

    某些玩法離開了音效更是不可能,比如《別踩白塊》,或者一些以速度為主的游戲類型。

    麒麟子公司最近有一款斗地主上微信小游戲,另外還做了兩款休閑類小游戲。

    當我們覺得差不多大功告成的時候,有用戶反饋說,背景音樂突然就沒了,要返回大廳再進游戲場景才有。

    我當時第一反應就是,正在播放的音樂被干掉了,重新播放又是 OK 的。

    基于這個假設,那就表示這不是 Cocos Creator 的鍋。

    經過多方測試,找到了觸發微信小游戲聲音消失的重現辦法:

    (1)打接電話

    (2)觸摸 iPhone X 底部的那個白色操作條

    接下來就是一頓,百度,論壇,微信文檔操作,最后鎖定了一個微信 API

    wx.onAudioInterruptionEnd

    監聽音頻中斷結束事件,在收到 onAudioInterruptionBegin 事件之后,小程序內所有音頻會暫停,收到此事件之后才可再次播放成功。

    微信小游戲官方文檔地址:

    https://developers.weixin.qq.com/minigame/dev/api/wx.onAudioInterruptionEnd.html

    與它配套的還有一個 wx.onAudioInterruptionBegin 事件,但是我們是要恢復播放,只需要處理這個end 事件就好了。

    解決辦法:

    加上這個解決辦法,是方便急著解決 BUG 的同學們,忽略之前的分析過程,直接鎖定最終結果拿走,不謝!

    wx.onAudioInterruptionEnd(function(){
    //強行暫停音樂 如果不暫停,調用resumeMusic是無效的,因為是微信讓聲音消失了
    cc.audioEngine.pauseMusic();
    //恢復音樂播放,比如調用 cc.audioEngine.resumeMusic();
    //self.refreshBG();
    //console.log(‘refreshBG’);
    });

    注意:必須要先強行調用 cc.audioEngine.pauseMusic,再調用 cc.audioEngine.resumeMusic, 因為這個聲音是微信小游戲關掉的,Cocos Creator 的音樂管理器并不知情。


    技巧四:打包原生 App 截圖白屏解決方案

    大家在做棋牌 App 或者一些特定需求的時候,需要截取當前游戲屏幕內容保存。

    我們一般是采用 cc.RenderTexture 來截圖并保存到游戲的可寫目錄。

    有時候會遇上,截出來的圖片是白屏,或者部分白屏。

    經過多方測試,我們發現,是 Mask 的鍋,用了 cc.Mask 的界面,截圖的時候,就會遇上這樣的問題。

    如果遇上這樣的問題,只需要檢查你的 cc.RenderTexture 初始化的時候,是否少了參數。最主要的是第三個參數,一定要是 RGBA8888

    var texture = new cc.RenderTexture(w, h, cc.Texture2D.PIXEL_FORMAT_RGBA8888, gl.DEPTH24_STENCIL8_OES);

    完整示例如下:

    function captureScreen(){
    var size = cc.director.getWinSize();
    var fileName = “result_share.jpg”;
    var fullPath = jsb.fileUtils.getWritablePath() + fileName;
    if (jsb.fileUtils.isFileExist(fullPath)) {
    jsb.fileUtils.removeFile(fullPath);
    }
    var width = Math.floor(size.width);
    var height = Math.floor(size.height);
    var texture = new cc.RenderTexture(width, height, cc.Texture2D.PIXEL_FORMAT_RGBA8888, gl.DEPTH24_STENCIL8_OES);
    texture.setPosition(cc.p(size.width / 2, size.height / 2));
    texture.begin();
    cc.director.getRunningScene().visit();
    texture.end();
    texture.saveToFile(fileName, cc.IMAGE_FORMAT_JPG);
    }


    技巧五:技能 CD 效果制作

    此效果不僅可以用于技能 CD,一些按鈕的 CD 也是可以用的。

    麒麟子一開始預備了兩個套路:

    一、是準備 100 張圖片,然后根據 CD 進度進行切換

    對于第一個方案,肯定是可行的,且不需要引擎提供特殊支持。而由于麒麟子的 PS 功力有限,沒有折騰出來。值得說明的是,此方案適用于任何引擎,只要有對應的美術圖片配合就行。

    二、繪制 100 個 Graphics 作為緩存,然后根據 CD 進度進行切換

    麒麟子創建了一個節點,添加了一個 cc.Graphics 組件。最后發現,cc.Graphics 的 arc 函數,并不能繪制出我想要的效果。既然沒有直接支持的函數,想必 Cocos Creator 并不推薦這樣的操作,放棄了。

    思索了半分鐘,抱著試一試的心態,打開了 ProgressBar 的組件,畢竟,CD 效果從本質上來說,是一個倒著播放的進度條。

    三、最終,找到了基于 ProgressBar 組件的解決方案

    1、場景樹右鍵 –> 新建 –> UI 組件 –>ProgressBar 組件

    2、修改 New ProgressBar 以及其子節點 bar 的寬高, 調為正方形,且錨點為 0.5,0.5

    3、修改 bar 的填充模式,如下(注意紅色箭頭部分)

    4、修改 New ProgressBar 的參數如下(注意紅色箭頭部分)

    然后拖動 Progress 就能看到變化了。

    四、DEMO

    DEMO 向大家展示了以下內容:

    技能點擊響應

    技能 CD 根據不同的時間,進行 CD 效果旋轉

    為了匹配技能效果,我旋轉了技能 CD 層的節點

    DEMO 源代碼地址:

    https://gitee.com/qilinzi/qlz_ccc_tips(目錄 05_skill_cd)


    寫在最后

    我建了兩個群,一個是棋牌的,一個是非棋牌的,大家有興趣的可以加入。
    幼麟棋牌社區官方群:176294790
    Cocos Creator 交流中心:727901932

    非常感謝麒麟子帶來的 Cocos Creator 干貨分享,相信對于 Cocos 新手小白黨應該很有學習意義,上述提及到的跟引擎相關的問題,我們也將在后續版本中進行完善,期待麒麟子后續帶來更多的教程。

    同時也非常感謝各位開發者對 Cocos 社區所做出的貢獻以及對 Cocos 的信任與支持,在引擎的使用過程中,如有遇到任何問題,或者是有對 Cocos 的意見和建議,歡迎大家多多在社區中發帖交流噢,祝大家周末愉快!

    女人脱裤子让男生桶爽免费看,久青草无码视频在线播放,精品国产人成亚洲区,久久精品国产亚洲一区二区