当前位置: 首页 > news >正文

cocos creator 3.x实现手机虚拟操作杆

简介

在许多移动游戏中,虚拟操纵杆是一个重要的用户界面元素,用于控制角色或物体的移动。本文将介绍如何在Unity中实现虚拟操纵杆,提供了一段用于移动控制的代码。我们将讨论不同类型的虚拟操纵杆,如固定和跟随,以及如何在实际游戏中使用这些操纵杆。

unity2022版本实现虚拟操作杆可以查看这篇文章 点击查看

界面节点设置


1. 添加一个Canvas节点

首先,我们需要创建一个画布节点,这是我们整个界面的基础。这个节点将允许我们绘制和排列其他元素。

2. 在Canvas节点下添加一个Camera节点

接下来,我们将在Canvas节点下创建一个Camera节点。这个Camera节点是查看操作按钮的摄像头

2. 在Canvas节点下添加一个Joystick节点

这个Joystick节点将充当容器,用于组织和管理我们的界面元素。

3. 在Joystick节点下添加两个Sprite节点

在Joystick节点中,我们将添加两个Sprite节点。这两个Image节点具有不同的用途:

a. 背景节点:第一个Sprite节点将用作背景,为整个界面提供背景图像或颜色。

b. 操作按钮节点:第二个Sprite节点将用于显示操作按钮或其他交互元素。

Canvas (画布)
│
└─ Camera (摄像机)
└─ Joystick (虚拟操作父节点)│├─ Bg(背景)│└─ Btn(操作按钮)

截图可以这样:

脚本编写


简要说明:


因为编写的是虚拟操作杆 需要添加三个事件:

触摸开始(touchStart),拖动(touchMove),触摸结束(touchEnd)

在触摸开始记录拖动的一些起始坐标。

在拖动中移动操作按钮节点如果是操作角色移动这里就可以操作移动角色

在触摸结束的时候重置坐标

        1.touchStart方法:描述touchStart方法,它处理当玩家触摸操纵杆时的行为。根据操纵杆类型(固定或跟随),它设置操纵杆的初始位置。

        2.touchMove方法:详细解释touchMove方法,这是当玩家拖动操纵杆时执行的代码。说明如何计算操纵杆输入的方向,以及如何限制操纵杆的移动范围。

        3.touchEnd方法:描述touchEnd方法,用于当玩家释放操纵杆时重置相关变量和位置,同时停止玩家的移动。在初始化引用的时候可以传入参数(JoystickType)控制虚拟操作杆是固定的还是跟随触摸点的

完整的脚本如下:

