上次我們介紹了基于laya實現(xiàn)微信小游戲的排行榜功能,過程中免不了遇到一些坑历恐,主要包含一些圖片加載寸癌、邏輯處理、排行榜繪制弱贼、微信頭像跨域等問題蒸苇,具體可參考下面的記錄文檔。
2018/08/01
- 設(shè)置laya舞臺全屏顯示出現(xiàn)游戲崩潰問題:
- 錯誤信息:Stage is not defined
- 解決方案:增加前綴包名Laya
Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;
- 第二個boss出現(xiàn)后吮旅,boss子彈發(fā)生了重疊:
- 解決方案:在生成每個boss前移除之前的boss
/**
* 根據(jù)關(guān)卡生成boss
*/
function generateBoss(level,grade,hp,shootType){
if(this.boss!=null){
this.boss.removeSelf();
//回收到對象池
Laya.Pool.recover("role",this.boss);
}
isLastTime = true;
//在循環(huán)中創(chuàng)建敵人
Laya.timer.frameLoop(1,this,onLoop);
this.boss = new Role();
this.boss.init("boss"+level+"_"+grade,1,hp,0,60 );
this.boss.shootType = shootType;
this.boss.shootInterval = 800;
//boss出現(xiàn)位置
this.boss.pos(187, 100);
this.boss.visible = true;
//添加到舞臺上
this.roleBox.addChild(this.boss);
}
- 第一個boss被擊敗后溪烤,需要根據(jù)第二個boss刷新攻擊屬性和傷害值:
function appearBoss(){
Laya.timer.clear(this, onNextBossWarning);
removeEnemys();
generateBoss(currentLevel,this.bossGrade,20,1);
console.log("當(dāng)前選中的技能是"+levelWeaponData[this.weapon_ready_list.selectedIndex]);
if(levelWeaponData[this.weapon_ready_list.selectedIndex] != (currentLevel*10 + this.bossGrade)){
//如果派出的boss與選中的武器屬性不吻合,那么降低傷害值
console.log("70%火力~");
upgradeBullet(false);
}else{
console.log("100%火力~");
upgradeBullet(true);
}
}
2018/08/02
- laya圖集打包后鸟辅,部分圖片加載不出來的問題:
- 錯誤日志:
[warn]Retry to load: war/war/bg_second_level.png
[warn]Retry to load: war/hero_down1.png
[warn]Retry to load: war/hero_down2.png
[warn]Retry to load: war/hero_down3.png
[warn]Retry to load: war/hero_down4.png
[error]Failed to load: war/war/bg_second_level.png
- 問題原因:圖集打包最大只允許2048x512,而最終打包后的圖片大小超出了范圍莺葫,導(dǎo)致無法顯示出來匪凉。
- 解決方案:可以分開打包圖集
2018/08/03
- 將boss的出現(xiàn)改在答題之前后,戰(zhàn)機(jī)無法發(fā)射子彈或者一直warning:
- 解決方案:需要修改generateBoss方法邏輯捺檬,將繼續(xù)游戲與boss出現(xiàn)功能代碼分離再层,先在warning結(jié)束時生成boss,然后在答題結(jié)束后調(diào)用resume方法繼續(xù)游戲堡纬。
- 退出當(dāng)前關(guān)卡后聂受,進(jìn)入下一關(guān),然后再退出烤镐,游戲場景卡住不返回首頁的問題:
- 問題原因:沒有合適的移除UI資源
- 解決方案:關(guān)閉游戲場景前需要移除里面的背景資源蛋济、場景資源以及角色資源,并判斷首頁UI是否存在炮叶,如果存在需要回收碗旅,然后新建渡处。
function onGameLeave(){
dialog.close();
console.log("結(jié)束游戲~");
removeGame();
this.removeChildren();
this.removeSelf();
if(!GameScene.homePage){
GameScene.homePage = null;
}
GameScene.homePage = new HomePageUI();
Laya.stage.addChild(GameScene.homePage);
}
2018/08/06
- 給點擊事件的回調(diào)方法添加參數(shù)回調(diào):
btn_use.on(Laya.Event.CLICK, this,onUseEquipment, [index]);
......
/**
* list中對應(yīng)位置的使用按鈕的點擊事件處理
* @param {*} index
*/
function onUseEquipment(index){
console.log("當(dāng)前使用了第"+index+"個裝備");
for(var i=0; i<data.length; i++){
if(i === index){
//設(shè)置選中的狀態(tài)
console.log("當(dāng)前boss級別->"+(currentLevel*10 + this.bossGrade)+",當(dāng)前選中的武器->"+levelWeaponData[index]);
if((currentLevel*10 + this.bossGrade) === levelWeaponData[index]){
//使用的武器與boss是對應(yīng)的
console.log("100%火力~");
upgradeBullet(true);
}else{
console.log("70%火力~");
upgradeBullet(false);
}
}
}
}
2018/08/07
- 開放域打包集成到主域后祟辟,出現(xiàn)以下問題:
- 日志信息:
gameSubContextThirdScriptError
wx.getFileSystemManager is not a function;at onMessage callback function
TypeError: wx.getFileSystemManager is not a function
- 問題原因:開放域中的圖集資源并沒有成功加載
- 解決方案:開放域中并不能加載圖集資源医瘫,可以直接加載圖片集
_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.dialog = new RankDialogUI();
sample.rankView = new RankingViewUI();
Laya.stage.addChild(sample.rankView);
}));
}
- 開放域代碼打包到微信小游戲項目中時無法運行的問題:
- 錯誤信息:
dispatchMessage is not defined;at onMessage callback function ReferenceError: dispatchMessage is not defined
- 解決方案:通過_proto來創(chuàng)建方法:
var _proto = LayaUISample.prototype;
/**
* 寫入排行榜數(shù)據(jù)
*/
_proto.writeRankingData = function(rankingData){
//KVDataList代表排行數(shù)據(jù),可以為多個,多個代表多個排行
//key-排行類型,value-排行分?jǐn)?shù)
window['wx'].setUserCloudStorage({
KVDataList: [
//{ key: '擊殺排行', value: "" + 1 },
{ key: '分?jǐn)?shù)排行', value: "" + 100 },//需要改成動態(tài)的值
],
success: function (res) {
console.log('setUserCloudStorage', 'success', res)
},
fail: function (res) {
console.log('setUserCloudStorage', 'fail')
}
});
}
2018/08/08
- 開放域繪制的排行榜被主域的dialog覆蓋的問題:
- 問題原因:開放域與主域的視圖層級不一樣,dialog的層級遠(yuǎn)遠(yuǎn)大于普通視圖容器旧困。
- 解決方案:dialog的默認(rèn)層級zOrder為1000醇份,最簡單的方式是將shareCanvas的容器sprite的層級zOrder大于1000即可。
/**
* 設(shè)置共享Canvas
*/
function showShareCanvas(){
window['sharedCanvas'].width = rankViewWidth;
window['sharedCanvas'].height = rankViewHeight;
//主域顯示開放域內(nèi)容???
//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);
});
}
- 提交排行榜數(shù)據(jù)時出現(xiàn)以下問題:
- 錯誤信息:setUserCloudStorage:fail invalid KVData item僚纷。
- 問題原因:提交數(shù)據(jù)的格式錯誤,key與value都應(yīng)該是string類型
- 參考:https://developers.weixin.qq.com/minigame/dev/document/open-api/data/KVData.html
2018/08/09
- 小游戲分享失敗的問題:
- 問題原因:在開放域分享用戶排名后馍悟,提示無該方法畔濒,開放域官方只提供了幾個有限的api接口,應(yīng)該在主域去請求分享
window['wx'].showShareMenu({
withShareTicket:false,
success:function(res){
console.log("開啟轉(zhuǎn)發(fā)成功~");
},
fail:function(res){
console.log("開啟轉(zhuǎn)發(fā)失敗~");
},
complete:function(res){
}
});
window['wx'].onShareAppMessage(function () {
// 用戶點擊了“轉(zhuǎn)發(fā)”按鈕
return {
title: '我在飛機(jī)大戰(zhàn)游戲中排名又上升了,快來挑戰(zhàn)我吧~'
}
})
window['wx'].shareAppMessage({
title: '我在飛機(jī)大戰(zhàn)游戲中排名又上升了,快來挑戰(zhàn)我吧~',
imageUrl: canvas.toTempFilePathSync({
destWidth: 500,
destHeight: 400
})
});
- 提交排行榜分?jǐn)?shù):
/**
* 向開放域發(fā)送消息锣咒,并接收開放域返回過來的數(shù)據(jù)侵状,
* 可根據(jù)發(fā)送參數(shù)和接收數(shù)據(jù)在主域這邊進(jìn)行下步處理
* @param message
* @param caller
* @param callback
*/
function wxPostMessage(message, caller, callback){
window['wx'].postMessage(message);
Laya.timer.once(300, this, function (){
//回調(diào)處理
if (caller == null || caller == undefined) {
callback(message);
} else {
caller.callback(message);
}
});
}
/**
* 提交分?jǐn)?shù)到微信服務(wù)器
*/
function postScoreToWXServer(){
wxPostMessage({
command: 2,
text: "提交玩家分?jǐn)?shù)",
rankingData: {
fightScore:this.score*scoreFactor,
fightTime:new Date().getTime()
}
}, null, function (message) {
console.log("提交分?jǐn)?shù)的回調(diào)");
});
}
2018/08/10
- 調(diào)取用戶好友排行數(shù)據(jù)并排序整合后,得到的nickName為undefine:
- 問題原因:獲取好友排行榜的數(shù)據(jù)中當(dāng)前登錄用戶的昵稱是空值
- 解決方案:先通過getUserInfo獲取當(dāng)前用戶的數(shù)據(jù)毅整,然后通過avatarUrl去查找好友排行榜中數(shù)據(jù)趣兄,如果相同,說明為同一個用戶悼嫉,將當(dāng)前用戶昵稱復(fù)制給好友排行榜中當(dāng)前用戶的昵稱艇潭。
- 統(tǒng)計三關(guān)分?jǐn)?shù),并對它們的總分進(jìn)行排序的解決思路:
可以通過微信提供的排行榜分類統(tǒng)計功能戏蔑,這樣就無需理會玩家是一次性通關(guān)還是多次選擇關(guān)卡通關(guān)的問題了蹋凝。只要將玩家玩每一關(guān)通過時的分?jǐn)?shù)通過key(關(guān)卡)、value(分值)鍵值對形式存儲总棵,然后每次重復(fù)選擇都會刷新關(guān)卡的分值鳍寂。而獲取好友排行榜數(shù)據(jù)時,需要將分?jǐn)?shù)先轉(zhuǎn)化為number情龄,然后累加進(jìn)行排序迄汛,并展示即可。
- 關(guān)閉排行榜后骤视,再次打開鞍爱,數(shù)據(jù)沒了或者出現(xiàn)混亂的問題:
- 解決方案:需要重新清空重置數(shù)據(jù),并渲染list:
/**
* 關(guān)閉排行榜
*/
_proto.closeRankingDialog = function(){
//dialog.close();
console.log("關(guān)閉排行榜~");
sortData = [];
lastRenderIndex = -1;
sample.rankView.removeChildren();
sample.rankView = null;
}
- 關(guān)于如何在laya游戲引擎中顯示外部網(wǎng)頁的問題:
- 方法一:通過設(shè)置href來添加外部網(wǎng)頁資源专酗。但這種方法無法關(guān)閉和設(shè)置外部網(wǎng)頁的位置和大小睹逃。
Laya.Browser.window.location.;
- 方法二:通過iframe來添加外部網(wǎng)頁并控制其位置、大小以及移除:
var iframe = Laya.Browser.document.createElement("iframe");
iframe.style.position ="absolute";//設(shè)置布局定位祷肯。這個不能少唯卖。
iframe.style.zIndex = 1006;//設(shè)置層級
iframe.style.left = "36px";
iframe.style.top = "136px";
iframe.width = 180;
iframe.height = 220;
iframe.src = "http://ask.layabox.com/";
Laya.Browser.document.body.appendChild(iframe);
function onHelpClose(){
Laya.Browser.document.body.removeChild(iframe);;
dialog.close();
}
2018/08/13
- 無法加載微信用戶頭像的問題:
- 錯誤信息:
gameThirdScriptError
module "code.js" is not defined
Error: module "code.js" is not defined
- 解決方案:應(yīng)該是變量的作用域不同造成的粱玲,需要定義一個外部的全局變量,并將this.userLogoImage賦值給它拜轨,然后在獲取完畢微信頭像信息后加載該全局變量即可抽减。
- 關(guān)于如何讓laya的label內(nèi)容超出空間大小后自動滾動的問題:
- 解決方案:可以通過Panel組件來包裹label控件,讓其達(dá)到滾動效果橄碾。
- 使用panel組件后卵沉,里面的label內(nèi)容超過本身大小后無法滾動的問題:
- 解決方案:panel組件只是讓其內(nèi)部的控件在大小超過其容器(即panel)的時候,盡量達(dá)到滑動顯示全部信息法牲,所以史汗,需要將里面的label控件高度設(shè)置盡量大,以保證文字內(nèi)容全部顯示出來拒垃。
- 打包成微信小游戲后包太大無法預(yù)覽上傳的問題:
- 問題原因:微信限制上傳的代碼包不得超過4m停撞。
- 解決方案:
- 壓縮圖片資源
- 去除index中沒有使用到的library
- 刪除圖集打包生成的多余的文件
- 頭像設(shè)置的遮罩無效的問題:
- 問題原因:為了降低包大小,不小心將webgl代碼庫注釋了悼瓮,導(dǎo)致mask遮罩無法渲染成功
2018/08/14
- ios手機(jī)中無法播放游戲聲音的問題:
- 問題原因:laya引擎內(nèi)部的方法播放音頻只對Android手機(jī)有效戈毒,對ios的機(jī)型沒有效果
- 解決方案:需要借助于微信自帶的接口來播放音頻
var audio = wx.createInnerAudioContext()
audio.src = "res/sound/game_over.mp3" // src 可以設(shè)置 http(s)
audio.obeyMuteSwitch = false
audio.play();
- 調(diào)試模式下可以正常顯示用戶的頭像,但在非調(diào)試模式下無法顯示用戶頭像問題:
- 問題原因:微信用戶授權(quán)方法失效引起的
- 解決方案:
- 排行榜玩家昵稱不顯示問題以及排序錯亂問題:
- 問題原因:沒有正確復(fù)制好友排行榜的數(shù)據(jù)横堡,頭像鏈接埋市、分?jǐn)?shù)等都可以獲取到,但是偏偏昵稱獲取為undefined命贴,排行榜排序方式也有問題道宅。
- 解決方案:由于直接拿到微信返回的排行榜數(shù)據(jù)中用戶昵稱是存在的,而通過變量賦值獲取后便為undefined了胸蛛,可以拿到原始數(shù)據(jù)res.data[i].nickname污茵,然后復(fù)制給變量currentPlayer,再便遍歷添加到數(shù)組集合葬项。排序可以通過sort方法泞当,通過比較目標(biāo)集合中的兩個任意對象的分值,從大到小排列:
//取出所有好友數(shù)據(jù)
window['wx'].getFriendCloudStorage({
keyList: [
//'擊殺排行',
'第1關(guān)',
'第2關(guān)',
'第3關(guān)'
],
success: res => {
console.log("wx.getFriendCloudStorage success", res);
let data = res.data;
for (let i = 0; i < data.length; i++) {
var playerInfo = data[i];
var currentPlayer = res.data[i].nickname;
console.log("當(dāng)前排行玩家昵稱為=>"+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轉(zhuǎn)化為int再累加
scoreSum+=Number(kvList[j].value);
}
}
}
if (data[i].avatarUrl == userData.avatarUrl) {
//獲取群好友的時候,沒有自己的名字??
data[i].nickName = userData.nickName;
myRanking = i+1;
console.log("此ID為自己,當(dāng)前排名第"+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);
},
});
- 三張背景圖打包圖集后玷室,有一張無法顯示出來的問題:
- 問題原因:圖集打包的圖片超過了最大限制
- 解決方案:可以不打包圖片零蓉,直接在bin中使用
2018/08/15
- laya繪制的好友排行榜在微信開發(fā)工具無法滑動的問題:
- 問題原因:主域和開放域的排行榜的位置坐標(biāo)矩陣不同步造成的
- 解決方案:需要將主域和開放域的排行榜對應(yīng)位置坐標(biāo)矩陣同步
主域代碼:
// 解決顯示對象和鼠標(biāo)錯位而導(dǎo)致的排行榜滑動無效問題
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);
//var mat = new Laya.Matrix(Laya.Browser.clientWidth/Laya.stage.width, 0, 0, Laya.Browser.clientHeight/Laya.stage.height);
mat.translate(globalPosition.x * mat.a, globalPosition.y * mat.d);
wxPostMessage({
command: 0,
text: "設(shè)置開放域canvas大小",
canvasData: {
width: rankViewWidth * mat.a, height: rankViewHeight * mat.d, matrix: mat
//width:rankViewWidth, height:rankViewHeight, matrix: Laya.stage._canvasTransform
},
isLoad: false
}, null, function (message) {
console.log("再次往開放域發(fā)請求");
window['wx'].postMessage({
command: 1,
text: '開放域加載資源',
});
});
開放域代碼:
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;
- 主域修改了坐標(biāo)矩陣的同步代碼后笤受,小游戲排行榜無法顯示:
- 錯誤信息:
gameSubContextThirdScriptError
Cannot read property 'ranking_list' of undefined;at api getFriendCloudStorage success callback function
TypeError: Cannot read property 'ranking_list' of undefined
- 問題原因:laya平臺自身問題穷缤,只是存在以下代碼,開放域的排行榜便無法繪制:
// 解決顯示對象和鼠標(biāo)錯位而導(dǎo)致的排行榜滑動無效問題
......
var mat = new Laya.Matrix(Laya.Browser.clientWidth/Laya.stage.width, 0, 0, Laya.Browser.clientHeight/Laya.stage.height);
mat.translate(globalPosition.x * mat.a, globalPosition.y * mat.d);
......
2018/08/21
- 將游戲發(fā)布到微信平臺后箩兽,微信頭像無法顯示的問題:
- 問題原因:微信頭像url跨域了
- 解決方案:獲取到微信頭像地址后津肛,需要將其傳到服務(wù)器,讓服務(wù)器復(fù)制一份生成自己的服務(wù)器圖片url