我々は、すべての小と雷の現在フルマイクロチャネルのゲームプログラム、多くの企業が徐々に早く自社製品を促進し、ユーザーグループをつかむために、関連するビジネスラインを増加していることを知っています。それは、マイクロチャネルの試合に出たとき、あなたはランキングにこの機能を言及する必要があり、現在のゲーム業界は、ランキングこの重要な機能から、ユーザーがこの一見些細モジュールの大部分を保持頼っている切り離せないようです。だから、マイクロチャネルのミニゲームは、具体的にどのようにこの機能の援助ラヤエンジンのランキングを実装するには?私たちは最初、最終的なレンダリングを見て:
我々は公式のマイクロチャネル使用の関係チェーンのデータをバディにしたい場合は、私たちはプロジェクトに直接グラフを描くことができない、と言って公式マイクロ手紙によると、私たちは、オープンフィールドを用いてグラフを描画する必要があります。
あなたは、このようなチャートや他のビジネスシナリオを描くように、APIの連鎖によって取得したユーザデータを表示したい場合は、我々はグラフを描画する必要があるsharedCanvas
プライマリドメインと画面に描画後、sharedCanvasに。簡単に言えば、sharedCanvasオープンデータは、プライマリドメインで、ドメインがオフスクリーンキャンバスにアクセスすることができます。オープン呼び出しwx.getSharedCanvasデータフィールドでは()sharedCanvasを返します。します。https://mp.weixin.qq.com/debug/wxagame/dev/tutorial/open-ability/open-data.html詳細は私がネットワークを導入知らせる行くことができます
その後、我々は実際のハンズオンそれについてに来ます。
プライマリドメインドロー
オープンフィールドは、チャートのUI、ので、UI以外の、私たちが描く、プライマリドメイン内で処理する必要があるの相互作用を描画するための唯一の責任があるので、効果がそれを通して見ることができる、私たちのリスト上のポップフォームが表示されます。ポップはどこしたがって、dialog
プライマリドメインに描画する必要が次のように、対応する位置情報とグラフ表示の長さと幅は、オープンフィールドに特定のコードをマッピングが必要です。
/**
* 显示排行榜数据
*/
function onRankInfoLoad(){
console.log("查看排行榜~");
var dialog = new RankDialogUI();
showShareCanvas();
// 解决显示对象和鼠标错位而导致的排行榜滑动无效问题
var globalPosition = dialog.ranking_list.localToGlobal(new Laya.Point());
var originMatrix = Laya.stage._canvasTransform;
var mat = new Laya.Matrix(originMatrix.a, 0, 0, originMatrix.d, globalPosition.x * originMatrix.a, globalPosition.y * originMatrix.d);
wxPostMessage({
command: 0,
text: "设置开放域canvas大小",
canvasData: {
width: rankViewWidth * mat.a, height: rankViewHeight * mat.d, matrix: mat
},
isLoad: false
}, null, function (message) {
console.log("再次往开放域发请求");
window['wx'].postMessage({
command: 1,
text: '开放域加载资源',
});
});
Laya.stage.addChild(dialog);
dialog.ranking_list.visible = false;
dialog.popup();
Laya.timer.once(400,this,function(){
wxPostMessage({
command: 3,
text: "获取排行榜数据~"
}, null, function (message) {
console.log("获取排行榜的回调~");
});
});
dialog.btn_rank_dialog_share.on(Laya.Event.CLICK, this, onGameRankShare);
dialog.btn_rank_dialog_back.on(Laya.Event.CLICK, this, onDialogClose);
function onDialogClose(){
wxPostMessage({
command: 4,
text: "关闭排行榜~"
}, null, function (message) {
console.log("关闭排行榜的回调~");
});
dialog.close();
}
function onGameRankShare(){
console.log("分享排行榜~");
window['wx'].showShareMenu({
withShareTicket:false,
success:function(res){
console.log("开启转发成功~");
},
fail:function(res){
console.log("开启转发失败~");
},
complete:function(res){
}
});
window['wx'].onShareAppMessage(function () {
return {
title: '我在飞机大战游戏中排名又上升了,快来挑战我吧~'
}
})
window['wx'].shareAppMessage({
title: '我在飞机大战游戏中排名又上升了,快来挑战我吧~',
imageUrl: canvas.toTempFilePathSync({
x: (screenWidth - rankViewWidth)/2 - 10,
y: (screenHeight - rankViewHeight)/2+80,
width: (rankViewWidth - 30)*4,
height: (rankViewHeight - 40)*4,
destWidth: 500,
destHeight: 600
})
});
}
}
/**
* 设置共享Canvas
*/
function showShareCanvas(){
window['sharedCanvas'].width = rankViewWidth;
window['sharedCanvas'].height = rankViewHeight;
//主域显示开放域内容???
//window['sharedCanvas'].sharedCanvas = window['wx'].getOpenDataContext().canvas;
Laya.timer.once(1000, this, function () {
var sprite = new Laya.Sprite();
sprite.zOrder = 1008;
sprite.pos(0, 0);
var texture = new Laya.Texture(window['sharedCanvas']);
texture.bitmap.alwaysChange = true;//小程序使用,非常费
sprite.graphics.drawTexture(texture, (screenWidth - rankViewWidth)/2, (screenHeight - rankViewHeight)/2, texture.width, texture.height);
Laya.stage.addChild(sprite);
});
}
/**
* 向开放域发送消息,并接收开放域返回过来的数据,
* 可根据发送参数和接收数据在主域这边进行下步处理
* @param message
* @param caller
* @param callback
*/
function wxPostMessage(message, caller, callback){
window['wx'].postMessage(message);
Laya.timer.once(400, this, function (){
//回调处理
if (caller == null || caller == undefined) {
callback(message);
} else {
caller.callback(message);
}
});
}
本体側によって送信されたメッセージは、コマンドフィールド、異なるオープンフィールドを行うための機能コードを運び、ここに分け:チャートサイズコマンドを初期化し、リソースのロード命令は、関係チェーン(図)、及びコマンドデータを取得します閉じるチャートコマンドは、適切なビジネスの特定のニーズに応じて増減することができます。
オープンドロードメイン
根据官方的说明,开放数据域
是一个封闭、独立的 JavaScript 作用域。要让代码运行在开放数据域,需要在 game.json 中添加配置项 openDataContext
指定开放数据域的代码目录。添加该配置项表示小游戏启用了开放数据域,这将会导致一些 限制。这些限制主要包含:
- 无法设置sharedCanvas的宽高
- 只能使用有限的接口(如逐帧动画、Timer、触摸事件以及获取和设置关系链数据等接口)
下面我们一步步来在开放域绘制排行榜。
首先,需要新建一个项目作为开放域,这个项目目录是与主域项目平行的(主域就是未做排行榜之前的项目目录),比如我的项目目录是这样的:
接着,我们需要在开放域中接收主域发送的消息并处理不同的功能命令,UI就不放了,看看具体代码吧:
/** * 监听从主域发过来的消息 */ function wxOnMessage(){ if(window['wx'] != undefined){ window['wx'].onMessage(function (message){ dispatchMessage(message); }); }else{ console.log("微信接口无法使用~"); } } /** * 处理消息 * @param {*} message */ function dispatchMessage(message){ switch(message.command){ //设置开放域画布大小 case 0: sample.setCanvasSize(message.canvasData); break; //加载资源 case 1: sample.loadResource(); break; //写入排行榜数据 case 2: sample.writeRankingData(message.rankingData); break; //获取微信排行榜数据 case 3: sample.getRankingData(); break; //关闭排行榜 case 4: sample.closeRankingDialog(); break; default: console.log(JSON.stringify(message)); } } /** * 设置开放域画布大小 * @param {*} size */ _proto.setCanvasSize = function(size){ console.log("设置开放域canvas大小~"); window['sharedCanvas'].width = size.width; window['sharedCanvas'].height = size.height; //Laya.stage.width = size.width; //Laya.stage.width = size.height; /** * 将主域的canvasTransform映射到开放域 */ if(size.matrix!=null){ console.log("收到主域的同步canvasTransform了~"); } var mainMatrix = size.matrix; var openMatrix = new Laya.Matrix(); openMatrix.a = mainMatrix.a; openMatrix.b = mainMatrix.b; openMatrix.c = mainMatrix.c; openMatrix.d = mainMatrix.d; openMatrix.tx = mainMatrix.tx; openMatrix.ty = mainMatrix.ty; //重置矩阵 Laya.stage._canvasTransform = openMatrix; //监听舞台的鼠标移动事件 Laya.stage.mouseEnabled = true; } /** * 用户自己的排名 */ var myRanking = -1; /** * 获取微信排行榜数据 */ _proto.getRankingData = function(){ window['wx'].getUserInfo({ openIdList: ['selfOpenId'], success: (userRes) => { console.log('success', userRes.data); //索引代表各个好友0为自己 let userData = userRes.data[0]; console.log("取信息索引0" + userData.nickName); //取出所有好友数据 window['wx'].getFriendCloudStorage({ keyList: [ //'击杀排行', '第1关', '第2关', '第3关' ], success: res => { console.log("wx.getFriendCloudStorage success", res); let data = res.data; /*data.sort((a, b) => { if (a.KVDataList.length == 0 && b.KVDataList.length == 0) { return 0; } if (a.KVDataList.length == 0) { return 1; } if (b.KVDataList.length == 0) { return -1; } return b.KVDataList[0].value - a.KVDataList[0].value; });*/ for (let i = 0; i < data.length; i++) { var playerInfo = data[i]; var currentPlayer = res.data[i].nickname; console.log("当前排行玩家昵称为=>"+res.data[i].nickname); var kvList = playerInfo.KVDataList; var scoreSum = 0; if(kvList.length>0){ for(var j = 0;j<kvList.length;j++){ if(kvList[j].key != null){ //将value转化为int再累加 scoreSum+=Number(kvList[j].value); } } } if (data[i].avatarUrl == userData.avatarUrl) { //获取群好友的时候,没有自己的名字?? data[i].nickName = userData.nickName; myRanking = i+1; console.log("此ID为自己,当前排名第"+myRanking); } //填充总分信息 sortData.push({ nickName: currentPlayer, avatarUrl: data[i].avatarUrl, totalScore: scoreSum }); } sortData.sort((a, b) => { var score1 = Number(a.totalScore); var score2 = Number(b.totalScore); if (score1 > score2) { return -1; }else if(score1 < score2){ return 1; }else{ return 0; } }); showRankingDialog(); }, fail: res => { console.log("拉取好友信息失败", res); }, }); }, fail: (res) => { console.log("拉取个人信息失败") } }); } /** * 加载资源 */ _proto.loadResource = function(){ Laya.loader.load(["comp/bg_line.png","comp/ranking1.png","comp/ranking2.png", "comp/ranking3.png","comp/userholder_img.png"], Laya.Handler.create(null,function(){ console.log("开放域资源加载完毕~"); sample.rankView = new RankingViewUI(); Laya.stage.addChild(sample.rankView); })); } /** * 写入排行榜数据 */ _proto.writeRankingData = function(rankingData){ console.log("写入排行榜数据~"); //KVDataList代表排行数据,可以为多个,多个代表多个排行 //key-排行类型,value-排行分数 window['wx'].setUserCloudStorage({ KVDataList: [ //{ key: '击杀排行', value: "" + 1 }, { key: '第'+rankingData.fightLevel+'关', value: rankingData.fightScore+"" },//需要改成动态的值 ], success: function (res) { console.log('setUserCloudStorage', 'success', res) }, fail: function (res) { console.log('setUserCloudStorage', 'fail') } }); } var sortData = []; /** * 渲染排行榜列表 */ function showRankingDialog(){ console.log("拿到好友排行榜信息", sortData); sample.rankView.ranking_list.vScrollBarSkin = ""; sample.rankView.ranking_list.array = sortData; sample.rankView.ranking_list.renderHandler = new Laya.Handler(this, onRender); sample.rankView.ranking_list.selectHandler = new Laya.Handler(this, onSelect); } var lastRenderIndex = -1; function onRender(cell, index){ if (index == lastRenderIndex) { return; } lastRenderIndex = index; //根据子节点的name获取子节点对象 var name = cell.getChildByName("item_rank_name"); var ranking = cell.getChildByName("item_rank_text"); var userlogo = cell.getChildByName("item_rank_logo"); var score = cell.getChildByName("item_rank_score"); var rank_icon = cell.getChildByName("item_rank_icon"); name.text = sortData[index].nickName; console.log("渲染排行榜当前的用户名为="+sortData[index].nickName+",渲染索引:"+lastRenderIndex); ranking.text = (index+1)+""; userlogo.skin = sortData[index].avatarUrl; score.text = sortData[index].totalScore+"分"; if(lastRenderIndex === 0 || lastRenderIndex === 1 || lastRenderIndex === 2){ ranking.visible = false; rank_icon.visible = true; rank_icon.skin = "comp/ranking"+(lastRenderIndex+1)+".png"; }else{ rank_icon.visible = false; ranking.visible = true; } } function onSelect(index){ console.log("当前选择的索引是:"+index); } /** * 关闭排行榜 */ _proto.closeRankingDialog = function(){ //dialog.close(); console.log("关闭排行榜~"); sortData = []; lastRenderIndex = -1; sample.rankView.removeChildren(); sample.rankView = null; } _proto.start = function(){ console.log("开始接收主域的消息~"); wxOnMessage(); } }
可以看到,我们这里通过
wx.onMessage
方法来获取主域发送的数据,然后借助dispatchMessage
方法作消息的分发处理。值得注意的是,我们在设置开放域canvas大小的时候,需要重置坐标矩阵,将主域的排行榜显示位置映射到开放域中来,否则会发生滑动无效的问题。我这里设置的排行榜数据有三条,大家可以根据具体需求来传入,获取到排行榜数据后,需要对它进行排序处理并展示,这里直接借助于laya中的List
控件展示就可以了,对于它用法不熟悉的可以去laya官网了解一下:https://ldc.layabox.com/doc/?nav=zh-js-6-0-0- 开放域图片加载问题:
用过laya游戏引擎的都知道,我们一般用官方推荐的打包图集的方式来加载游戏中的图片资源,这种方式在主域中是可行的,然而,在开放域中却不能成功加载图片资源。因此,开放域中,我们不需要将图片资源打包成图集,只要像下面这样直接加载图片即可:
/**
* 加载资源
*/
_proto.loadResource = function(){
Laya.loader.load(["comp/bg_line.png","comp/ranking1.png","comp/ranking2.png",
"comp/ranking3.png","comp/userholder_img.png"], Laya.Handler.create(null,function(){
console.log("开放域资源加载完毕~");
sample.rankView = new RankingViewUI();
Laya.stage.addChild(sample.rankView);
}));
}
その後、我々はまた、そうでない場合は、画像リソースを見つけるために、プロンプトが表示されます、wx_publishディレクトリにコピーされた画像フォルダに対応する必要があります。
組み合わせプライマリドメインとオープンドメイン
プライマリドメインとドメイン機能オープンソース実装した後、我々は、マイクロチャネルのゲームプロジェクトにパッケージ化する必要があります。リリースの上に示すように、まず、我々は、最初の直接のプロジェクトのルートディレクトリに、マイクロチャネルのゲームにプライマリドメインプロジェクトを公開する必要がありますwx_publish
ディレクトリ。次に、ディレクトリ内のsrc / myOpenDataContextディレクトリを作成します。次に、我々はあなたが名前の、デスクトップディレクトリを選択することができ、また、手紙のゲームをリリースしたマイクロドメインのプロジェクトに開放する必要がありますwx_open
にcode.js、weapp-adapter.jsとindex.jsファイルをコピーし、成功した後に掲載さディレクトリを入力するwx_publish/src/myOpenDataContext
ディレクトリそして、game.json
オープンドメインマッピングのディレクトリファイルの増加:
{
"deviceOrientation": "portrait",
"showStatusBar": "false",
"networkTimeout": {
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
},
"openDataContext": "src/myOpenDataContext"
}
ここでは、マイクロチャネルのゲームリーダーボードに実現しても、最終的には実際には、見つけ、実装することは困難ではない、難易度は、情報の不足、唯一歓迎任意の質問を開始するために使用され、この記事です。