import { Component, assetManager, _decorator, Node, Prefab, instantiate, JsonAsset, UITransform, Vec3, Widget, Graphics, Enum, input, Input, EventTouch, RichText, Label, sys, CCString, Vec2, Camera } from "cc"
import utils from "../../../utils";
const { ccclass, property, type } = _decorator;// 定义操纵杆的类型
export enum JoystickType {FIXED,    // 固定类型的操纵杆FOLLOW    // 跟随类型的操纵杆
}// 定义操纵杆的显示类型
export enum JoystickShowType {ALWAYS_DISPLAY,         // 一直显示NOT_ALWAYS_DISPLAY      // 仅在操作时显示
}@ccclass('Joystick')
export default class Joystick extends Component {// 绑定Camera组件,用于获取屏幕触摸位置@property(Camera)public camera: Camera;// 绑定操纵杆节点@property(Node)public joystick: Node;// 绑定操纵杆背景节点@property(Node)public joystickBG: Node;// 绑定操纵杆的父节点@property(Node)public joystickParent: Node;// 存储操纵杆的移动向量public joystickVec: Vec3;// 指定操纵杆的类型(固定或跟随)@property({type: Enum(JoystickType),tooltip: "类型"})public joystickType: JoystickType = JoystickType.FIXED;// 指定操纵杆的显示类型(一直显示或仅操作时显示)@property({type: Enum(JoystickShowType),tooltip: "显示类型"})public joystickShowType: JoystickShowType = JoystickShowType.ALWAYS_DISPLAY;// 触摸开始时操纵杆的位置private joystickTouchPos: Vec3;// 操纵杆背景的原始位置private joystickOriginalPos: Vec3;// 操纵杆背景的半径private joystickRadius: number;// 标识是否开始拖动操纵杆public startDrop: boolean;// 初始化start() {// 根据操纵杆显示类型设置其初始显示状态if (this.joystickShowType === JoystickShowType.NOT_ALWAYS_DISPLAY) {this.joystickParent.active = false;} else {this.joystickParent.active = true;}// 保存操纵杆背景的原始位置this.joystickOriginalPos = this.joystickBG.position.clone();// 计算操纵杆背景的半径(背景节点宽度的一半)this.joystickRadius = utils.getNodeSize(this.joystickBG).width / 2;// 绑定触摸事件的处理函数this.node.on(Input.EventType.TOUCH_END, this.touchEnd, this);this.node.on(Input.EventType.TOUCH_START, this.touchStart, this);this.node.on(Input.EventType.TOUCH_MOVE, this.touchMove, this);}// 在组件销毁时,解除触摸事件的绑定protected onDestroy(): void {this.node.off(Input.EventType.TOUCH_END, this.touchEnd, this);this.node.off(Input.EventType.TOUCH_START, this.touchStart, this);this.node.off(Input.EventType.TOUCH_MOVE, this.touchMove, this);}/*** 获取触摸事件在节点坐标系中的位置** @param e 触摸事件对象* @returns 触摸事件在节点坐标系中的位置*/getEventPosInNodePos(e: EventTouch) {// 获取触摸点的屏幕坐标let p = e.getLocation();// 将屏幕坐标转换为世界坐标let word = this.camera.screenToWorld(utils.getVec3(p));// 获取UITransform组件,将世界坐标转换为节点本地坐标let uiTransform = this.node.getComponent(UITransform);let localPos = uiTransform.convertToNodeSpaceAR(new Vec3(word.x, word.y));return localPos;}// 触摸开始事件处理函数touchStart(e: EventTouch) {this.startDrop = true;this.joystickParent.active = true;// 根据操纵杆类型设置初始触摸位置if (this.joystickType == JoystickType.FIXED) {// 固定类型的操纵杆,设置触摸位置为操纵杆背景的原始位置this.joystickTouchPos = this.joystickOriginalPos.clone();} else if (this.joystickType == JoystickType.FOLLOW) {// 跟随类型的操纵杆,将操纵杆和背景设置为触摸位置this.joystick.setPosition(utils.nodePosToNodePos(this.getEventPosInNodePos(e), this.node, this.joystick.parent));this.joystickBG.setPosition(this.joystick.position);this.joystickTouchPos = this.joystick.position.clone();}// 处理触摸移动this.touchMove(e);}/*** 触摸移动事件处理函数** @param e 触摸事件对象*/touchMove(e: EventTouch) {// 如果没有开始拖动,则不处理if (this.startDrop === false) {return;}// 获取操纵杆触摸位置的副本let joystickTouchPos = this.joystickTouchPos.clone();// 获取触摸事件在节点坐标系中的位置let dragPos = this.getEventPosInNodePos(e);// 获取操纵杆背景相对于节点的本地坐标let nodePos = utils.nodePosToNodePos(joystickTouchPos, this.joystickBG.parent, this.node);// 计算操纵杆的移动向量,并归一化let joystickVec = dragPos.clone().subtract(nodePos).normalize();// 计算触摸点与操纵杆触摸位置之间的距离let joystickDist = Vec3.distance(dragPos, nodePos);// 限制操纵杆在指定半径范围内移动if (joystickDist < this.joystickRadius) {// 如果距离小于半径,直接设置操纵杆的位置let pos = joystickTouchPos.add(joystickVec.multiplyScalar(joystickDist));this.joystick.setPosition(pos);} else {// 如果距离大于半径,设置操纵杆到半径位置let pos = joystickTouchPos.add(joystickVec.multiplyScalar(this.joystickRadius));this.joystick.setPosition(pos);}}/*** 触摸结束事件处理函数** @param e 触摸事件对象*/touchEnd(e: EventTouch) {// 标识结束拖动this.startDrop = false;// 根据操纵杆显示类型设置其显示状态if (this.joystickShowType === JoystickShowType.NOT_ALWAYS_DISPLAY) {this.joystickParent.active = false;} else {this.joystickParent.active = true;}// 将操纵杆移动向量重置为零this.joystickVec = Vec3.ZERO;// 将操纵杆和背景位置重置为原始位置this.joystick.setPosition(this.joystickOriginalPos);this.joystickBG.setPosition(this.joystickOriginalPos);}
}

