- 小游戏 图片保存到本地用户文件目录 怎么读取?
- 当前 Bug 的表现(可附上截图) - 预期表现 - 复现路径 - 提供一个最简复现 Demo 保存图片到本地用户文件目录 wx.env.USER_DATA_PATH 成功没有问题 不能使用 img.src = wx.env.USER_DATA_PATH 对应地址 直接赋值显示图片 不能使用 wx.previewImage 直接预览图片 使用FileSystemManager 读取图片 转码后 经putimagedata 还是无法正确查看到图片 请问有没有什么办法可以将图片存储到本地,再在界面正确显示的 [图片] [图片]
2019-07-15 - 云开发实时数据推送制作小游戏匹配玩家功能
下面是功能介绍: 小程序·云开发新增实时数据推送能力,可以实时监听数据库中的数据变更。该功能有效地解决了即时通信以及实时更新和推送数据的问题,极大地降低在此类场景下的开发成本。 基于是实时数据推送能力,在给定查询条件的情况下,每当数据库更新而导致查询条件对应的查询结果发生变更时,小程序可收到一个更新事件,其中可获取更新内容和更新后的查询结果快照。 许多对战类型的小游戏需要一个匹配玩家界面,下面就从制作一个匹配玩家界面入手,简单介绍一下云开发实时数据推送功能。 1.首先打开微信开发者工具里云开发,在数据库中新建一个集合,集合名称:rooms,权限设置:所有用户可读,仅创建者可读写。2.我们用一个两人对战的例子,来介绍如何实现匹配玩家。当玩家进入匹配状态有两个情况,一是当前已经有队列玩家只需进入队列即可,二是当前没有队列玩家要创建队列。这里定义一下创建队列的人叫做newMen,加入队列的人叫做addMen。如何判定当前是否有队列,下面用一段代码说明下: [代码]const db = wx.cloud.database();[代码][代码]const $ = db.command.aggregate;[代码][代码]db.collection([代码][代码]'rooms'[代码][代码])[代码][代码].aggregate()[代码][代码].match({[代码][代码] [代码][代码]people: $.eq(1)[代码][代码]})[代码][代码].sort({[代码][代码] [代码][代码]createTimestamp: -1[代码][代码]})[代码][代码].limit(1)[代码][代码].end().then(res =>{[代码][代码] [代码][代码]console.log([代码][代码]'聚合查询结果rooms'[代码][代码],res.list);[代码][代码] [代码][代码]this[代码][代码].initRoom(res.list);[代码][代码]})[代码]这里用的是聚合查询,对集合rooms进行查询,只要当前people字段值为1就说明已经队列,如果查询不到结果就是没有队列需要创建队列,下面就是initRoom()方法进行判断,代码如下: initRoom(rooms){ [代码] if[代码] [代码](!rooms.length) {[代码] [代码] [代码][代码]this[代码][代码].createEmptyRoom();[代码] [代码] [代码][代码]} [代码][代码]else[代码] [代码]{[代码] [代码] [代码][代码]console.log([代码][代码]'进入队列成功'[代码][代码]);[代码] [代码] [代码][代码]this[代码][代码].nowPlayer = [代码][代码]'addMen'[代码][代码];[代码] [代码] [代码][代码]this[代码][代码].docid = rooms[0]._id;[代码] [代码] [代码][代码]this[代码][代码].roomid = rooms[0].roomid;[代码] [代码] [代码] this.updatePeopleField(); [代码][代码] [代码] [代码][代码]};[代码] } 从上面代码可以看出,如果查询结果为空就要创建队列。不为空就进入队列,然后执行更新字段操作,后面会详细介绍。下面介绍创建队列createEmptyRoom()方法,代码如下: [代码]createEmptyRoom(){[代码][代码] [代码][代码]const db = wx.cloud.database();[代码][代码] [代码][代码]const roomid = Date.now().toString();[代码][代码][代码][代码] let room = {[代码][代码] [代码][代码]roomid,[代码][代码] [代码][代码]createTimestamp: Date.now().toString(),[代码][代码] [代码][代码]people: 1,[代码][代码] [代码][代码]};[代码][代码] [代码][代码]db.collection('rooms').add({ data: room })[代码][代码] [代码][代码].then(res =>{[代码][代码] [代码][代码]this[代码][代码].nowPlayer = [代码][代码]'newMen'[代码][代码];[代码][代码] [代码][代码]this[代码][代码].docid = res._id;[代码][代码] [代码][代码]this[代码][代码].roomid = roomid;[代码][代码] [代码][代码]this[代码][代码].waitJionGame();[代码][代码] [代码][代码]})[代码][代码][代码][代码] [代码][代码]},[代码]这里向集合rooms添加一个新记录,即创建队列,当前玩家即nowPlayer为newMen。创建队列完成后,我们要监听是否有玩家进入队列,就是有没有addMen进来。这里就要用到上面说的云开发实时数据推送功能了,相关代码如下: [代码]waitJionGame(){[代码][代码] [代码][代码]let docid = [代码][代码]this[代码][代码].docid;[代码][代码] console.log('正在匹配对手...');[代码][代码] [代码][代码]const db = wx.cloud.database();[代码][代码] [代码][代码]this[代码][代码].player = db.collection('rooms')[代码][代码] [代码][代码].where({[代码][代码] [代码][代码]_id: docid[代码][代码] [代码][代码]})[代码][代码] [代码][代码].watch({[代码][代码] [代码][代码]onChange: snapshot => {[代码][代码] [代码][代码]const docChange = snapshot.docChanges[0];[代码][代码] [代码][代码]const doc = snapshot.docs[0];[代码][代码] [代码][代码]console.log([代码][代码]'监听玩家进入'[代码][代码], snapshot);[代码][代码] [代码][代码]if[代码] [代码](docChange.dataType === [代码][代码]'update'[代码] [代码]&& doc.people === 2) {[代码][代码] console.log('匹配成功');[代码][代码] [代码][代码]this[代码][代码].player.close();[代码][代码] [代码][代码]}[代码][代码] [代码][代码]},[代码][代码] [代码][代码]onError: error => {[代码][代码] [代码][代码]console.log(error);[代码][代码] [代码][代码]}[代码][代码] [代码][代码]})[代码][代码] [代码][代码]},[代码]通过对刚才创建的记录进行监听,只要dataType === 'update'即记录有更新操作,并且doc.people === 2,就说明有玩家进入即addMen进入队列,此时就可以关闭监听,执行close()。这时队列创建者即newMen,匹配阶段所有工作都完成了。对于加入队列者即addMen还有一个工作,告诉newMen我已经进入队列了,很简单就是把记录里的people字段更新为2。相关代码如下: [代码]updatePeopleField() {[代码] [代码] let docid = this.docid;[代码] [代码] [代码][代码]wx.cloud.callFunction({[代码][代码] [代码][代码]name: [代码][代码]'updateDoc'[代码][代码],[代码][代码] [代码][代码]data: {[代码][代码] [代码][代码]collection: 'rooms',[代码][代码] [代码][代码]docid: docid,[代码][代码] [代码][代码]people: 2,[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}).then(res => {[代码][代码] [代码][代码]console.log([代码][代码]'更新人数成功'[代码][代码],res);[代码][代码] [代码][代码]}).[代码][代码]catch[代码][代码](err => {[代码][代码] [代码][代码]console.log(err);[代码][代码] [代码][代码]})[代码][代码] [代码][代码]},[代码]更新队列创建者newMen创建的记录里的字段是一个越权操作,所以要调用云函数。通过云函数更新完成字段后,addMen所有使命都已经完成了。 这就是整个匹配玩家阶段的流程,相关效果可以参考本人开发的游戏--圣兵棋盘。 [图片] 圣兵棋盘
2019-09-05 - aggregate.sample随机获取云数据库记录,为什么无法显示在wxml?
wxml界面:[图片]onload定义了加载界面时随机从数据库取3组记录,下面控制台显示已取到,但是在wxml中要显示数组的数据是却空白,这是为什么?哪里出错了吗? [图片]
2019-08-18 - 云函数openapi.security.msgSecCheck异常问题解决
问题: 自己做了个日志簿小程序,后端接口完全使用微信云函数,但在开发文字分享评论模块时遇到了问题:文字合规检查; 调用openapi.security.msgSecCheck异常如下: {“errCode”:-501001,“errMsg”:"openapi.security.msgSecCheck:fail source.on is not a function; at openapi.security.msgSecCheck api; "} 解决: 因为创建了两个云环境 dev 和 publish 在调用云函数时需要动态切换当前环境如下: [代码]//代码1 cloud.updateConfig({ env: { database: wxContext.ENV, storage: wxContext.ENV, functions: wxContext.ENV } }) //代码2 const db = cloud.database({ env: wxContext.ENV }); //代码3 let result = await cloud.openapi.security.msgSecCheck({ content: event.content }) [代码] 这样就可以正常返回result了: {“errMsg”:“openapi.security.msgSecCheck:ok”,“errCode”:0} 原因: 因为之前少了代码片2;其他接口都加了代码1 代码2;但文本合规检查接口想当然认为与数据库环境无关就删掉了代码2…掉坑了~ 补充注意点: 合规检查正常时返回result,不合规时会走异常catch,而非直接返回到result…O_O ; 自定义示例代码如下,只有code:300时表示文字不合规;仅供参考~ [代码] try { console.log('待检测文本:'+event.content); let result = await cloud.openapi.security.msgSecCheck({ content: event.content }) console.log('result:'+JSON.stringify(result)); if (result && result.errCode.toString() === '87014'){ return { code: 300, msg: '内容含有违法违规内容', data: result } // }else{ return { code: 200, msg: 'ok', data: result } } } catch (err) { if (err.errCode.toString() === '87014'){ return { code: 300, msg: '内容含有违法违规内容', data: err } // } return { code: 400, msg: '调用security接口异常', data: err } } } [代码] 以上,希望对大家有所帮助~ ps:日志簿项目二期功能正在开发中…一期开发了私密日志功能;放个程序码,希望大家支持!!~ 开发交流,共同进步~ [图片]
2019-08-06