1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 在微信小游戏中实现语音互动

在微信小游戏中实现语音互动

时间:2022-02-23 13:54:23

相关推荐

在微信小游戏中实现语音互动

之前在unity里尝试用过语音控制,当时的想法是实时控制游戏角色的移动与攻击,这在通过在线api解析语义的方式下体验一般,不过也想到在实时性要求不那么高的互动场景应该可以用起来。这里就在微信小游戏中尝试一下。

语音交互自然需要一个对象,像我这种手残人士最适合的设计当然就是卡通的小动物了。经过多次修改,在iPad上完成了形象设计(有点丑,有点歪,大家不要见怪):

设计好形象之后就可以设计动画了。一帧一帧的画出连贯的动作。因为偷懒,所以一个动画也就几帧,准备了下面几个动画:

眨眼。1帧,空闲状态的时候播放,避免什么都不做的时候画面看起来太死板。挠头。2帧,录音结束发给服务器等待服务器结果的时候播放,使得能在话音刚落时就给出反应。微笑。1帧,对它说“笑一个”的时候播放。举牌子。3帧,狗狗不会说话,要通过写字的方式和玩家交流。

接下来就可以参考飞机示例,完成游戏的代码部分。

首先新建一个class InterAction,在constructor中进行各种初始化,主要是加载一些图片资源,注册事件等:

constructor(c, returnTitle) {ctx = cthis.returnTitle = returnTitlethis.bg = wx.createImage()this.bg.src = 'images/bg2.png'this.recordBtn = wx.createImage()this.recordBtn.src = 'images/record.png'this.recordBtnDown = wx.createImage()this.recordBtnDown.src = 'images/recorddown.png'this.btn = this.recordBtnthis.dog = new Dog()this.idleFrameCount = 0this.result = ''this.recorderManager = wx.getRecorderManager()this.recorderManager.onStop(this.onRecordEnd.bind(this))this.restart()}restart() {this._touchStartHandler = this.touchStartHandler.bind(this)wx.onTouchStart(this._touchStartHandler)this._touchEndHandler = this.touchEndHandler.bind(this)wx.onTouchEnd(this._touchEndHandler)requestAnimationFrame(this.loop.bind(this))}

之后,可以看到主线程结构和飞机的基本一样:

loop() {this.update()this.render()requestAnimationFrame(this.loop.bind(this))}

在update和按钮、录音的回调函数中更新状态,在render中显示当前帧的内容。

录音结束后,调用happycxz提供的接口进行语音解析:

onRecordEnd(res) {// 向服务器发送录音文件let url = '/wxapp/mp32asr'this.dog.playAnimation('thinking', 0, true)this.idleFrameCount = 0this.processFileUploadForAsr(url, res.tempFilePath)}processFileUploadForAsr(url, filePath) {wx.uploadFile({url: url,filePath: filePath,name: 'file',formData: { 'appKey': appkey, 'appSecret': appsecret, 'userId': UTIL.getUserUnique()},header: {'content-type': 'multipart/form-data'},success: function(res) {let nliResult = this.getNliFromResult(res.data)let stt = this.getSttFromResult(res.data)let result = ''if (nliResult != undefined && nliResult.length != 0) {result = nliResult[0].desc_obj.result} else {result = '出了点问题'}this.handleResult(result)}.bind(this),fail: function (res) {wx.showModal({title: '提示',content: "网络请求失败,请确保网络是否正常",showCancel: false,success: function (res) {}})}.bind(this)})}

处理返回结果:

handleResult(res) {if (res.length > 6) {res = res.substr(0, 6)}this.result = resif (this.result == '微笑') {this.dog.playAnimation('smile', 0, true, 60)this.idleFrameCount = 0} else if (this.result == 'exit') {wx.offTouchStart(this._touchStartHandler)wx.offTouchEnd(this._touchEndHandler)this.returnTitle()} else {this.dog.playAnimation('answer', 0, false, 240, function () {ctx.fillStyle = "#ffffff"ctx.font = "15px Arial"ctx.fillText(this.result,constants.screenWidth * 17 / 32,constants.screenHeight * 15 / 32)}.bind(this), 2)this.idleFrameCount = 0}}

Dog是继承自我扩展之后的Animation类,主要的改动有两个,一个是支持多个动画,另一个是在playAnimation时增加了多个参数,可以控制动画循环的方式,并可以指定在特定的帧显示时调用的回调函数。具体的代码可以看文末的代码包,这里就不多说了。

最后来看看测试效果。

按下录音键,说话,松开后会做挠头动作(有点难看),等待一段时间会举起牌子显示结果。目前只在olami平台配置了闲聊、24点和算术功能。为了适应牌子大小,结果做了截断处理。下面是几个测试例子:

笑一个/笑一笑:会做出笑脸

再见/拜拜:会返回标题界面

其他:会通过牌子上显示文字信息

另外,代码中还包含了一个跳跃的小游戏,通过在主界面点击开始可以进入。如果进一步开发,可以把小游戏的分数做为奖励,在互动界面购置一些装饰品之类的,应该会增加不少游戏的趣味性。

附:

此项目源码地址:/stdioh_cn/jumpingdog

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。