寫遊戲的時候經常會要儲存一些遊戲内的資料,比如遊戲等級,金币數量等。作為遊戲前端,剛開始是把這些資料寫在本地緩存。怕使用者主動修改這些資料,會再做一層簡單的加密處理。但是,這有個弊端,當使用者換裝置或清理緩存的時候,這些遊戲内的使用者資料就不存在了。
後來接觸了FBInstant(facebook小遊戲)裡提供了存儲讀取使用者資料的接口,可以将使用者資料儲存在伺服器上。相對微信小遊戲未提供使用者資料存儲接口,對遊戲前端開發不是很友好,自己搭建伺服器也要新的成本。還好,最近微信提供了雲開發,看到裡面有資料庫,雲函數,存儲等功能,可以用來實作使用者資料存儲。
1. 使用 FBInstant 存儲使用者資料
1.1 擷取資料
直接調用
FBInstant.player.getDataAsync(keys)
從指定的雲存儲中檢索目前使用者的資料。
let userData = {coin:0, level:0};
const keys = ['coin','level'];
FBInstant.player.getDataAsync(keys)
.then((data) => {
console.log('FBInstant.player.getDataAsync success', data);
for (const key in data) {
if (data.hasOwnProperty(key)) {
this.userData[key] = data[key];
}
}
}, (err) => {
console.log('FBInstant.player.getDataAsync err', err);
});
複制
1.2 上傳資料
使用
setDataAsync()
設定要儲存到指定雲存儲的目前使用者的資料,使用
flushDataAsync()
立即将使用者資料的任何更改重新整理到指定的雲存儲中。
let userData = {coin:100,level:1};
FBInstant.player
.setDataAsync(userData)
.then(FBInstant.player.flushDataAsync, (err) => {
console.log('FBInstant.player.setDataAsync err', err)
})
.then(() => {
console.log('Data persisted to FB!');
}, (err) => {
console.log('FBInstant.player.flushDataAsync err', err)
});
複制
2. 使用用微信雲開發存取使用者資料
首先參考微信雲開發文檔建立資料庫集合
users
,建立雲函數
user
。
2.1 雲函數
通過
cloud.getWXContext()
擷取使用者唯一辨別
OPENID
作為資料庫集合
users
的唯一id值,用于查找修改該使用者的資料。
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();
const collection = db.collection('users');
const { OPENID, APPID, UNIONID } = cloud.getWXContext();
const _openid = OPENID;
複制
修改/增加使用者資料:通過擷取的
_openid
在集合内添加資料,注意插入的資料不能含有
_id
字段。
const addUser = async (_openid, userInfo) => {
delete userInfo._id;
await collection.doc(_openid).set({ data: userInfo });
return userInfo;
}
複制
擷取使用者資料:先在資料庫裡查詢有沒有該使用者資料,沒有資料要先建立資料。
const getUser = async (_openid) => {
let user;
const hasUser = await collection.where({ _id: _openid }).get();
if (Array.isArray(hasUser.data) && hasUser.data.length === 0) {
user = addUser(_openid, { _id: _openid });
} else {
const user_t = await collection.doc(_openid).get();
user = user_t.data;
}
return user;
}
複制
完整的雲函數代碼如下:
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();
const collection = db.collection('users');
const addUser = async (_openid, userInfo) => {
delete userInfo._id;
await collection.doc(_openid).set({ data: userInfo });
return userInfo;
}
const getUser = async (_openid) => {
let user;
const hasUser = await collection.where({ _id: _openid }).get();
if (Array.isArray(hasUser.data) && hasUser.data.length === 0) {
user = addUser(_openid, { _id: _openid });
} else {
const user_t = await collection.doc(_openid).get();
user = user_t.data;
}
return user;
}
exports.main = async (event, context) => {
const { func, data } = event;
const { OPENID, APPID, UNIONID } = cloud.getWXContext();
let res;
if (func === 'addUser') {
res = await addUser(OPENID, data);
} else if (func === 'getUser') {
res = await getUser(OPENID);
} else if (func === 'getOpenId') {
res = OPENID;
}
return res;
}
複制
2.2 用戶端調用
先初始化雲環境
wx.cloud.init({env: 'your-env'})
複制
擷取使用者資料的實作
let userData = {coin:0,level:0};
wx.cloud.callFunction({
// 雲函數名稱
name: 'user',
// 傳給雲函數的參數
data: {
func: 'getUser',
data: {},
},
}).then((res) => {
console.log('getDataAsync success', res);
const result = res.result || {};
for (const key in result || {}) {
if (result.hasOwnProperty(key)) {
this.userData[key] = result[key];
}
}
}, (err) => {
console.log('getDataAsync err', err);
})
複制
上傳使用者資料的實作
let userData = {coin:100,level:10};
wx.cloud.callFunction({
// 雲函數名稱
name: 'user',
// 傳給雲函數的參數
data: {
func: 'addUser',
data: userData,
},
}).then(res => {
console.log('flushDataAsync success', res)
console.log(res.result)
}, (err) => {
console.log('flushDataAsync err', err)
})
複制
以上是用微信雲存取使用者資料的一種實作方式。自己主要是寫遊戲前端的邏輯,不足之處,歡迎指出。