能滑動的排行榜

參考:http://www.pianshen.com/article/876094934/

好友排行榜微信只讓我們在開放數據域(後文都簡稱爲”子域”)裏面操作(畢竟這是人家最重要最值錢的數據了,不會讓我們拿來隨便用的),小遊戲做好後,想加入排行榜和超越好友等功能,白鷺官方也給出了詳細的教程了。目前官網的demo排行榜是分頁的,點擊查看下一頁數據,不能像scrollView那樣滾動展示數據,不是我想要的,我看了下其他人做的,說可以用一個項目做遊戲,一個項目專門放排行榜,放排行榜的項目直接導出到遊戲項目的openDataContext文件夾下。我也試着操作了下,發現坑有點難踩,遇到了個wx.getFileSystemManager not function的錯誤,後面發現在5.2.2中,使用assetsmananger而不是res,解決方案。而且這樣會多引入一次egret和game庫,其實好像也就多幾百KB而已。第一種方案;這裏我着重說一下另外一個方案,就是目前官方demo那種,在js裏面直接用canvas做出類似於scrollView那種滾動效果,其實就是監聽下Y軸滑動距離,根據滑動距離來處理canvas的位置。
想要排行榜有數據,就先上傳用戶數據到微信後臺,就是託管數據。我是在比賽結束的時候發送一個消息給子域,此消息帶上用戶分數。


   platform["openDataContext"].postMessage({

           command: 'updateMaxScore',

           myScore: _myScore

      });

    然後在子域的index.js裏面監聽並處理這個消息


else if (data.command == 'updateMaxScore') {

      if (myCurrentScore <= data.myScore) {

        setUserCloudStorage(data.myScore);

      }

      getFriendCloudInfo();

}

這個setUserCloudStorage加了個上傳時間的操作,用於之後通過時間來處理週一數據清零的操作,後面會貼上完整代碼。上傳新分數後再通過getFriendCloudInfo拿新數據並過濾排序。在排行榜界面先創建一個離屏canvas
 


let bitmap_rank = platform["openDataContext"].createDisplayObject(null,this.stageW, rank_item_bg_Group.height, 0);

bitmap_rank.y = 80;

rank_item_bg_Group.addChild(bitmap_rank);

rank_item_bg_Group就是圖中綠色框部分,在這個上面添加canvas,方便位置調整。然後傳消息給後臺根據是否有shareTicket來顯示是好友排行榜還是羣排行榜。


        let delayTime = 0;

        if(game.myShareTicket != undefined && game.myShareTicket != ""){

            delayTime = 1000;

        }

        setTimeout((e)=> {

                platform["openDataContext"].postMessage({

                    command: "open",

                    shareTicket: game.myShareTicket

                });

        }, delayTime);

createScene創建的是除圖上紅色框之外的排行榜內容,createMyScene創建的是我的內容,就是紅色框那塊,其實可以合併到一起的,後期再整理一下。微信頭像和圖片一樣做一下預加載,先拿到頭像數據保存起來,再預加載。


function preloadAvatarUrl() {

  let preloaded = 0;

  let count = 0;

  for (let asset in avatarUrlList) {

    count++;

    const img = wx.createImage();

    img.onload = () => {

      preloaded++;

      if (preloaded == count) {

        // console.log("頭像加載完成");

        hasLoadRes = true;

      }

    }

    // console.log("src:" + avatarUrlList[asset] + " asset:" + asset);

    img.src = avatarUrlList[asset];

    assetsAvatarUrl[asset] = img;

  }

}

這個是給排行榜排序,根據用戶分數做降序處理


//給排行榜排序(降序)

var compare = function (prop) {

  return function (obj1, obj2) {

    var val1 = obj1[prop];

    var val2 = obj2[prop];

    var int1 = val1[0]["value"];

    var int2 = val2[0]["value"];

    if (!isNaN(Number(int1)) && !isNaN(Number(int2))) {

      int1 = Number(int1);

      int2 = Number(int2);

    }

    if (int1 < int2) {

      return 1;

    } else if (int1 > int2) {

      return -1;

    } else {

      return 0;

    }

  }

}

