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

Cocos解耦移动和发射模块

目标玩家受到摇杆A控制移动和方向发射受到摇杆B负责方向和发射//玩家模块ccclass(Player) export class Player extends Component { //玩家速度 Speed:number 500; //玩家方向 property(Vec3) PlayerDir:Vec3; //虚拟摇杆 property(Node) Joystick:Node null; start() { } update(deltaTime: number) { //更新位置 this.PlayerDir this.Joystick.getComponent(Joystick).dir.normalize(); let newPos this.node.position.clone().add(this.PlayerDir.clone().multiplyScalar(this.Speed*deltaTime)); this.node.setPosition(newPos); //视角跟随移动方向 this.node.angle this.Joystick.getComponent(Joystick).calculateAngle() - 90; } }//发射模块import { _decorator, Component, instantiate, Node, Prefab, Vec3 } from cc; import { Joystick } from ../UI/Joystick; import { Bullet } from ../Game/Bullet; const { ccclass, property } _decorator; ccclass(Shell) export class Shell extends Component { // 第二个摇杆射击方向 property(Node) fireJoystick: Node null; // 发射点 property(Node) launchPoint: Node null; // 关联玩家节点用来跟着走 property(Node) player: Node null; // 输出给子弹的方向 public fireDir: Vec3 new Vec3(); // 子弹相关 //子弹预制体 property(Prefab) BulletPrefab: Prefab null; property(Node) LaunchPoint: Node null; //发射频率 property LaunchCD: number 0.2; //计时器 private LaunchTimer: number 0; //子弹存储 property(Node) BulletStorage:Node null; update(deltaTime: number) { // // 核心外壳 跟随玩家位置旋转跟随第二个摇杆 if (this.player) { this.node.setWorldPosition(this.player.worldPosition); } if (!this.fireJoystick) return; const dir this.fireJoystick.getComponent(Joystick).dir; if (dir.length() 0.1) return; // 外壳朝向射击方向 this.fireDir dir.normalize(); //外壳方向摇杆方向 const angle Math.atan2(dir.y, dir.x) * 180 / Math.PI - 90; this.node.angle angle; // this.LaunchTimer deltaTime; if(this.LaunchTimer this.LaunchCD){ //发射 this.Launch(); //重置计时器 this.LaunchTimer 0; } } Launch(){ //前置检查--预制体和父节点是否正常 if (!this.BulletPrefab || !this.LaunchPoint) { console.warn(请配置子弹预制体和发射点); return; } //实例化子弹,挂载父节点 const bullet instantiate(this.BulletPrefab); //设置父节点 bullet.parent this.BulletStorage; //设置子弹的世界位置 发射点位置 bullet.setWorldPosition(this.LaunchPoint.worldPosition); // 关键给子弹设置飞行方向 // const bulletComp bullet.getComponent(Bullet); if (bulletComp) { bulletComp.setDirection(this.fireDir); } } }//子弹模块import { _decorator, Component, Node, Vec3, instantiate, Prefab, Quat, CCObject, Game } from cc; import { Joystick } from ../UI/Joystick; import { GameManager } from ./GameManager; const { ccclass, property } _decorator; ccclass(Bullet) export class Bullet extends Component { // 子弹飞行方向 public BulletDir: Vec3 new Vec3(1,1,0); // 子弹速度 speed: number 300; // 子弹生命周期 lifeTime: number 5; // 已存活时间 private _aliveTime: number 0; //游戏管理器 property(Node) GameManagerNode:Nodenull; update(deltaTime: number) { // 累加存活时间--正常 this._aliveTime deltaTime; // 超过生命周期则销毁--正常 if (this._aliveTime this.lifeTime) { this.node.destroy(); return; } // 计算子弹移动--正常 const moveStep this.BulletDir.clone().multiplyScalar(this.speed * deltaTime); const newPos this.node.position.clone().add(moveStep); this.node.setPosition(newPos); // 朝方向移动 this.node.translate(this.BulletDir.clone().multiplyScalar(this.speed * deltaTime)); } // 设置飞行方向由外壳调用 setDirection(direction: Vec3) { this.BulletDir.set(direction); } }//摇杆import { v3, Vec3 } from cc; import { v2 } from cc; import { EventTouch } from cc; import { _decorator, Component, Node, NodeEventType, UITransform, Vec2 } from cc; const { ccclass, property } _decorator; ccclass(Joystick) export class Joystick extends Component { public static ins: Joystick null; property({ type: Node, displayName: 摇杆bg }) node_dotBg: Node null; property({ type: Node, displayName: 摇杆中间点 }) node_dot: Node null; /** node_dotBg的UITransform组件*/ UITf_dot: UITransform null; /** 摇杆移动的最大半径 */ maxLength: number 0; /** 方向 */ private _dir: Vec3 new Vec3(0, 0); public get dir(): Vec3 { return this._dir; } public set dir(value: Vec3) { this._dir value; } /** 角度 */ roleAngle: number 0; onLoad() { if (Joystick.ins null) { Joystick.ins this; } this.init(); } init() { this.UITf_dot this.node_dotBg.getComponent(UITransform); this.maxLength this.node_dotBg.getComponent(UITransform).width / 2; this.node_dotBg.on(NodeEventType.TOUCH_START, this.onTouchMove, this); this.node_dotBg.on(NodeEventType.TOUCH_MOVE, this.onTouchMove, this); this.node_dotBg.on(NodeEventType.TOUCH_END, this.onTouchEnd, this); this.node_dotBg.on(NodeEventType.TOUCH_CANCEL, this.onTouchEnd, this); } /** 触摸移动 */ private onTouchMove(event: EventTouch) { // 获取世界坐标 let worldPos event.getUILocation(); // 摇杆点是dotBg的子节点所以要转换成dotBg的局部坐标 let localPos this.UITf_dot.convertToNodeSpaceAR(v3(worldPos.x, worldPos.y, 0)); let length localPos.length(); if (length 0) { // 只计算方向 this.dir.x localPos.x / length; this.dir.y localPos.y / length; // 计算最外一圈的x,y位置 if (length this.maxLength) { localPos.x this.maxLength * this.dir.x; localPos.y this.maxLength * this.dir.y; } this.node_dot.setPosition(localPos); } } /** 触摸结束 */ private onTouchEnd(event: NodeEventType) { this.dir v3(0, 0,0); this.node_dot.setPosition(0, 0, 0); } /** 求角度 */ public calculateAngle() { if (this.dir.x 0 this.dir.y 0) return this.roleAngle; // 计算单位向量相对于正右方向的角度以弧度表示 let angleRad Math.atan2(this.dir.y, this.dir.x); // 将弧度转换为角度以度数表示 this.roleAngle angleRad * 180 / Math.PI; return this.roleAngle; } }

