《Cocos Creator游戏实战》虚拟摇杆实现
虚拟摇杆实现
摇杆布局实现
摇杆功能实现
用摇杆控制主角
该功能已收录在Many Widgets插件中,使用Cocos Creator 3.x版本的小伙伴可以用该插件快速生成摇杆。
插件地址:https://store.cocos.com/app/detail/3147
2D摇杆演示地址:https://www.bilibili.com/video/BV1LP4y1W73z/
3D摇杆演示地址:https://www.bilibili.com/video/BV1w64y1Y7Xm/
在本教程中我们实现一个控制主角转向并移动的虚拟摇杆。
运行效果如下:
Cocos Creator版本:2.2.0
公众号后台回复"虚拟摇杆",获取该教程完整代码下载地址:
摇杆布局实现
项目文件的初始内容截图如下:
新建一个名为joystick的场景,textures文件夹中有两张图片分为作为摇杆背景和摇杆按钮,JoyStick.js中存放摇杆功能代码。
首先我们把joystick_panel图片拖到层级管理器中作为Canvas的子节点:
然后再将joystick_btn图片拖到层级管理器中,让它作为joystick_panel的子节点(这样按钮就会自动位于背景的正中央):
接着在属性检查器中设置joystick_btn宽高为60:
现在场景编辑器显示如下:
通常摇杆位于屏幕左下方,所以我们给joystick_panel节点添加一个Widget组件来固定其位置:
我们设置该节点离屏幕左边和底部的距离值都为5%:
游戏运行截图如下:
我们看到左下角的FPS信息遮挡了一些,我们在JoyStick.js中用这行代码可以把它去掉:
onLoad () {// hide FPS infocc.debug.setDisplayStats(false);
},
将JoyStick.js挂到joystick_panel节点上后再次运行游戏:
发现已经没有FPS信息了。
摇杆功能实现
这里肯定要用到触摸事件,我们先把这部分相关代码编写完整:
onLoad () {// hide FPS infocc.debug.setDisplayStats(false);// get joyStickBtnthis.joyStickBtn = this.node.children[0]; // touch eventthis.node.on('touchstart', this.onTouchStart, this);this.node.on('touchmove', this.onTouchMove, this);this.node.on('touchend', this.onTouchEnd, this);this.node.on('touchcancel', this.onTouchCancel, this);
},onDestroy() {// touch eventthis.node.off('touchstart', this.onTouchStart, this);this.node.off('touchmove', this.onTouchMove, this);this.node.off('touchend', this.onTouchEnd, this);this.node.off('touchcancel', this.onTouchCancel, this);
},
在onLoad方法中我们也获取了joystick_btn这个节点并存储在joyStickBtn变量中。
下面分别是onTouchStart,onTouchMove,onTouchEnd和onTouchCancel方法实现:
onTouchStart(event) {// when touch starts, set joyStickBtn's position let pos = this.node.convertToNodeSpaceAR(event.getLocation());this.joyStickBtn.setPosition(pos);
},onTouchMove(event) {// constantly change joyStickBtn's positionlet posDelta = event.getDelta();this.joyStickBtn.setPosition(this.joyStickBtn.position.add(posDelta));
},onTouchEnd(event) {// resetthis.joyStickBtn.setPosition(cc.v2(0, 0));
},onTouchCancel(event) {// resetthis.joyStickBtn.setPosition(cc.v2(0, 0));
},
- 在onTouchStart中我们通过event.getLocation()获取触摸坐标,由于这里获取到的是世界坐标,我们需要通过convertToNodeSpaceAR方法将其转换成joystick_panel节点上的坐标。转换好后,将其设置成摇杆按钮的坐标。
- 在onTouchMove中,我们通过event.getDelta()获取手指位移距离(向量),然后加上当前摇杆按钮的坐标就得到了按钮在移动之后的坐标。
- 在onTouchEnd和onTouchCancel中,我们还原按钮位置。
此时运行游戏,我们发现一个待完善的地方,就是按钮它可以移动到摇杆背景外:
为解决这个问题我们在update方法中添加如下代码:
update (dt) {// get ratiolet len = this.joyStickBtn.position.mag();let maxLen = this.node.width / 2;let ratio = len / maxLen;// restrict joyStickBtn inside the joyStickPanelif (ratio > 1) {this.joyStickBtn.setPosition(this.joyStickBtn.position.div(ratio));}
},
为方便理解以上代码,请看下面这张图:
首先获取摇杆按钮当前所在位置坐标(x1, y1),因为这是一个向量,所以我们可以调用mag()求出该向量的长度len。也就是按钮中心到原点(摇杆背景中心)的直线长度。如果该直线长度大于摇杆背景的半径maxLen(按钮在背景外),那我们就获取超出的比例值ratio,然后让按钮当前的坐标除以它,即x1/ratio和y1/ratio,这样我们其实就得到了按钮在摇杆背景边界上时的x和y坐标。
现在运行游戏你会发现摇杆按钮被限制在了背景中:
用摇杆控制主角
这里的主角我们直接用粒子来代替。在层级管理器中创建一个粒子节点并重命名为player:
接着我们在properties中添加两个属性,一个是用于挂载节点,另一个用于设置主角最大移动速度:
properties: {player: {default: null,type: cc.Node},maxSpeed: 0,
},
将player节点拖入,并设置maxSpeed属性值为10:
现在来解决主角的移动问题。首先是移动方向,我们在onLoad方法中新建一个dir变量用于存储主角移动方向:
onLoad () {...// Player's move directionthis.dir = cc.v2(0, 0);...
},
读者如果玩过带摇杆功能的游戏的话,应该都知道摇杆按钮的移动方向就是主角的移动方向。而我们在onTouchMove方法中是知道主角移动后的坐标(向量)的,所以获取方向非常简单:
onTouchMove(event) {// constantly change joyStickBtn's positionlet posDelta = event.getDelta();this.joyStickBtn.setPosition(this.joyStickBtn.position.add(posDelta));// get directionthis.dir = this.joyStickBtn.position.normalize();
},
我们这里调用了normalize()让向量归一化(方向不变但长度为1)。
接着在update方法中设置玩家位置:
update (dt) {...// move Playerlet dis = this.dir.mul(this.maxSpeed * ratio);this.player.setPosition(this.player.position.add(dis));
},
this.maxSpeed *ratio表示主角移动的速度会根据摇杆按钮所移动的距离来变换。如果摇杆按钮只移动一点,那么主角移动速度就慢;如果摇杆按钮处于摇杆背景的边界处,那么移动速度就达到最大值。
然后我们再将得到的值与this.dir这个方向向量相乘,这样就可以得到朝特定方向的位移大小,最后加上主角当前位置即可。
当然我们还得限制主角移动范围,不能移动到屏幕外边:
update (dt) {...// move Playerlet dis = this.dir.mul(this.maxSpeed * ratio);this.player.setPosition(this.player.position.add(dis));// restrict Player inside the Canvasif (this.player.x > this.player.parent.width / 2)this.player.x = this.player.parent.width / 2;else if (this.player.x < -this.player.parent.width / 2)this.player.x = -this.player.parent.width /2;if (this.player.y > this.player.parent.height / 2)this.player.y = this.player.parent.height / 2;else if (this.player.y < -this.player.parent.height / 2)this.player.y = -this.player.parent.height / 2;
},
这里的this.player.parent就是Canvas节点。
运行截图如下:
好,那到这里虚拟摇杆的功能就全部都实现了,希望大家有所收获!
欢迎关注我的微信公众号,发现更多有趣内容:
《Cocos Creator游戏实战》虚拟摇杆实现相关推荐
- 《Cocos Creator游戏实战》贪吃蛇平滑移动
贪吃蛇平滑移动 贪吃蛇平滑移动 初始化蛇头和蛇身 调整蛇头方向 贪吃蛇移动 蛇头和蛇身的节点顺序 添加食物 添加碰撞逻辑代码 从pointsArray中剔除无用的坐标点(更新) 在本教程中我们重点来学 ...
- 《Cocos Creator游戏实战》棋类游戏中的棋子摆放逻辑
棋类游戏中的棋子摆放逻辑 创建节点 代码编写 其实要点就一句话:我们看到的不应是棋盘,而是坐标. 现在通过下面的五子棋(或围棋)实例来看下如何理解这句话. 运行效果如下: Cocos Creator版 ...
- 《Cocos Creator游戏实战》游戏转场时如何保留节点信息
游戏转场时如何保留节点信息 使用常驻节点 使用全局变量 使用本地存储 引擎同时只会运行一个场景,当切换场景时,默认会将场景内所有节点和其他实例销毁(本句来自Cocos Creator文档). 在这一节 ...
- 《Cocos Creator游戏实战》摘星星进阶版
摘星星进阶版 添加开始按钮 实现按钮功能 显示"Game Over" 限制主角移动范围 让跳跃动作更加细腻 加入星星收集动画 编写动画脚本 加入触屏控制 添加游戏提示 Cocos ...
- 《Cocos Creator游戏实战》新手引导实现
新手引导实现 新建节点 完成代码 该功能已收录在Many Widgets插件中,使用Cocos Creator 3.x版本的小伙伴可以用该插件快速生成新手引导. 插件地址:https://store. ...
- 《Cocos Creator游戏实战》关卡功能实现
关卡功能实现 创建节点 设置关卡信息 实现关卡界面 为预制添加脚本 完善Game.js逻辑 在上一节教程中我们讲解了打砖块的主要功能与逻辑实现,在这一篇教程中,笔者会在它的基础上增加关卡功能(建议先阅 ...
- 《Cocos Creator游戏实战》老虎机抽奖效果实现思路
在线体验地址 Cocos Creator | SlotMachine Cocos Store 购买地址(如果没有显示,那就是还在审核): https://store.cocos.com/app/det ...
- cocoscreator editbox 只允许数字_《Cocos Creator游戏实战》做一个数字调节框
当玩家购买道具的时候,一个个买可能会比较麻烦,用数字调节框的话玩家一次性就可以买好几十个了(钱够的话). 运行效果如下: Cocos Creator版本:2.2.0 公号"All Codes ...
- 《Cocos Creator游戏实战》你画我猜中的画板功能
你画我猜中的画板功能 创建节点 完成脚本 本节我们来做一个画板,该画板一共有三个小功能: 调节笔刷大小 改变笔刷颜色 橡皮擦 运行效果如下: Cocos Creator版本:2.2.0 后台回复&qu ...
最新文章
- 【前端2】js:原始类型,运算符,调试,页面加载,轮播图,Bom(对象,时钟),Dom(全选全不选,省市级联,隔行/触摸换色,表单校验)
- 【F3简介】一张图看懂FPGA-F3实例
- 目前最厉害的象棋软件_qq什么引流方式最厉害,QQ引流目前最有效的方法
- ros安装过后怎么找不到安装文件_ros配置乐视奥比中光相机
- 275. H-Index II 递增排序后的论文引用量
- 【玩转Golang】 自定义json序列化对象时,非法字符错误原因
- C#异步方法调用(四大方法详解)
- 网络流(最大流) CQOI 2015 BZOJ 3931 网络吞吐量
- SQL进阶教程(一)——CASE表达式
- (首个填坑)联想拯救者Y7000(自带win10 home) 安装Ubuntu16.04.6 + NVIDIA GTX1650驱动
- 计算机网络原理 谢希仁(第8版)第二章习题答案
- Python — — turtle 常用代码
- ubuntu linux 郑码,如何输入间隔号 - dengyz的个人页面 - OSCHINA - 中文开源技术交流社区...
- 在北京租房 舒舍的租客素质怎么样?
- 程序员的奋斗史(七)——沟通交流、表达能力的重要性
- 5.2.1_3 普通心理学(彭冉玲第四版) - 第2章 心理的神经生理机制
- HBuilder打开发生了错误。请参阅日志文件
- 浅谈一下汽车行业中的OTA/FOTA/SOTA
- 爸爸给4岁女儿的遗书 10年后女儿回了信(感人)
- 基于微信小程序的校园跑腿系统
热门文章
- 行人检测——Caltech Pedestrian Dataset 数据集的使用
- 4.设备像素、css像素、设备独立像素、dpr、ppi 之间的区别?
- .NET Framework和.NET Core/.NET5/.NET6
- Git与Git可视化工具TortoiseGit-小乌龟安装和配置
- PRE_LOAD+putenv
- HTML5期末大作业:生鲜超市网站设计——生鲜超市网站设计(5页)HTML+CSS+JavaScript 学生DW网页设计作业成品 美食站
- 计算机应用基础18在线作业容,东师《计算机应用基础》18秋在线作业2.doc
- Cesium 卫星轨迹、卫星通信、卫星过境,模拟数据传输。
- 笨方法学Python 练习16
- 本固枝荣 —— Java关键字之分类