【基于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.rhkb.cn/news/134039.html

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

相关文章

Python __slots__:限制类实例动态添加属性和方法

​通过学习《Python类变量和实例变量》一节,了解了如何动态的为单个实例对象添加属性,甚至如果必要的话,还可以为所有的类实例对象统一添加属性(通过给类添加属性)。​ ​ 那么,Python 是 ​否也允许动态地…

MySQL 约束与复杂查询

当涉及到数据库管理系统(DBMS)的高级主题时,包括数据库的约束、表的设计以及各种类型的查询,特别是聚合查询、联合查询和合并查询,是非常重要的。这些主题可以帮助我们更好地理解数据库的内部工作机制以及如何有效地操…

二叉搜索树经典笔试题【力扣、牛客】

文章目录 1.根据二叉树创建字符串2. 二叉树的层序遍历3.二叉树的层序遍历Ⅱ4.二叉树的最近公共祖先1.法一:定位p、q在左还是右 分类讨论2.法二:利用stack求出p、q路径 求相交值 5.二叉搜索树与双向链表1.法一:递归:递归过程修正指…

Acwing 828. 模拟栈

Acwing 828. 模拟栈 题目要求思路讲解代码展示 题目要求 思路讲解 栈&#xff1a;先进后出 队列&#xff1a;先进先出 代码展示 #include <iostream>using namespace std;const int N 100010;int m; int stk[N], tt;int main() {cin >> m;while (m -- ){string o…

java创建excel文件和解析excel文件

创建excel文件 package com.bjpowernode.crm.poi;import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.HorizontalAlignment;import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.…

leetcode刷题(简单篇):9.回文数

9.回文数 题目描述&#xff1a;给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&…

mybatis mapper.xml转建表语句

从网上下载了代码&#xff0c;但是发现没有DDL建表语句&#xff0c;只能自己手动创建了&#xff0c;感觉太麻烦&#xff0c;就写了一个工具类 将所有的mapper.xml放入到一个文件夹中&#xff0c;程序会自动读取生成建表语句 依赖的jar <dependency><groupId>org.d…

关于Python数据分析,这里有一条高效的学习路径

无处不在的数据分析 谷歌的数据分析可以预测一个地区即将爆发的流感&#xff0c;从而进行针对性的预防&#xff1b;淘宝可以根据你浏览和消费的数据进行分析&#xff0c;为你精准推荐商品&#xff1b;口碑极好的网易云音乐&#xff0c;通过其相似性算法&#xff0c;为不同的人…

Python中Mock和Patch的区别

前言&#xff1a; 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 在测试并行开发&#xff08;TPD&#xff09;中&#xff0c;代码开发是第一位的。 尽管如此&#xff0c;我们还是要写出开发的测试&#xff0c…

教育领域数据可视化:点亮知识之路

教育领域一直以来都在不断进步和演变&#xff0c;而数据可视化技术正在为这一领域带来一场革命。在过去的几年里&#xff0c;教育者们越来越意识到&#xff0c;通过将教育数据转化为可视化图表和图形&#xff0c;可以更好地理解学生的表现、需求和趋势&#xff0c;从而提供更好…

科学计算器网站Desmos网站

科学计算器网站Desmos网站 有时在学习工作或者生活中&#xff0c;需要用到计算问题&#xff0c;但由于电脑上没有安装相应的专业软件&#xff0c;难以计算有的问题&#xff0c;因而&#xff0c;本文推荐一种免费的在线计算网站Desmos。 一、Desmos网址 Desmos官网的地址为&a…

doccano 文本标注工具使用

最近在做面向大模型的文本标注工作&#xff0c;涉及到多人协同的问题&#xff0c;因此用到了doccano工具。 这个工具可以使用docker进行安装&#xff0c;安装之后的启动也都比较简单。 关于基础使用&#xff08;例如管理员登录、新建任务、上传数据集等&#xff09;&#xff…

系统架构设计师(第二版)学习笔记----信息系统基础

【原文链接】系统架构设计师&#xff08;第二版&#xff09;学习笔记----信息系统基础 文章目录 一、信息系统概述1.1 信息系统的5个基本功能1.2 信息系统发展阶段1.3 初始阶段的主要特点1.4 传播阶段的主要特点1.5 控制阶段的主要特点1.6 集成阶段的主要特点1.7 信息系统的种类…

计算机是如何工作的(上篇)

计算机发展史 世界上很多的高科技发明,来自于军事领域 计算机最初是用来计算弹道导弹轨迹的 弹道导弹 ~~国之重器,非常重要 两弹一星 原子弹,氢弹,卫星(背后的火箭发射技术) 计算弹道导弹轨迹的计算过程非常复杂,计算量也很大 ~~ 但是可以手动计算出来的(当年我国研究两弹一…

MySQL架构介绍与说明

1、MySQL架构介绍 和其它数据库相比&#xff0c;MySQL有点与众不同&#xff0c;它的架构可以在多种不同场景中应用并发挥良好作用。主要体现在存储引擎的架构上&#xff0c; 插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离。这种架构可以根据业务的…

【数据结构】C++实现二叉搜索树

二叉搜索树的概念 二叉搜索树又称为二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有结点的值都小于根结点的值。若它的右子树不为空&#xff0c;则右子树上所有结点的值都大于根结…

Spring Boot 动态加载jar文件

Spring Boot 动态加载jar文件 接口实现&#xff1a; package org.bc.device;public interface IDeviceHandler {String start();String stop(); }实现类&#xff1a; package org.bc.device; public class MqttDevice implements IDeviceHandler{ Override public String s…

Linux——Shell脚本编程(2)

一、Shell变量 Linux Shell 中的变量分为&#xff0c;系统变量 和 用户自定义变量 (这个用的比较多)。 系统变量 : $HOME、$PWD、$SHELL、$USER 等等&#xff0c;比如 : echo $HOME 等等.. 显示当前shell中所有变量 : set 举例说明&#xff1a; 二、设置环境变量 记得在注释…

小丑未能阻止抢购iPhone15,预约人数快500万了,而且越贵越买

iPhone15发布后&#xff0c;在昨天开启预约&#xff0c;从某电商平台可以看到预约人数已近300万&#xff0c;加上其他平台&#xff0c;估计预约人数已快500万了&#xff0c;显示出消费者仍然是嘴上说不爱&#xff0c;行动上却是迅速抢购&#xff0c;苹果的真香定律让竞争对手很…

服务器数据恢复-热备盘同步过程中硬盘离线的RAID5数据恢复案例

服务器数据恢复环境&#xff1a; 华为OceanStor某型号存储&#xff0c;11块硬盘组建了一组RAID5阵列&#xff0c;另外1块硬盘作为热备盘使用。基于RAID5阵列的LUN分配给linux系统使用&#xff0c;存放Oracle数据库。 服务器故障&#xff1a; RAID5阵列1块硬盘由于未知原因离线…