【基于Cocos Creator 3.5的赛车游戏】8.引入触摸屏幕事件并简单的控制小车

转载知识星球 | 深度连接铁杆粉丝,运营高品质社群,知识变现的工具

项目地址:赛车小游戏-基于Cocos Creator 3.5版本实现: 课程的源码,基于Cocos Creator 3.5版本实现

上一张您已经对Cocos的坐标系有了了解。这一章我们将让小车能够自动的向您触控的点运动过去。所以为了达到这个目的,我们要接收触摸屏幕事件,再对小车的刚体组件施加一个由小车的坐标点指向触摸点的力。具体步骤如下:

一、实现一个触控类:

1.请在script文件夹下新建一个名为TouchInput的脚本文件,我们将会在这里完成对触控事件的接收。新建脚本后效果如下:

2.打开并初步编辑脚本文件

双击这个脚本文件,VS Code将会为您打开并编辑这个脚本文件,因为这个脚本文件只负责处理触控事件,不会挂载到某个节点上,所以它无需具备组件的特性,所以我们可以删掉他的“extend Componment”属性。而您要实现的游戏是个单人游戏,也就是说触控接收器只为由玩家操控的汽车节点提供触控事件处理服务,不会为别的节点例如电脑提供的NPC车辆提供服务,所以以单例模式运行即可。综上,TouchInput的初步代码为:

3.接收触摸事件

cocos中采用input常量中的on方法来注册事件,on方法一共有两个参数:第一个参数是要注册的事件类型,事件类型的枚举值都Input.EventType下;第二个参数是一个方法,当接收到对应事件后这个方法将会执行,这个方法的入参是框架已经为您封装好的事件的具体值,例如点击的是哪个坐标点等。现在您要实现的是点击屏幕来控制小车的运动,所以在控制器里首先您需要注册开始点击、结束点击、点击时手指移动以及点击时手指移动到触控区域外这四个函数,不过在处理时,我们可以把点击时手指移动到触控区域外也视为结束点击的逻辑。其次我们还需要记录当前是否玩家处于点击状态以及当前的触控点的坐标。具体代码如下:

import { _decorator, Component, Node, input, Input, Vec2 } from 'cc';
const { ccclass, property } = _decorator;@ccclass('TouchInput')
export class TouchInput {private static singleiInstance: TouchInput = new TouchInput();touchX: number = 0;touchY: number = 0;inTouch: boolean = falsestatic Instance() {return TouchInput.singleiInstance;};private constructor() { input.on(Input.EventType.TOUCH_MOVE, (event)=>{this.inTouch = truevar pos = new Vec2(event.getLocation())this.touchX = pos.xthis.touchY = pos.yconsole.log('移动中 点击的X坐标: '+this.touchX+  ' 点击的Y坐标:'+this.touchY + ' 点击状态:'+this.inTouch)})input.on(Input.EventType.TOUCH_START,(event)=>{this.inTouch = truevar pos = new Vec2(event.getLocation())this.touchX = pos.xthis.touchY = pos.yconsole.log('开始点击 点击的X坐标: '+this.touchX+  ' 点击的Y坐标:'+this.touchY+ ' 点击状态:'+this.inTouch)})input.on(Input.EventType.TOUCH_CANCEL,(event)=>{this.inTouch = falseconsole.log('点击结束 点击的X坐标: '+this.touchX+  ' 点击的Y坐标:'+this.touchY+ ' 点击状态:'+this.inTouch)})input.on(Input.EventType.TOUCH_END,(event)=>{this.inTouch = falseconsole.log('点击结束 点击的X坐标: '+this.touchX+  ' 点击的Y坐标:'+this.touchY+ ' 点击状态:'+this.inTouch)})}
}

我们可以看到,我们在实例化类时自动执行的构造函数中注册了对应的事件,并且将是否处于触控状态以及点击的坐标保存到了TouchInput的成员变量中。

4.测试触摸接收事件:

保存好文件,然后点击运行按钮,在浏览器运行后打开开发者工具,然后在屏幕上点击任意位置,我们将会在控制台中看到对event的打印:

也许你可能会有疑问,为何感觉console.log打印出来的坐标和上一章说的无论是世界坐标系还是本地坐标系都匹配不上?这是因为点击事件返回的点是根据触控坐标系计算出来的,您可能会对又引入了一个坐标系感到很Angry,但是不要紧,只需要使用相机来转化一下就能把触控坐标转化为世界坐标,这个具体过程我们会在后面实现。

5.在控制汽车节点的CarControl脚本中引入并使用TouchInput:

双击CarControl来让VS Code编辑它,我们先清空下update方法中的语句,然后把添加一个TouchInput类型的成员变量,并且在start函数中让这个成员变量指向TouchInput的单例。具体效果如下:

6.分析小车向触控点运动的实现:

