"resource/skins/GameRect.exml",
"resource/skins/MainScene.exml"
skins中添加代码:
"MainScene": "resource/skins/MainScene.exml",
"GameRect": "resource/skins/GameRect.exml"
这样,就可以通过在src代码文件夹中创建与皮肤同名的类来控制皮肤中对应的图片了。
具体方法如下:
在MainScene.exml中给对应的元件添加id属性,那么在新建的MainScene.ts中,定义与id同名同类型的变量,就能调用到这个元件了。
1、游戏逻辑
参考链接: Egret制作打砖块小游戏项目实战.
2、排行榜
由于排行榜是通过微信的开放域来实现的,所以它的初始化需要手动来处理,这里可以写入游戏的初始化函数里:
//初始化开放域
var platform = window.platform;
platform.openDataContext.postMessage({
command: "loadRes"
});
我是在每次游戏结束后弹出排行榜的,所以写在了游戏结束的函数里:
//添加排行榜
var plathform = window.platform;
//处理遮罩,避免开放域数据影响主域
this.rankingListMask = new egret.Shape();
this.rankingListMask.graphics.beginFill(0x000000,1);
this.rankingListMask.graphics.drawRect(0,0,this.stage.width,this.stage.height);
this.rankingListMask.graphics.endFill();
this.rankingListMask.alpha = 0.4;
//设置为true,以免触摸到下面的按钮
this.rankingListMask.touchEnabled = true;
this.addChildAt(this.rankingListMask,999);
//显示开放域数据
this.bitmap = plathform.openDataContext.createDisplayObject(null,this.stage.stageWidth, this.stage.stageHeight);
this.addChild(this.bitmap);
//主域向子域发送数据
plathform.openDataContext.postMessage({
isRanking: this.isRankClick,
curScore: this.config.score,
text: "egret",
year: (new Date()).getFullYear(),
command: "open"
});
//添加关闭排行榜按钮
var rankBtn = new eui.Button();
rankBtn.icon = RES.getRes("closeBtn");
rankBtn.width = rankBtn.height = 50;
rankBtn.x = this.stage.stageWidth * 9 / 10 - rankBtn.width;
rankBtn.y = this.stage.stageHeight * 1 / 10;
this.addChild(rankBtn);
rankBtn.addEventListener(egret.TouchEvent.TOUCH_TAP, function (e) {
plathform.openDataContext.postMessage({
year: (new Date()).getFullYear(),
command: "close"
});
this.removeChild(rankBtn);
this.removeChild(this.rankingListMask);
this.removeChild(this.bitmap);
}, this);
写完之后会发现,有错误,因为platform中没有openDataContext这个属性,我们可以在 Platform.ts 中添加(以下是部分Platform.ts的代码,仅粘贴了填写openDataContext的部分):
declare interface Platform {
getUserInfo(): Promise<any>;
login(): Promise<any>;
openDataContext: any;
}
class DebugPlatform implements Platform {
async getUserInfo() {
return { nickName: "username" }
}
async login() {
}
openDataContext: any;
}
"target": { "current": "wxgame" },
发布之后,打开微信开发者工具,开始调试微信小游戏。
//授权处理函数
applyJurisdiction() {
wx.getSetting({ //得到用户的当前设置
success: (res) => {
var status = res.authSetting;
if (!status['scope.userInfo'])//如果用户信息没有被授权获取
{
wx.authorize({
scope: 'scope.userInfo',
success: (res) => {
//授权成功后执行的内容
}, fail: (res) => {
wx.showModal({
title: '是否授权用户信息',
content: '需要获取您的用户信息,请确认授权,否则排行榜功能将无法使用',
success: function (tip) {
if (tip.confirm) {
wx.openSetting({
success: (res) => {
if (res.authSetting["scope.userInfo"]) {
wx.showToast({
title: '授权成功!',
icon: 'success',
duration: 1000
});
//授权成功后打开排行榜
console.log("打开排行榜");
}
else {
wx.showToast({
title: '授权失败!',
icon: 'success',
duration: 1000
});
}
},
});
}
}
});
}
});
}
}, fail: (res) => {
wx.showToast({
title: '调用授权窗口失败!',
icon: 'success',
duration: 1000
});
}
})
}
login() {
this.applyJurisdiction();
return new Promise((resolve, reject) => {
wx.login({
success: (res) => {
resolve(res)
}
})
})
}
//获得用户的信息
getUserInfo() {
return new Promise((resolve, reject) => {
wx.getUserInfo({ //需要注意的是,如果用户未授权,不会弹授权的窗口,需要主动去判断是否需要弹窗
withCredentials: true,
success: function (res) {
var userInfo = res.userInfo //微信号
var nickName = userInfo.nickName //微信用户名
var avatarUrl = userInfo.avatarUrl //头像链接
var gender = userInfo.gender //性别 0:未知、1:男、2:女
var province = userInfo.province //省份
var city = userInfo.city //城市
var country = userInfo.country //国家
resolve(userInfo);
}
})
})
}
"openDataContext": "openDataContext",
,之后可以发现项目目录中多了一个名为"openDataContext"的文件夹,如下:if (data.command == 'open') {
curScore.score = ~~data.curScore; //此处使用位取反是为了得到数字类型的值,下同
wx.getUserCloudStorage({ //得到制定key的所有数据
keyList: ["score"],
success: function (callBackData) {
//获取玩家数据成功
let kvDataList = callBackData.KVDataList;
let oldScore = ~~getKVValueByKey(kvDataList, "score");
if (oldScore < curScore.score) {//破纪录
curScore.isMax = true;
wx.setUserCloudStorage({ //如果破纪录,重新在数据库修改分数
KVDataList: [{
key: "score",
value: curScore.score.toString()
}],
success: handleFriends()
})
} else {
curScore.isMax = false;
handleFriends();
}
}
})
}
2、获得好友的数据后,对数据进行处理
function handleFriends() {
wx.getFriendCloudStorage({
keyList: ["score"],
success: function (callBackData) {
userInfoList = [];
let data = callBackData.data;
//获取同玩数据成功
for (let i = 0; i < data.length; i++) {
let userData = data[i];
let avatarUrl = userData.avatarUrl;
let nickname = userData.nickname;
let curScore = 0;
let KVDataList = userData.KVDataList;
for (let kvData of KVDataList) {
if (kvData.key == "score") {
curScore = ~~kvData.value;
}
}
let playerData = {
key: 0,
name: "",
url: assets.icon,
scroes: 0
}
playerData.key = i + 1;
playerData.name = nickname;
playerData.url = avatarUrl;
playerData.scroes = curScore;
userInfoList.push(playerData);
}
let compare = function (a, b) {//比较函数
if (a.scroes < b.scroes) {
return 1;
} else if (a.scroes > b.scroes) {
return -1;
} else {
return 0;
}
}
userInfoList.sort(compare);
for (let i = 0; i < userInfoList.length; i++) {
let userInfo = userInfoList[i];
userInfo.key = i + 1;
}
//创建并初始化
if (!hasCreateScene) {
hasCreateScene = createScene();
}
requestAnimationFrameID = requestAnimationFrame(loop);
context.clearRect(0, 0, sharedCanvas.width, sharedCanvas.height);
drawRankPanel();
}
});
}
3、绘制每一项数据
/**
* 根据绘制信息以及当前i绘制元素
*/
function drawByData(data, i) {
let x = startX;
let headX = startX + indexWidth + intervalX;
//绘制序号
context.fillStyle = "#888489";
if (i == 0) {
context.fillStyle = "#FC670A";
} else if (i == 1) {
context.fillStyle = "#FF004C";
} else if (i == 2) {
context.fillStyle = "#0019FF";
}
context.font = Math.floor(stageWidth / 25) + "px Microsoft YaHei";
context.fillText(data.key + "", x, startY + i * preOffsetY + textOffsetY, 50);
x += indexWidth + intervalX;
//绘制头像
let img = wx.createImage();
img.src = data.url;
img.onload = function () {
context.save();
context.beginPath(); //开始绘制
context.arc(headX + (avatarSize / 2), startY + i * preOffsetY + (barHeight - avatarSize) / 2 + (avatarSize / 2), avatarSize / 2, 0, Math.PI * 2, false);
context.clip();
context.drawImage(img, headX, startY + i * preOffsetY + (barHeight - avatarSize) / 2, avatarSize, avatarSize);
context.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制
}
x += avatarSize + intervalX;
//绘制名称
context.fillStyle = "#888489";
context.font = Math.floor(stageWidth / 28) + "px Arial";
context.fillText(data.name + "", x, startY + i * preOffsetY + textOffsetY, textMaxSize);
x += textMaxSize + intervalX;
//绘制分数
context.fillStyle = "#09E0EF";
context.font = Math.floor(stageWidth / 25) + "px Microsoft YaHei";
context.fillText(data.scroes + "", x, startY + i * preOffsetY + textOffsetY, textMaxSize);
}
已传至gitbub的项目链接: 打砖块微信小游戏.
BlockCrusher文件夹储存的是Egret Wing编辑的内容
BlockCrusher_wxgame文件夹是发布微信小游戏后编辑的内容