能滑动的排行榜

参考: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);

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值