相关文章:

Cocos解耦移动和发射模块

目标:玩家受到摇杆A控制移动和方向,发射受到摇杆B负责方向和发射 //玩家模块 ccclass(Player) export class Player extends Component {//玩家速度Speed:number 500;//玩家方向property(Vec3)PlayerDir:Vec3;//虚拟摇杆property(Node)Joystick:Node n…...

告别串口线!手把手教你用WCH-LinkE的SDI功能实现CH32V303RCT6的无线调试打印

无线调试革命:基于WCH-LinkE的SDI功能实现CH32V303RCT6高效打印 调试嵌入式系统时,串口打印是最常用的调试手段之一。然而传统串口调试需要占用宝贵的硬件UART资源,在IO口紧张或串口已被占用的场景下尤为不便。沁恒微电子推出的SDI(Serial Da…...

探索二维非常规态型近场动力学代码

非常规态型近场动力学代码 纬度:二维; 时间积分:自适应动态松弛 or verlet-velocity; 零能抑制模式:silling method or Li pan method; 语言:MATLAB 代码注释详细,可适当在数值模拟领域,近场动力…...

DeepSeek-OCR 2技术突破:动态视觉token重排效果展示

DeepSeek-OCR 2技术突破:动态视觉token重排效果展示 1. 引言 想象一下,当你阅读一份复杂的学术论文时,眼睛不会机械地从左上角扫到右下角,而是会自然地跳过标题、关注图表、追踪公式推导,甚至在不同的文本栏之间灵活…...

# 数据仓库分层设计指南

从 0 搭建企业级数仓架构,ODS/DWD/DWS/ADS 分层详解📌 前言 为什么你的 SQL 越来越难维护? 为什么每次加需求都要改一堆表? 为什么数据口径对不上? 根本原因:没有分层设计! 这篇文章带你从零设计…...

【MySQL | 第一篇】 深入理解三大日志(undo Redo Bin)

目录 Undo Log日志 Redo Log日志 Redo Log与Bin Log的区别 Bin Log日志 三大日志全流程 Undo Log日志 一、核心定义 Undo Log 是MySQL InnoDB存储引擎特有的事务回滚日志,核心作用是记录事务执行前的数据版本,用于事务回滚、MVCC实现,是…...

浪潮服务器硬盘红灯报警?手把手教你更换RAID阵列故障盘(附同步失败解决方案)

浪潮服务器硬盘红灯报警全流程处置指南:从故障诊断到阵列重建 当浪潮服务器的硬盘指示灯突然亮起刺眼的红色,大多数运维人员的第一反应往往是心头一紧。这种视觉警报不仅意味着硬件故障,更可能预示着数据丢失的风险。不同于普通PC的硬盘故障…...

Comsol热流耦合拓扑优化:最大化放热量与功率耗散的探索

Comsol热流耦合拓扑优化。 目标函数采用最大化放热量和功率耗散。在工程领域,热流耦合问题一直是研究的重点,尤其是如何通过拓扑优化来实现特定目标,比如最大化放热量和功率耗散,这对于提高系统性能至关重要。而Comsol作为一款强大…...

macOS Sequoia 15.7.5 (24G624) 正式版 ISO、IPSW、PKG 下载

macOS Sequoia 15.7.5 (24G624) 正式版 ISO、IPSW、PKG 下载 iPhone 镜像、Safari 浏览器重大更新和 Apple Intelligence 等众多全新功能令 Mac 使用体验再升级 请访问原文链接:https://sysin.org/blog/macOS-Sequoia/ 查看最新版。原创作品,转载请保留…...

机票价格智能监控:如何用Flight Spy锁定最佳购票时机

机票价格智能监控:如何用Flight Spy锁定最佳购票时机 【免费下载链接】flight-spy Looking for the cheapest flights and dont have enough time to track all the prices? 项目地址: https://gitcode.com/gh_mirrors/fl/flight-spy 你是否曾在预订机票时陷…...

OpenClaw 小龙虾Windows10 专属一键部署教程|10 分钟搞定本地 AI 数字员工

适配系统:Windows10 64 位(纯小白友好版) 核心优势:免命令行、免环境配置、解压即装,内置所有运行依赖,全程可视化操作,新手也能一次成功部署 2026 爆火的开源 AI 智能体! 本文专属…...

从零开始:SpaCy安装与模型下载的完整流程(含版本查询技巧)

从零开始:SpaCy安装与模型下载的完整流程(含版本查询技巧) 自然语言处理(NLP)正在改变我们与计算机交互的方式,而SpaCy作为这一领域的明星工具库,以其高效性和易用性赢得了众多开发者的青睐。无…...

LuckyLilliaBot:NTQQ的终极OneBot协议插件完整指南

LuckyLilliaBot:NTQQ的终极OneBot协议插件完整指南 【免费下载链接】LuckyLilliaBot NTQQ的OneBot API插件 项目地址: https://gitcode.com/gh_mirrors/li/LuckyLilliaBot LuckyLilliaBot是一个基于TypeScript开发的NTQQ插件,为QQ客户端提供完整的…...

智能排错助手:让快马AI分析你的openclaw安装错误并生成解决方案

最近在折腾openclaw这个工具时,遇到了不少安装报错的问题。作为一个经常在各类开发环境中摸爬滚打的程序员,我发现这类开源工具的安装过程往往隐藏着不少坑。不过这次尝试用AI辅助诊断后,整个排错效率提升了不少,这里记录下我的实…...

最近帮实验室刚入门的师弟复现了西储大学轴承故障的迁移学习代码,本来以为是手到擒来的活,结果还是踩了好几个坑,刚好整理出来给同样摸鱼入门的小伙伴参考

一区top轴承故障诊断迁移学习代码复现 故障诊断代码 复现首先使用一维的cnn对源域和目标域进行特征提取,域适应阶段:将源域和目标域作为cnn的输入得到特征,然后进行边缘概率分布对齐和条件概率分布对齐,也就是进行JDA联合对齐。此…...

塔罗牌选框架:准确率超机器学习模型

技术选型困境与创新突破在软件测试领域,技术栈选择一直是核心挑战。传统方法依赖历史数据和机器学习模型,但常陷入“预测陷阱”——过度依赖过往经验导致创新盲区。例如,自动化测试框架的错误选型每年造成巨额损失:38.7%源于技术生…...

2026 年智慧工地排名榜单第一|山东建安物联科技有限公司

2026 年度智慧工地综合实力榜单正式揭晓,山东建安物联科技有限公司(大建安)凭借标准引领、技术实力与标杆项目,登顶全国榜首,成为行业公认的智慧工地领军企业。公司打造的中建八局烟台崆峒胜境项目,获评国家…...

如何快速上手TradingView图表库:15+框架完整集成实战指南

如何快速上手TradingView图表库:15框架完整集成实战指南 【免费下载链接】charting-library-examples Examples of Charting Library integrations with other libraries, frameworks and data transports 项目地址: https://gitcode.com/gh_mirrors/ch/charting-…...

Excel 技巧:一键批量填充空值

🚀 操作步骤选中区域首先,用鼠标选中包含空值的目标数据区域。定位空值按下快捷键 Ctrl G 打开“定位”对话框:点击左下角的 「定位条件...」。选择 「空值」。点击「确定」。✅ 此时,区域内所有空白单元格已被高亮选中。输入公式…...

NaViL-9B效果展示:电商主图自动提取卖点文案+竞品对比分析

NaViL-9B效果展示:电商主图自动提取卖点文案竞品对比分析 1. 多模态大模型惊艳登场 想象一下,当你上传一张商品图片,AI不仅能准确识别图片内容,还能自动生成吸引人的卖点文案——这就是NaViL-9B带来的革命性体验。作为原生多模态…...

Python 3.13 + CUDA 13.0编译轮子

核心工具链安装 1、安装 Visual Studio 2022 (勾选 “使用 C 的桌面开发”) 2、安装 CUDA Toolkit 13.0环境变量注入 在终端执行,确保编译器能精准定位 CUDA 路径:set CUDA_PATHD:\Program Files\NVIDIA_GPU_Computing_Toolkit\v13 set PATH%CUDA_PATH%\…...

League Akari:英雄联盟玩家的终极智能辅助工具实战指南

League Akari:英雄联盟玩家的终极智能辅助工具实战指南 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否厌倦了在…...

AI赋能安装流程:快马智能诊断工具,自动解决软件安装兼容性问题

在开发软件的过程中,安装环节往往是第一个拦路虎。特别是当遇到系统环境复杂、依赖库版本冲突、权限配置等问题时,传统的安装方式常常让人头疼不已。最近我在尝试开发一个智能安装问题诊断工具时,发现InsCode(快马)平台的AI辅助功能特别实用&…...

南京四季旅游攻略:最美时节去最美地方

南京四季旅游攻略:最美时节去最美地方 🌸🍃🍂❄️本文作者:南京码农 发布日期:2026年3月26日 关键词:南京旅游、四季景点、旅游攻略、南京必去、季节推荐前言:南京,一座四…...

ESP32 SPI性能调优指南:从80MHz时钟到DMA配置,避开那些坑

ESP32 SPI性能调优实战:突破80MHz时钟与DMA配置的终极指南 当你在ESP32项目中遇到SPI通信速度瓶颈时,是否曾为如何突破80MHz时钟限制而苦恼?是否在配置DMA时踩过各种坑?本文将带你深入ESP32 SPI性能优化的核心领域,从硬…...

AI+医疗从模型到产品:做一个真正可用系统,需要跨过哪些坎?

# AI医疗从模型到产品:做一个真正可用系统,需要跨过哪些坎?做 AI医疗的人,常常会经历一个很像的阶段。前期我们把大部分精力放在模型上:换 backbone、调 loss、做多模态融合、补校准、压错误样本,最后终于把…...

如何用dpkg-architecture解决Debian软件包的多架构依赖问题?

深度解析dpkg-architecture:Debian多架构依赖管理的实战指南 在Debian软件包开发领域,多架构支持一直是开发者面临的复杂挑战之一。随着ARM架构的崛起和异构计算场景的普及,单一架构的软件包已经无法满足现代计算需求。本文将带您深入探索dpk…...

从零部署JetLinks社区版:一站式物联网平台本地化搭建实战

1. JetLinks社区版:物联网开发的瑞士军刀 第一次接触JetLinks社区版是在三年前的一个智能家居项目上。当时客户要求两周内搭建一个能管理5000设备的物联网平台,还要支持自定义协议开发。在对比了多个开源方案后,JetLinks的模块化设计让我眼前…...

解锁Navicat密码:突破加密限制的开源解密工具

解锁Navicat密码:突破加密限制的开源解密工具 【免费下载链接】navicat_password_decrypt 忘记navicat密码时,此工具可以帮您查看密码 项目地址: https://gitcode.com/gh_mirrors/na/navicat_password_decrypt 当数据库连接密码被Navicat加密保存却无法记起&…...

模电小白必看:3种基本放大电路实战对比(附电路图+避坑指南)

模电入门实战:三大基础放大电路深度解析与避坑指南 刚接触模拟电路时,面对共射极、共集极和共基极这三种基本放大电路,很多初学者都会感到困惑——它们看起来相似,但特性却大不相同。本文将用面包板搭建的真实电路和示波器实测波形…...