大致效果如下:

固定

跟随

社交:

QQ群:859055710 

相关文章:

cocos creator 3.x实现手机虚拟操作杆

简介 在许多移动游戏中&#xff0c;虚拟操纵杆是一个重要的用户界面元素&#xff0c;用于控制角色或物体的移动。本文将介绍如何在Unity中实现虚拟操纵杆&#xff0c;提供了一段用于移动控制的代码。我们将讨论不同类型的虚拟操纵杆&#xff0c;如固定和跟随&#xff0c;以及如…...

【数据分享】中国电力年鉴(2004-2022)

大家好&#xff01;今天我要向大家介绍一份重要的中国电力统计数据资源——《中国电力年鉴》。这份年鉴涵盖了从2004年到2022年中国电力统计全面数据&#xff0c;并提供限时免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 自1993年首次出版以来&#xf…...

两个数组的交集Ⅱ-力扣

想到的解法是使用两个map来进行记录&#xff0c;mp1用来统计num1中每个元素出现的次数。当nums2的元素能够在mp1中查找到时&#xff0c;将这个元素添加到mp2&#xff0c;按照这个规则统计得到nums2和nums1重复的元素&#xff0c;mp2中的value记录了nums2中这个元素出现的次数最…...

【TCP协议中104解析】wireshark抓取流量包工具,群殴协议解析基础

Tcp ,104 ,wireshark工具进行解析 IEC104 是用于监控和诊断工业控制网络的一种标准&#xff0c;而 Wireshark则是一款常用的网络协议分析工具&#xff0c;可以用干解析TEC104 报文。本文将介绍如何使用 Wireshark解析 IEC104报文&#xff0c;以及解析过 程中的注意事项。 一、安…...

[个人笔记] 记录docker-compose使用和Harbor的部署过程

容器技术 第三章 记录docker-compose使用和Harbor的部署过程 容器技术记录docker-compose使用和Harbor的部署过程Harborhttps方式部署&#xff1a;测试环境部署使用自签名SSL证书https方式部署&#xff1a;正式环境部署使用企业颁发的SSL证书给Docker守护进程添加Harbor的SSL证…...

详细介绍运算符重载函数,清晰明了

祝各位六一快乐~ 前言 1.为什么要进行运算符重载&#xff1f; C中预定义的运算符的操作对象只能是基本数据类型。但实际上&#xff0c;对于许多用户自定义类型&#xff08;例如类&#xff09;&#xff0c;也需要类似的运算操作。这时就必须在C中重新定义这些运算符&#xff…...

国内外知名的低代码开发平台下载地址

以下是国内外几款低代码开发平台的列表&#xff0c;包含了下载地址、适应操作系统、是否可以独立部署、优点、缺点以及是否包含流程引擎的信息。 平台名称 下载地址 适应操作系统 是否可以独立部署 优点 缺点 是否包含流程引擎 国内平台 阿里云宜搭 阿里云官网 跨平台…...

【Pr学习】01新建项目起步

【Pr学习】01新建项目起步 1、新建项目2.序列设置2.1新建序列2.2序列参数讲解2.3自定义设置 3.PR窗口认识3.1 项目窗口3.2 源窗口2.4 保存面板 4.剪辑导入4.1 素材导入4.2 视图切换4.3 时间轴4.4轨道工具4.5 节目窗口素材导入 5.基础操作5.1 取消视频音频链接5.2 单独渲染&…...

【Redis延迟队列】redis中的阻塞队列和延迟队列

阻塞队列&#xff08;RBlockingQueue&#xff09; 作用和特点&#xff1a; 实时性&#xff1a;阻塞队列用于实时处理消息。生产者将消息放入队列&#xff0c;消费者可以立即从队列中取出并处理消息。阻塞特性&#xff1a;如果队列为空&#xff0c;消费者在尝试获取消息时会被…...

