楼主,请教一下,这个方法可以在子域里面使用使用UI的Prefab来显示吗。
mark
绘制的排名闪一下就不见了,这个什么情况呢?怎样可以不用子域工程呢?
怎么解决的?
楼主你好,你创建的是creator工程么?我直接打开打不开
我怎么编辑帖子啊,现在帖的有点bug,我想修改下
帖子内容写的有点bug,滑动效率太低。因为我修改了排行榜实现。在子域中先将排行榜绘制到离屏canvas中,滑动的时候根据滑动距离将离屏canvas相关内容绘制到sharedCanvas,再将sharedCanvas绘制到主域中。这样解决了原版实现滑动卡顿的问题。
主域代码如下
import * as Consts from "./consts"
import {appdata} from './appdata'
import {POP_UI_BASE} from './common/ui/pop_ui_base'
import {pop_mgr, UI_CONFIG} from "./common/ui/pop_mgr"
import {TimerMgr} from "./common/timer/timer_mgr"
import * as utils from "./common/util"
import * as wxapi from "./common/wxapi"
import * as Audio from "./common/audio/audioplayer"
const {ccclass, property} = cc._decorator;
@ccclass
export class RankView2 extends POP_UI_BASE {
@property(cc.Sprite)
img_rank: cc.Sprite = null;
timerId:number;
isDirty:boolean;
rankTexture:cc.Texture2D;
rankSpriteFrame:cc.SpriteFrame;
on_show(...params)
{
//只能在主域设置大小, 且要先于赋值到sprite才起作用
const sharedCanvas = wxapi.wxOpenData.wxGetSharedCanvas();
sharedCanvas.width = this.img_rank.node.width;
sharedCanvas.height = this.img_rank.node.height;
this.rankTexture = new cc.Texture2D();
this.rankSpriteFrame = new cc.SpriteFrame();
//拿好友排行榜
this.isDirty = true;
wxapi.wxOpenData.wxPostMessageToSubDomain({
action:wxapi.WxDomainAction.FetchFriend,
});
this.timerId = TimerMgr.getInst().addUpdater(utils.gen_handler(this.updateRankList, this));
this.img_rank.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
}
on_hide()
{
this.rankTexture = null;
this.rankSpriteFrame = null;
this.isDirty = false;
TimerMgr.getInst().remove(this.timerId);
this.img_rank.node.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
}
private lastDeltaY:number;
onTouchMove(event:cc.Event.EventTouch)
{
const deltaY = event.getDeltaY();
if(this.lastDeltaY == deltaY)
{
return;
}
this.lastDeltaY = deltaY;
// console.log("rank touchmove:", deltaY);
this.isDirty = true;
wxapi.wxOpenData.wxPostMessageToSubDomain({
action:wxapi.WxDomainAction.Paging,
data:deltaY,
});
}
updateRankList()
{
if(!this.isDirty)
{
return;
}
const sharedCanvas = wxapi.wxOpenData.wxGetSharedCanvas();
this.rankTexture.initWithElement(sharedCanvas);
this.rankTexture.handleLoadedTexture();
this.rankSpriteFrame.setTexture(this.rankTexture);
this.img_rank.spriteFrame = this.rankSpriteFrame;
}
onTouchGroupRank()
{
report.getShareInfo(res => {
wxapi.wxShare.share(
{
title:res.text,
imageUrl:res.image,
query:`openID=${appdata.appUserInfo.openid}`,
},
utils.gen_handler((shareTickets:string[]) => {
if(!shareTickets || !shareTickets.length)
{
console.log('本次分享无shareTicket');
return;
}
const shareTicket = shareTickets[0];
this.isDirty = true;
wxapi.wxOpenData.wxPostMessageToSubDomain({
action:wxapi.WxDomainAction.FetchGroup,
data:shareTicket,
});
}, this),
);
}, this);
Audio.AudioPlayer.getInst().play_sound(Audio.AUDIO_CONFIG.Audio_Btn);
}
onTouchPlayBtn()
{
this.hide();
if(wxapi.wxSession.get())
{
pop_mgr.get_inst().show(UI_CONFIG.level);
}
}
}
子域代码如下:
import * as Consts from './consts'
const ITEM_HEIGHT = 125;
const PAGE_SIZE = 10;
const RANK_PAGE_HEIGHT = ITEM_HEIGHT * PAGE_SIZE;
const dataSorter = (gameDatas, field = Consts.OpenDataKeys.Grade) => {
return gameDatas.sort((a, b) => {
const kvDataA = a.KVDataList.find(kvData => kvData.key === Consts.OpenDataKeys.Grade);
const kvDataB = b.KVDataList.find(kvData => kvData.key === Consts.OpenDataKeys.Grade);
const gradeA = kvDataA ? parseInt(kvDataA.value || 0) : 0;
const gradeB = kvDataB ? parseInt(kvDataB.value || 0) : 0;
return gradeA > gradeB ? -1 : gradeA < gradeB ? 1 : 0;
});
}
//"openDataContext": "subdomain",
class RankListRenderer {
constructor() {
}
init() {
if(this.isInited) {
return;
}
this.isInited = true;
// console.log("RanklListRenderer init");
this.offsetY = 0;
this.contentHeight = 0;
this.gameDatas = []; //https://developers.weixin.qq.com/minigame/dev/document/open-api/data/UserGameData.html
const sharedCanvas = wx.getSharedCanvas();
this.sharedCtx = sharedCanvas.getContext('2d');
this.sharedCanvasWidth = sharedCanvas.width;
this.sharedCanvasHeight = sharedCanvas.height;
this.rankCanvasList = [];
this.rankImgLoadingCnt = [];
}
listen() {
//msg -> {action, data}
wx.onMessage(msg => {
//console.log("ranklist wx.onMessage", msg);
this.init();
switch (msg.action) {
case Consts.DomainAction.FetchFriend:
this.fetchFriendData();
break;
case Consts.DomainAction.FetchGroup:
if (!msg.data) {
return;
}
this.fetchGroupData(msg.data);
break;
case Consts.DomainAction.Paging:
if (!this.gameDatas.length) {
return;
}
const deltaY = msg.data;
const newOffsetY = this.offsetY + deltaY;
if (newOffsetY < 0) {
// console.log("前面没有更多了");
return;
}
if (newOffsetY + this.sharedCanvasHeight > this.contentHeight) {
// console.log("后面没有更多了");
return;
}
this.offsetY = newOffsetY;
this.drawSharedCanvas(newOffsetY);
break;
default:
console.log(`未知消息类型:msg.action=${msg.action}`);
break;
}
});
}
fetchGroupData(shareTicket) {
//取出群同玩成员数据
wx.getGroupCloudStorage({
shareTicket,
keyList: [
Consts.OpenDataKeys.Grade,
],
success: res => {
console.log("wx.getGroupCloudStorage success", res);
const dataLen = res.data.length;
this.gameDatas = dataSorter(res.data);
this.offsetY = 0;
this.contentHeight = dataLen * ITEM_HEIGHT;
if (dataLen) {
this.rankCanvasList.length = 0;
this.drawSharedCanvas(0);
}
},
fail: res => {
console.log("wx.getGroupCloudStorage fail", res);
},
});
}
fetchFriendData() {
//取出所有好友数据
wx.getFriendCloudStorage({
keyList: [
Consts.OpenDataKeys.Grade,
],
success: res => {
console.log("wx.getFriendCloudStorage success", res);
const dataLen = res.data.length;
this.gameDatas = dataSorter(res.data);
this.offsetY = 0;
this.contentHeight = dataLen * ITEM_HEIGHT;
if (dataLen) {
this.rankCanvasList.length = 0;
this.drawSharedCanvas(0);
}
},
fail: res => {
console.log("wx.getFriendCloudStorage fail", res);
},
});
}
drawSharedCanvas(offsetY) {
//清除sharedCanvas旧内容
const sharedWidth = this.sharedCanvasWidth;
const sharedHeight = this.sharedCanvasHeight;
this.sharedCtx.clearRect(0, 0, sharedWidth, sharedHeight);
//分页,绘制多个rankCanvas,再将rankCanvas内容绘制到sharedCanvas
const pageY = offsetY % RANK_PAGE_HEIGHT;
const pageIndex = Math.floor(offsetY / RANK_PAGE_HEIGHT);
const isOverOnePage = pageY + sharedHeight > RANK_PAGE_HEIGHT;
let rankCanvas = this.getPagedRankCanvas(pageIndex);
if(!isOverOnePage) {
this.sharedCtx.drawImage(rankCanvas, 0, pageY, sharedWidth, sharedHeight, 0, 0, sharedWidth, sharedHeight);
} else {
//绘制当前页后半部分
const partialHeight = RANK_PAGE_HEIGHT - pageY;
this.sharedCtx.drawImage(rankCanvas, 0, pageY, sharedWidth, partialHeight, 0, 0, sharedWidth, partialHeight);
//绘制下一页前半部分
rankCanvas = this.getPagedRankCanvas(pageIndex + 1);
this.sharedCtx.drawImage(rankCanvas, 0, 0, sharedWidth, sharedHeight - partialHeight, 0, partialHeight, sharedWidth, sharedHeight - partialHeight);
}
}
getPagedRankCanvas(pageIndex) {
let canvas = this.rankCanvasList[pageIndex];
if(!canvas) {
canvas = wx.createCanvas();
canvas.width = this.sharedCanvasWidth;
canvas.height = RANK_PAGE_HEIGHT;
this.rankCanvasList[pageIndex] = canvas;
this.rankImgLoadingCnt[pageIndex] = 0;
const ctx = canvas.getContext('2d');
this.drawPagedRanks(ctx, pageIndex, () => {
if(this.rankImgLoadingCnt[pageIndex] == 0) {
this.drawSharedCanvas(this.offsetY);
}
});
}
return canvas;
}
drawPagedRanks(ctx, pageIndex, cb) {
for(let i = 0; i < PAGE_SIZE; i++) {
const pageOffset = pageIndex * PAGE_SIZE;
const data = this.gameDatas[pageOffset + i];
if(!data) continue;
this.drawRankItem(ctx, pageIndex, i, pageOffset + i + 1, data, cb);
}
}
//canvas原点在左上角
drawRankItem(ctx, pageIndex, dataIndex, rank, data, cb) {
const nick = data.nickname.length <= 10 ? data.nickname : data.nickname.substr(0, 10) + "...";
const kvData = data.KVDataList.find(kvData => kvData.key === Consts.OpenDataKeys.Grade);
const grade = kvData ? kvData.value : 0;
const itemGapY = ITEM_HEIGHT * dataIndex;
//背景颜色
if (rank % 2 == 1) {
// ctx.fillStyle = "#FBF7E4";
ctx.fillStyle = "#C6C3B4";
ctx.fillRect(0, itemGapY, this.sharedCanvasWidth, ITEM_HEIGHT);
}
//名次
if (rank < 4) {
const rankImg = wx.createImage();
rankImg.src = `subdomain/images/llk_phb_icon${rank}.png`;
this.rankImgLoadingCnt[pageIndex]++;
rankImg.onload = () => {
ctx.drawImage(rankImg, 55, 30 + itemGapY, 78, 82);
this.rankImgLoadingCnt[pageIndex]--;
cb && cb();
};
} else {
ctx.fillStyle = "#777063";
ctx.textAlign = "right";
ctx.baseLine = "middle";
ctx.font = "50px Helvetica";
ctx.fillText(`${rank}`, 100, 80 + itemGapY);
}
//头像
const avatarX = 125;
const avatarY = 25 + itemGapY;
const avatarW = 80;
const avatarH = 80;
this.drawAvatar(ctx, data.avatarUrl, avatarX, avatarY, avatarW, avatarH, pageIndex, cb);
//名字
ctx.fillStyle = "#777063";
ctx.textAlign = "left";
ctx.baseLine = "middle";
ctx.font = "30px Helvetica";
ctx.fillText(nick, 220, 80 + itemGapY);
//分数
ctx.fillStyle = "#777063";
ctx.textAlign = "left";
ctx.baseLine = "middle";
ctx.font = "30px Helvetica";
ctx.fillText(`${grade}分`, 620, 80 + itemGapY);
}
drawAvatar(ctx, avatarUrl, x, y, w, h, pageIndex, cb) {
avatarUrl = avatarUrl.substr(0, avatarUrl.lastIndexOf('/')) + "/132";
ctx.fillStyle = "#ffffff";
ctx.fillRect(x - 5, y - 5, w + 10, h + 10);
const avatarImg = wx.createImage();
avatarImg.src = avatarUrl;
this.rankImgLoadingCnt[pageIndex]++;
avatarImg.onload = () => {
ctx.drawImage(avatarImg, x, y, w, h);
this.rankImgLoadingCnt[pageIndex]--;
cb && cb();
};
}
}
const rankList = new RankListRenderer();
rankList.listen();
1赞
我改了实现,我下面楼层我贴的最新代码
我改了实现,我下面楼层我贴的最新代码22222
我改了实现,我下面楼层我贴的最新代码333333
1赞
哪里有排行榜初级教程啊? 看不懂~
兄弟,你这头像出自哪个动漫呢?
一人之下
非常感谢!!楼主真好人
请教楼主,您的库中使用的Map是自己定义的吗?
mark
请教楼主,你的Map是怎么实现的?为什么可以存cc.Component类型的key ?
楼主 只支持es5的手机报错
我这边用原生的绘排行榜,es5的系统排行榜就是画出来乱七八糟的游戏资源贴图!
那你换成object字典就行呀