我们要实现的效果是小车向玩家点击屏幕的位置移动,所以在代码中的逻辑就是:在每一帧的update的函数中,先获取touchInput的inTouch字段来判断下是否处于触摸状态,如果处于触摸状态,就获取到触摸点,然后将触摸点转换为世界坐标,最后再给小车的刚体组件施加一个由当前小车刚体所在的节点的世界坐标点指向触摸点的世界坐标点的力。

7.引入camera组件:

上一步骤中说到,获取到触摸点后要将触摸点转换为世界坐标才能参与后续计算,camera类中提供了screenToWorld方法来完成了这种转换。所以我们要引入camera。和引入汽车节点的刚体组件时一样,我们先声明一个Camera类型的gameCamera成员变量并且为他添加上给Cocos Creator看的注解。也许你会问我为什么不直接叫camera而是叫gameCamera,这是因为后期要显示UI,所以可能不只有一个摄像头,所以这个就不采用比较笼统的camera的名字:

然后回到Cocos Creator中,指定这个变量指向Game场景下的Canvas下的Camera:

8.实现步骤6的逻辑:

逻辑非常简单,把6的步骤给翻译成代码就是了,直接上CarControl的代码:

import { _decorator, Component, Node, RigidBody2D, Vec3, Vec2, math, Camera } from 'cc';
import { TouchInput } from './TouchInput';
const { ccclass, property } = _decorator;@ccclass('CarControl')
export class CarControl extends Component {@property({type: RigidBody2D})carRigidBody: RigidBody2DtouchInput: TouchInput@property({type: Camera})gameCamera: Camerastart() {console.log('------------start-----------------')this.touchInput = TouchInput.Instance()}update(deltaTime: number) {var inTouching: boolean = this.touchInput.inTouchif(!inTouching){return}var twPos: Vec3 =  new Vec3(this.gameCamera.screenToWorld(new Vec3(this.touchInput.touchX,this.touchInput.touchY)))var nwPos: Vec3 = this.carRigidBody.node.getWorldPosition()var force: Vec2 = new Vec2(-nwPos.x+twPos.x,-nwPos.y+twPos.y)this.carRigidBody.applyForceToCenter(force,true)}
}

9.在浏览器中运行并查看结果:

VS Code和Cocos Creator中各自保存好,然后点击运行,在浏览器中查看运行。因为目前没有设置小车的阻力,所以如果一直点击的话持续受力会越来越快,如果只点击一下则会做向点击方向的匀速直线运动。但是不管怎么了,只要点击一下发现小车向着您点击的点做匀速直线运动了就表明没问题了,效果:

10、debug

虽然我们已经看到了小车的受力已经没问题了,但是小车的根节点,也就Car节点并没有随着刚体发生移动:

这是为什么呢,因为在前面的章节中我们在挂载刚体时按照常理给挂载到了小车的CarSprite节点上,而现在我们看到,因为刚体受力而发生位移时只对刚体所在的节点及其子节点生效,所以,刚体应该挂载到Car节点上才对。所以现在需要您删除掉CarSprite上的刚体:

然后按照相同方式在Car上面新建一个刚体:

最后记得让Car节点挂载的CarControl节点的carRigidBody变量指向Car的刚体:

11.重新测试

保存好,然后点击运行按钮,在浏览器中观察效果:

我们可以看到,Car节点不再一直停在起始位置了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/78008.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【经典小练习】JavaSE—拷贝文件夹

🎊专栏【Java小练习】 🍔喜欢的诗句:天行健,君子以自强不息。 🎆音乐分享【如愿】 🎄欢迎并且感谢大家指出小吉的问题🥰 文章目录 🎄效果🌺代码🛸讲解&#x…

微信管理系统在教育行业中的应用

随着教育行业越来越注重科技创新,对微信scrm工具的需求也会越来越大,微信scrm工具在教育行业的市场前景非常广阔,也为教育行业带来更多的发展机遇。 微信SCRM系统由监管、运营两大核心应用组成。能帮助培训机构实现从招生引流、销售管理、再…

【Android知识笔记】UI体系(四)

