• Egret5.2.2 微信小游戏行的示例排行榜


    Egret5.2.2版本发布微信小游戏后,在开放数据域有一个默认排行榜。这个文件夹代码+图大小就22kb。

    排行榜的效果就是示范用的,很丑...带翻页。

      

    代码如下,基本就是使用canvas渲染了一个排行榜。

    好处是不需要额外新建另一个Egret项目来实现排行榜,减小了代码体积。

    坏处是canvas手动绘制排行榜,没有egret的eui可视化编辑,非常的不方便。

    代码很长,慢慢看....

    /**
     * 微信开放数据域
     * 使用 Canvas2DAPI 在 SharedCanvas 渲染一个排行榜,
     * 并在主域中渲染此 SharedCanvas
     */
    
    
    
    
    
    
    
    /**
     * 资源加载组,将所需资源地址以及引用名进行注册
     * 之后可通过assets.引用名方式进行获取
     */
    var assets = {
      icon: "openDataContext/assets/icon.png",
      box: "openDataContext/assets/box.png",
      panel: "openDataContext/assets/panel.png",
      button: "openDataContext/assets/button.png",
      title: "openDataContext/assets/rankingtitle.png"
    };
    /**
     * canvas 大小
     * 这里暂时写死
     * 需要从主域传入
     */
    let canvasWidth;
    let canvasHeight;
    
    /**
     * 加载资源函数
     * 理论上只需要加载一次,且在点击时才开始加载
     * 最好与canvasWidht和canvasHeight数据的传入之后进行
     */
    preloadAssets();
    
    //获取canvas渲染上下文
    var context = sharedCanvas.getContext("2d");
    context.globalCompositeOperation = "source-over";
    
    
    /**
     * 所有头像数据
     * 包括姓名,头像图片,得分
     * 排位序号i会根据parge*perPageNum+i+1进行计算
     */
    let totalGroup = [
      { key: 1, name: "1111111111", url: assets.icon, scroes: 10000 },
      { key: 2, name: "2222222222", url: assets.icon, scroes: 9000 },
      { key: 3, name: "3333333", url: assets.icon, scroes: 8000 },
      { key: 4, name: "4444444", url: assets.icon, scroes: 7000 },
      { key: 5, name: "55555555", url: assets.icon, scroes: 6000 },
      { key: 6, name: "6666666", url: assets.icon, scroes: 5000 },
      { key: 7, name: "7777777", url: assets.icon, scroes: 4000 },
      { key: 8, name: "8888888", url: assets.icon, scroes: 3000 },
      { key: 9, name: "9999999", url: assets.icon, scroes: 2000 },
      { key: 10, name: "1010101010", url: assets.icon, scroes: 2000 },
      { key: 11, name: "111111111111", url: assets.icon, scroes: 2000 },
      { key: 12, name: "121212121212", url: assets.icon, scroes: 2000 },
      { key: 13, name: "13131313", url: assets.icon, scroes: 2000 },
      { key: 14, name: "1414141414", url: assets.icon, scroes: 2000 },
      { key: 15, name: "1515151515", url: assets.icon, scroes: 2000 },
      { key: 16, name: "1616161616", url: assets.icon, scroes: 2000 },
    ];
    
    /**
     * 创建排行榜
     */
    function drawRankPanel() {
      //绘制背景
      context.drawImage(assets.panel, offsetX_rankToBorder, offsetY_rankToBorder, RankWidth, RankHeight);
      //绘制标题
      let title = assets.title;
      //根据title的宽高计算一下位置;
      let titleX = offsetX_rankToBorder + (RankWidth - title.width) / 2;
      let titleY = offsetY_rankToBorder + title.height + 50;
      context.drawImage(title, titleX, titleY);
      //获取当前要渲染的数据组
      let start = perPageMaxNum * page;
      currentGroup = totalGroup.slice(start, start + perPageMaxNum);
      //创建头像Bar
      drawRankByGroup(currentGroup);
      //创建按钮
      drawButton()
    }
    /**
     * 根据屏幕大小初始化所有绘制数据
     */
    function init() {
      //排行榜绘制数据初始化
      RankWidth = stageWidth * 4 / 5;
      RankHeight = stageHeight * 4 / 5;
      barWidth = RankWidth * 4 / 5;
      barHeight = RankWidth / perPageMaxNum;
      offsetX_rankToBorder = (stageWidth - RankWidth) / 2;
      offsetY_rankToBorder = (stageHeight - RankHeight) / 2;
      preOffsetY = (RankHeight - barHeight) / (perPageMaxNum + 1);
    
      startX = offsetX_rankToBorder + offsetX_rankToBorder;
      startY = offsetY_rankToBorder + preOffsetY;
      avatarSize = barHeight - 10;
      intervalX = barWidth / 20;
      textOffsetY = (barHeight + fontSize) / 2;
      textMaxSize = 250;
      indexWidth = context.measureText("99").width;
    
      //按钮绘制数据初始化
      buttonWidth = barWidth / 3;
      buttonHeight = barHeight / 2;
      buttonOffset = RankWidth / 3;
      lastButtonX = offsetX_rankToBorder + buttonOffset - buttonWidth;
      nextButtonX = offsetX_rankToBorder + 2 * buttonOffset;
      nextButtonY = lastButtonY = offsetY_rankToBorder + RankHeight - 50 - buttonHeight;
      let data = wx.getSystemInfoSync();
      canvasWidth = data.windowWidth;
      canvasHeight = data.windowHeight;
    }
    
    /**
     * 创建两个点击按钮
     */
    function drawButton() {
      context.drawImage(assets.button, nextButtonX, nextButtonY, buttonWidth, buttonHeight);
      context.drawImage(assets.button, lastButtonX, lastButtonY, buttonWidth, buttonHeight);
    }
    
    
    /**
     * 根据当前绘制组绘制排行榜
     */
    function drawRankByGroup(currentGroup) {
      for (let i = 0; i < currentGroup.length; i++) {
        let data = currentGroup[i];
        drawByData(data, i);
      }
    }
    
    /**
     * 根据绘制信息以及当前i绘制元素
     */
    function drawByData(data, i) {
      let x = startX;
      //绘制底框
      context.drawImage(assets.box, startX, startY + i * preOffsetY, barWidth, barHeight);
      x += 10;
      //设置字体
      context.font = fontSize + "px Arial";
      //绘制序号
      context.fillText(data.key + "", x, startY + i * preOffsetY + textOffsetY, textMaxSize);
      x += indexWidth + intervalX;
      //绘制头像
      context.drawImage(data.url, x, startY + i * preOffsetY + (barHeight - avatarSize) / 2, avatarSize, avatarSize);
      x += avatarSize + intervalX;
      //绘制名称
      context.fillText(data.name + "", x, startY + i * preOffsetY + textOffsetY, textMaxSize);
      x += textMaxSize + intervalX;
      //绘制分数
      context.fillText(data.scroes + "", x, startY + i * preOffsetY + textOffsetY, textMaxSize);
    }
    
    /**
     * 点击处理
     */
    function onTouchEnd(event) {
      let x = event.clientX * sharedCanvas.width / canvasWidth;
      let y = event.clientY * sharedCanvas.height / canvasHeight;
      if (x > lastButtonX && x < lastButtonX + buttonWidth
        && y > lastButtonY && y < lastButtonY + buttonHeight) {
        //在last按钮的范围内
        if (page > 0) {
          buttonClick(0);
    
        }
      }
      if (x > nextButtonX && x < nextButtonX + buttonWidth
        && y > nextButtonY && y < nextButtonY + buttonHeight) {
        //在next按钮的范围内
        if ((page + 1) * perPageMaxNum < totalGroup.length) {
          buttonClick(1);
        }
      }
    
    }
    /**
     * 根据传入的buttonKey 执行点击处理
     * 0 为上一页按钮
     * 1 为下一页按钮
     */
    function buttonClick(buttonKey) {
      let old_buttonY;
      if (buttonKey == 0) {
        //上一页按钮
        old_buttonY = lastButtonY;
        lastButtonY += 10;
        page--;
        renderDirty = true;
        console.log('上一页');
        setTimeout(() => {
          lastButtonY = old_buttonY;
          //重新渲染必须标脏
          renderDirty = true;
        }, 100);
      } else if (buttonKey == 1) {
        //下一页按钮
        old_buttonY = nextButtonY;
        nextButtonY += 10;
        page++;
        renderDirty = true;
        console.log('下一页');
        setTimeout(() => {
          nextButtonY = old_buttonY;
          //重新渲染必须标脏
          renderDirty = true;
        }, 100);
      }
    
    }
    
    /////////////////////////////////////////////////////////////////// 相关缓存数据
    
    /**********************数据相关***************************/
    
    /**
     * 渲染标脏量
     * 会在被标脏(true)后重新渲染
     */
    let renderDirty = true;
    
    /**
     * 当前绘制组
     */
    let currentGroup = [];
    /**
     * 每页最多显示个数
     * 建议大于等于4个
     */
    let perPageMaxNum = 5;
    /**
     * 当前页数,默认0为第一页
     */
    let page = 0;
    /***********************绘制相关*************************/
    /**
     * 舞台大小
     */
    let stageWidth;
    let stageHeight;
    /**
     * 排行榜大小
     */
    let RankWidth;
    let RankHeight;
    
    /**
     * 每个头像条目的大小
     */
    let barWidth;
    let barHeight;
    /**
     * 条目与排行榜边界的水平距离
     */
    let offsetX_barToRank
    /**
     * 绘制排行榜起始点X
     */
    let startX;
    /**
     * 绘制排行榜起始点Y
     */
    let startY;
    /**
     * 每行Y轴间隔offsetY
     */
    let preOffsetY;
    /**
     * 按钮大小
     */
    let buttonWidth;
    let buttonHeight;
    /**
     * 上一页按钮X坐标
     */
    let lastButtonX;
    /**
     * 下一页按钮x坐标
     */
    let nextButtonX;
    /**
     * 上一页按钮y坐标
     */
    let lastButtonY;
    /**
     * 下一页按钮y坐标
     */
    let nextButtonY;
    /**
     * 两个按钮的间距
     */
    let buttonOffset;
    
    /**
     * 字体大小
     */
    let fontSize = 45;
    /**
     * 文本文字Y轴偏移量
     * 可以使文本相对于图片大小居中
     */
    let textOffsetY;
    /**
     * 头像大小
     */
    let avatarSize;
    /**
     * 名字文本最大宽度,名称会根据
     */
    let textMaxSize;
    /**
     * 绘制元素之间的间隔量
     */
    let intervalX;
    /**
     * 排行榜与舞台边界的水平距离
     */
    let offsetX_rankToBorder;
    /**
     * 排行榜与舞台边界的竖直距离
     */
    let offsetY_rankToBorder;
    /**
     * 绘制排名的最大宽度
     */
    let indexWidth;
    
    //////////////////////////////////////////////////////////
    /**
     * 监听点击
     */
    wx.onTouchEnd((event) => {
      var l = event.changedTouches.length;
      for (var i = 0; i < l; i++) {
        onTouchEnd(event.changedTouches[i]);
      }
    });
    
    
    /**
     * 资源加载
     */
    function preloadAssets() {
      var preloaded = 0;
      var count = 0;
      for (var asset in assets) {
        count++;
        var img = wx.createImage();
        img.onload = function () {
          preloaded++;
          if (preloaded == count) {
            setTimeout(function () {
              createScene();
            }, 500);
          }
        }
        img.src = assets[asset];
        assets[asset] = img;
      }
    }
    /**
     * 绘制屏幕
     * 这个函数会在加载完所有资源之后被调用
     */
    function createScene() {
      if (sharedCanvas.width && sharedCanvas.height) {
        console.log('初始化完成')
        stageWidth = sharedCanvas.width;
        stageHeight = sharedCanvas.height;
      } else {
        console.log(`sharedCanvas.${sharedCanvas.width}    sharedCanvas.height:${sharedCanvas.height}`)
      }
      init();
      requestAnimationFrame(loop);
    }
    /**
     * 循环函数
     * 每帧判断一下是否需要渲染
     * 如果被标脏,则重新渲染
     */
    function loop() {
      if (renderDirty) {
        console.log(`stageWidth :${stageWidth}   stageHeight:${stageHeight}`)
        context.setTransform(1, 0, 0, 1, 0, 0);
        context.clearRect(0, 0, sharedCanvas.width, sharedCanvas.height);
        drawRankPanel();
        renderDirty = false;
      }
      requestAnimationFrame(loop);
    }
    

      

  • 相关阅读:
    第五章.函数
    第四章.文件操作
    第三章.数据类型
    PyYaml简单学习
    Vim编辑器基本用法
    numpy.ndarray.transpose用法理解
    Django Formsets总结
    学习,认知,思维
    Django model总结(上)
    结合pandas,sqlite3批量将csv数据导入sqlite数据库
  • 原文地址:https://www.cnblogs.com/gamedaybyday/p/9196621.html
Copyright © 2020-2023  润新知