這個是根據上傳分數時帶的時間戳判斷分數是否是同一周,大致思路是首先新的天數要大於老的天數,週日的天數通過getDay()獲取到時是0,轉爲7,方便處理,然後天數不同通過時間戳差值判斷是否在一週內,如果天數相同則判斷差值是否在一天內,防止這週一早上10點和下週一早上9點被判斷成一週。


//判斷是否是同一周

function isSameWeek(oldTime) {

  oldTime = parseInt(oldTime);

  var newTime = new Date().getTime();

  let oneDayTime = 60 * 60 * 24 * 1000;

  // console.log("now:" + newTime + " old:" + oldTime + " off:" + (newTime - oldTime) + " one:" + (oneDayTime * 7))

  let oldDate = new Date(oldTime);

  let newDate = new Date(newTime);

 

  let oldDay = oldDate.getDay();

  let newDay = newDate.getDay();

  if (newDay == 0) {

    newDay = 7;

  }

  if (oldDay == 0) {

    oldDay = 7;

  }

  let isSame = false;

 

  if (oldDay < newDay) {

    if ((newTime - oldTime) < oneDayTime * 7) {  // 時間相差小於7

      isSame = true;

    }

  } else if (oldDay == newDay) {

    if ((newTime - oldTime) < oneDayTime) {

      isSame = true;

    }

  }

  return isSame;

}

 

platform.js裏面也改造了下


    createDisplayObject(type, width, height,offsetY) {

        sharedCanvas.width = width;

        sharedCanvas.height = height;

        const bitmapdata = new egret.BitmapData(sharedCanvas);

        bitmapdata.$deleteSource = false;

        const texture = new egret.Texture();

        texture._setBitmapData(bitmapdata);

        const bitmap = new egret.Bitmap(texture);

 

        bitmap.width = width;

        bitmap.height = height;

        bitmap.y = offsetY;

        if (egret.Capabilities.renderMode == "webgl") {

            const renderContext = egret.wxgame.WebGLRenderContext.getInstance();

            const context = renderContext.context;

            ////需要用到最新的微信版本

            ////調用其接口WebGLRenderingContext.wxBindCanvasTexture(number texture, Canvas canvas)

            ////如果沒有該接口,會進行如下處理,保證畫面渲染正確,但會佔用內存。

            if (!context.wxBindCanvasTexture) {

                egret.startTick((timeStarmp) => {

                    egret.WebGLUtils.deleteWebGLTexture(bitmapdata.webGLTexture);

                    bitmapdata.webGLTexture = null;

                    return false;

                }, this);

            }

        }

        return bitmap;

    }

 

排行榜好友我是隻顯示7個,根據Y軸滑動距離來判斷顯示哪7個數據就行,具體方法看後面代碼,寫的太多了,大家不一定有耐心看了,好久沒寫博客,有點亂,好像拆開寫比較合適啊。

下面是index.js詳細代碼,貼了全部代碼,發現顯示不了那麼多。就當附件傳上來吧,附件找不到在哪裏傳,就先直接上傳到資源裏吧index.js順便貼幾張子域效果圖。

 

子域的數據可以傳給主域了,一個qq羣裏同學說的,驗證了下,的確可以,現分享給大家。
在子域裏獲取到排行榜數據後,userDataList保存數據然後如下寫法:


      let openContext = wx.getSharedCanvas().getContext("2d");

      openContext["canvas"]["userDataList"] = JSON.stringify(userDataList);

在主域裏通過如下寫法可以拿到子域保存的排行榜數據,這些就可以在主域直接用ScrollView了,哎,發現的有點晚了啊。


        let openContext = wx.getOpenDataContext();

        let friendDataList:any;

        if(openContext["canvas"]["userDataList"]){

            friendDataList = JSON.parse(openContext["canvas"]["userDataList"]);

        }

        console.log("openContext");

        console.log(openContext);

        console.log("friendDataList");

        console.log(friendDataList);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章