事件分发原理 屏幕事件会由Linux通过JNI传给WMS(WindowManagerService),然后由WMS传给Activity,最终经过PhoneWindow->DecorView开始往下分发。 View的事件分发 View的事件分发核心源码为 dispatchTouchEvent() 方法: public boolean dispatchTouchEvent(MotionEvent …

导数的应用、单调性、极值、最大最小值

函数的单调性 函数的单调性是一个重要的性质,它描述了函数在某个区间上的变化趋势。如果函数在某个区间上单调递增,那么在这个区间上,随着自变量的增大,函数值也会增大;反之,如果函数在某个区间上单调递减&…

【halcon】halcon字符识别——OCR

前言 OCR(Optical Character Recongnition)光学字符识别。 halcon 的OCR,提供了几种方式,我们应该如何选择? 自动文本阅读器(find_text)手动文本阅读器(find_text)自己…

数据结构基础7:二叉树【链式结构】实现和递归思想。

二叉树的链式结构实现 一.二叉树链式结构的实现:1.前置说明:1.创建二叉树:2.二叉树的结构: 2.二叉树的遍历:1.二叉树的前中后序遍历:2.内容拓展: 二.二叉树链式(题目)题目一:计算节点…

【Axure高保真原型】日历日期原型模板

今天和大家分享日历日期的原型模板,包括月计划、周计划、日计划的原型案例,以及日期、时间、月份、区间选择器……具体效果可以点击下方视频观看 【原型预览及下载地址】 Axure 原型 备用地址:Untitled Document 【原型效果】 【原型效果…

2.k8s账号密码登录设置

文章目录 前言一、启动脚本二、配置账号密码登录2.1.在hadoop1,也就是集群主节点2.2.在master的apiserver启动文件添加一行配置2.3 绑定admin2.4 修改recommended.yaml2.5 重启dashboard2.6 登录dashboard 总结 前言 前面已经搭建好了k8s集群,现在设置下…

保姆级教程 --redis启动命令

1、在redis目录 打开命令 windowr 输入cmd 2、输入 redis-server.exe redis.windows.conf 启动redis命令,看是否成功 3、可能会启动失败,报28 Nov 09:30:50.919 # Creating Server TCP listening socket 127.0.0.1:6379: bind: No error 4、报错后&am…

【AI】《动手学-深度学习-PyTorch版》笔记(二十二):单发多框检测(SSD)

AI学习目录汇总 1、介绍 SSD(Single Shot MultiBox Detector)单发多框检测。“Single shot”说明SSD算法属于one-stage(一段式)方法,“MultiBox”说明SSD是多框预测(多尺度锚框/特征图)。 SSD和YOLO一样都是采用CNN网络执行one-stage(一段式)检测,区别是: YOLO速…

3D异常检测论文笔记 | Shape-Guided Dual-Memory Learning for 3D Anomaly Detection

参考:https://paperswithcode.com/sota/3d-anomaly-detection-and-segmentation-on 论文:https://openreview.net/pdf?idIkSGn9fcPz code:https://github.com/jayliu0313/Shape-Guided 文章目录 摘要一、介绍三、方法3.1. 形状引导专家学习3…

Linux下systemd深入指南:如何优化Java服务管理与开机自启配置

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER(二)

文章目录 TASK系列解析文章OptimizeByNLP1.get_nlp_info()定义问题规模2.get_bounds_info()定义约束边界约束3.get_starting_point()定义初值4.eval_f()求解目标函数5.eval_grad_f()求解梯度6.eval_g()求解约束函数7.eval_jac_g()求解约束雅可比矩阵8.eval_h()求解黑塞矩阵9. f…

碎片笔记 | 大模型攻防简报

前言:与传统的AI攻防(后门攻击、对抗样本、投毒攻击等)不同,如今的大模型攻防涉及以下多个方面的内容: 目录 一、大模型的可信问题1.1 虚假内容生成1.2 隐私泄露 二、大模型的模型安全问题(传统AI攻防&…

交叉编译poco-1.9.2

目录 一、文件下载二、编译三、可能遇到的问题和解决方法3.1 error "Unknown Hardware Architecture."3.2 error Target architecture was not detected as supported by Double-Conversion一、文件下载 下载地址:poco-1.9.2 二、编译 解压目录后打开build/config/…

Mybatis-Genertor逆向工程

1、导入mybaties插件 <build><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.4.2</version><dependencies><dependency>…

亲手实现:全方位解析SpringCloud Alibaba,这份全彩笔记送给你

SpringCloud Aliababa简介 大家好&#xff0c;这次我们来分享一个实用的开源项目—SpringCloud Alibaba。 SpringCloud是国内外微服务开发的首选框架&#xff0c;而SpringCloud Alibaba则是阿里巴巴为微服务架构而开发的组件&#xff0c;它支持SpringCloud原生组件&#xff0…

并联电容器交流耐压试验方法

对被试并联电容器两极进行充分放电。 检查电容器外观、 污秽等情况, 判断电容器是否满足试验要求状态。 用端接线将并联电容器两极短接连接湖北众拓高试工频耐压装置高压端, 外壳接地。 接线完成后经检查确认无误, 人员退出试验范围。 接入符合测试设备的工作电源&#xff0c;…

PHP8中获取并删除数组中第一个元素-PHP8知识详解

我在上一节关于数组的教程&#xff0c;讲的是在php8中获取并删除数组中最后一个元素&#xff0c;今天分享的是相反的&#xff1a;PHP8中获取并删除数组中第一个元素。 回顾一下昨天的知识&#xff0c;array_pop()函数将返回数组的最后一个元素&#xff0c;今天学习的是使用arr…

STM32--蓝牙

本文主要介绍基于STM32F103C8T6和蓝牙模块实现的交互控制 简介 蓝牙&#xff08;Bluetooth&#xff09;是一种用于无线通信的技术标准&#xff0c;允许设备在短距离内进行数据交换和通信。它是由爱立信&#xff08;Ericsson&#xff09;公司在1994年推出的&#xff0c;以取代…