《Cocos Creator游戏实战》非固定摇杆实现原理

devtools/2024/12/25 13:14:13/

为什么要使用非固定摇杆

许多同学在开发摇杆功能时,会将摇杆固定在屏幕左下某一位置,不会让其随着大拇指触摸点改变,而且玩家只有按在了摇杆上才能移动人物(触摸监听事件在摇杆精灵上)。然而,不同玩家的大拇指长度不同,使用这种固定摇杆可能会导致部分玩家无法快速按到摇杆,从而影响了游戏操作性。

非固定摇杆不需要玩家去寻找摇杆位置,玩家的大拇指只要在屏幕左下区域按下,摇杆就会自动被设置到大拇指按下的位置(触摸监听事件在画布上),游戏操作性因此提升。

注:有关固定摇杆的具体实现原理可以前往查看笔者的这篇文章。
P.S. 上面的摇杆文章发布的时间是19年10月,时间过得好快。


运行效果和源码获取

<a class=非固定摇杆" />

Cocos Creator>Cocos Creator版本: 3.8.4
项目源码获取:搜索公号All Codes,公号后台发送"非固定摇杆"


实现原理

1: 在摇杆组件生效时记录摇杆的位置。

/* 记录摇杆最初位置 */
recordOriginalPos() {this.originalPos = new Vec3(this.node.position)
}

2: 在TOUCH_START事件函数中,判断玩家触摸点是否在屏幕左下区域,是的话将摇杆设置到触摸点位置,不是的话则直接返回。
在这里插入图片描述

onTouchStart(event: EventTouch) {// 获取触摸点坐标let loc = event.getUILocation()let pos = this.canvas.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(loc.x, loc.y, 0))// 判断触摸点是否在画布左下区域// 不是的话直接返回,是的话设置摇杆底部面板位置if (pos.x > 0 || pos.y > 0) {return}this.node.setPosition(pos)this.isTouchAreaCorrect = true
}

3: 在TOUCH_MOVE事件函数中,更新摇杆中心按钮在摇杆底部面板上的位置。
在这里插入图片描述

onTouchMove(event: EventTouch) {if (!this.isTouchAreaCorrect) {return}// 在该事件中我们只需要设置摇杆中心按钮的位置let posDelta = event.getDelta()this.joystickBtn.setPosition(new Vec3(this.joystickBtn.position).add3f(posDelta.x, posDelta.y, 0))// 获取移动方向和旋转角度this.dir = new Vec3(this.joystickBtn.position.x, this.joystickBtn.position.y, 0).normalize()if (this.dir.y > 0) {this.angle =  Vec3.angle(this.dir, new Vec3(1, 0, 0)) * 180 / Math.PI}else {this.angle =  -Vec3.angle(this.dir, new Vec3(1, 0, 0)) * 180 / Math.PI}// 设置主角isMoving变量为truethis.playerComp.isMoving = true 
}

4: 在TOUCH_END和TOUCH_CANCEL事件函数中,重置相关变量并复原摇杆位置。摇杆底部面板回到在第1步中记录的位置,摇杆中心按钮回到摇杆底部面板中心位置。

onTouchEnd(event: EventTouch) {// 复原摇杆位置,重置相关变量this.node.setPosition(this.originalPos)this.joystickBtn.setPosition(Vec3.ZERO)this.playerComp.isMoving = falsethis.isTouchAreaCorrect = false
}onTouchCancel(event: EventTouch) {// 复原摇杆位置,重置相关变量this.node.setPosition(this.originalPos)this.joystickBtn.setPosition(Vec3.ZERO)this.playerComp.isMoving = falsethis.isTouchAreaCorrect = false
}

王者荣耀中的非固定摇杆
请添加图片描述


http://www.ppmy.cn/devtools/145265.html

相关文章

力扣238. 除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…

YOLOv9-0.1部分代码阅读笔记-dataloaders.py

dataloaders.py utils\dataloaders.py 目录 dataloaders.py 1.所需的库和模块 2.def get_hash(paths): 3.def exif_size(img): 4.def exif_transpose(image): 5.def seed_worker(worker_id): 6.def create_dataloader(path, imgsz, batch_size, stride, single_cl…

Apache RocketMQ 5.1.3安装部署文档

官方文档不好使&#xff0c;可以说是一坨… 关键词&#xff1a;Apache RocketMQ 5.0 JDK 17 废话少说&#xff0c;开整。 1.版本 官网地址&#xff0c;版本如下。 https://rocketmq.apache.org/download2.配置文件 2.1namesrv端口 在ROCKETMQ_HOME/conf下 新增namesrv.pro…

Linux 环境下运行 .NET 8.0 core项目

在 Linux 环境下运行 .NET 8.0 项目&#xff0c;.NET 已支持跨平台运行&#xff0c;以下是完整的步骤&#xff1a; 1. 安装 .NET 8.0 SDK 或运行时 首先需要在 Linux 系统中安装 .NET 8.0 SDK 或运行时。 1.1 添加 Microsoft 包管理源 运行以下命令添加 Microsoft 包管理源并安…

深度学习之超分辨率算法——FRCNN

– 对之前SRCNN算法的改进 输出层采用转置卷积层放大尺寸&#xff0c;这样可以直接将低分辨率图片输入模型中&#xff0c;解决了输入尺度问题。改变特征维数&#xff0c;使用更小的卷积核和使用更多的映射层。卷积核更小&#xff0c;加入了更多的激活层。共享其中的映射层&…

html固定头和第一列简单例子

<!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>冻结第一行和第一列的表格</titl…

网络协议入门

一、概述 1、模型 为了减少协议设计的复杂性&#xff0c;大多数网络模型均采用分层的方式来组织。每一层都有自己的功能&#xff0c;就像建筑物一样&#xff0c;每一层都靠下一层支持。每一层利用下一层提供的服务来为上一层提供服务&#xff0c;本层服务的实现细节对上层屏蔽…

外包干了两年,技术退步明显...

先说一下自己的情况&#xff0c;普通本科&#xff0c;曾在外包干了2年多的功能测试&#xff0c;再加上大环境不好&#xff0c;那时我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;所以当时我感觉自己不能够在这样蹉跎下去了&#xff0c;长时间呆在一个舒适的环境…