el-tree常用操作

一、定义 <el-treeclass"myTreeClass":data"dirTreeData":props"dirTreeProps":filter-node-method"filterDirTree":expand-on-click-node"false"node-key"id"node-click"dirTreeNodeClick":allow-…...

SQL 语言:存储过程和触发器

文章目录 基本概述创建触发器更改和删除触发器总结 基本概述 存储过程&#xff0c;类似于高阶语言的函数或者方法&#xff0c;包含SQL语句序列&#xff0c;是可复用的语句&#xff0c;保存在数据库中&#xff0c;在服务器中执行。特点是复用&#xff0c;提高了效率&#xff0c…...

Ubuntu Linux 24.04 使用certbot生成ssl证书

设置域名 1. 将需要生成SSL证书的域名解析到IP地址 idealand.xyz <> 64.176.82.190 检查防火墙的设置 1. 首先查看防火墙的状态&#xff1a; # ufw status 2. 如果防火墙开启了&#xff0c;要开放80和443端口用于certbot验证 # ufw allow 80 # ufw allow 443 生…...

Vivado 比特流编译时间获取以及FPGA电压温度获取(实用)

Vivado 比特流编译时间获取以及FPGA电压温度获取 语言 &#xff1a;Verilg HDL 、VHDL EDA工具&#xff1a;ISE、Vivado Vivado 比特流编译时间获取以及FPGA电压温度获取一、引言二、 获取FPGA 当前程序的编译时间verilog中直接调用下面源语2. FPGA电压温度获取&#xff08;1&a…...

Window下VS2019编译WebRTC通关版

这段时间需要实现这样一个功能&#xff0c;使用WebRTC实现语音通话功能&#xff0c;第一步要做的事情就是编译WebRTC源码&#xff0c;也是很多码友会遇到的问题。 经过我很多天的踩坑终于踩出来一条通往胜利的大路&#xff0c;下面就为大家详细介绍&#xff0c;编译步骤以及踩…...

【云原生 | 60】Docker中通过docker-compose部署kafka集群

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…...

allure测试报告用例数和 pytest执行用例数不相同问题

我出现的奇怪问题&#xff1a; pytest执行了9条用例&#xff0c;但是测试报告确只显示3条用例 我将其中的一个代码删除后&#xff0c;发现allure测试报告又正常了 我觉得很奇怪这个代码只是删除了二维数组的第一列&#xff0c;我检查了半天都找不到问题&#xff0c;只有降低版本…...

Ubuntu 离线安装 gcc、g++、make 等依赖包

前言 项目现场的服务器无法连接互联网&#xff0c;需要提前获取 gcc、g、make 等依赖包。 一、如何获取依赖包 需要准备一台可以连接互联网的电脑&#xff08;如&#xff1a;个人电脑上的虚拟机安装一个与服务器一样的系统&#xff09;&#xff0c;用于下载依赖包。之后把通过…...

Vxe UI vxe-upload 上传组件,显示进度条的方法

vxe-upload 上传组件 查看官网 https://vxeui.com 显示进度条很简单&#xff0c;需要后台支持进度就可以了&#xff0c;后台实现逻辑具体可以百度&#xff0c;这里只介绍前端逻辑。 上传附件 相关参数说明&#xff0c;具体可以看文档&#xff1a; multiple 是否允许多选 li…...

探索API接口:技术深度解析与应用实践

在当今的软件开发和数据交换领域&#xff0c;API&#xff08;应用程序编程接口&#xff09;已经成为了一个不可或缺的工具。它允许不同的软件应用程序或组件之间进行交互和通信&#xff0c;从而实现了数据的共享和功能的扩展。本文将深入探讨API接口的技术原理、设计原则以及在…...

ARM-V9 RME(Realm Management Extension)系统架构之系统安全能力的系统隔离属性

安全之安全(security)博客目录导读 目录 一、系统隔离属性 1、系统配置完整性 1.1、时间隔离 2、关键错误的报告 一、系统隔离属性 1、系统配置完整性 MSD必须确保任何可能危及其安全保证的系统寄存器的正确性和完整性。例如&#xff0c;MSD必须确认内存控制器配置是一致…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...