CocosCreator物理引擎Demo源码分析(3)-stick-arrow

2024-09-04 09:58

本文主要是介绍CocosCreator物理引擎Demo源码分析(3)-stick-arrow,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

CocosCreator开发笔记(8)-读取和解析JSON数据文件
Box2D C++ 三种作用力效果 ApplyForce、ApplyLinearImpulse、SetLinearVelocity


stick-arrow示例展示了如何动态发射刚体飞往目标点。

技术点
1、触摸屏幕发射刚体,计算起点和目标点的夹角,设置刚体的线性速度。
2、在Update中不断施加一个作用力到刚体尾部,使它能一直往目标点飞去。
3、在碰撞上后,动态计算并设置WeldJoint的属性,使刚体和碰撞体按一定角度连接起来,不致于自然掉落。

源码分析
arrow.js
arrow.js代码功能是处理碰撞之后的逻辑,主要是动态计算和设置WeldJoint关节的属性。

cc.Class({
extends: cc.Component,

properties: {},// LIFE-CYCLE CALLBACKS:onLoad () {this.weldJoint = this.getComponent(cc.WeldJoint);
},// 每次处理完碰撞体接触逻辑时被调用
onPostSolve: function(contact, selfCollider, otherCollider) {// 获取冲量信息 注意:这个信息只有在 onPostSolve 回调中才能获取到var impulse = contact.getImpulse();// normalImpulses: 法线方向的冲量// PTM_RATIO: 物理单位与像素单位互相转换的比率,一般是 32。if (Math.abs(impulse.normalImpulses[0]) < cc.PhysicsManager.PTM_RATIO) return;let joint = this.weldJoint;if (joint.enabled) {joint.enabled = false;return;}if (otherCollider.node.name === 'arrow') {return;}let arrowBody = selfCollider.body;let targetBody = otherCollider.body;// 将 arrowBody 本地坐标系下的点转换为世界坐标系下的点let worldCoordsAnchorPoint = arrowBody.getWorldPoint(cc.v2(0.6, 0));joint.connectedBody = targetBody;// 将给定的世界坐标系下的点转换为 arrowBody 本地坐标系下的点joint.anchor = arrowBody.getLocalPoint(worldCoordsAnchorPoint);// 将给定的世界坐标系下的点转换为 targetBody 本地坐标系下的点joint.connectedAnchor = targetBody.getLocalPoint(worldCoordsAnchorPoint);joint.referenceAngle = targetBody.node.rotation - arrowBody.node.rotation;joint.enabled = true;
},

});

shoot-arrow.js
shoot-arrow.js代码功能是发射刚体,并在刚体飞行过程中不断计算和施加作用力。

cc.Class({
extends: cc.Component,

properties: {arrow: {type: cc.Node,default: null}
},onEnabled: function() {this.debugDrawFlags = cc.director.getPhysicsManager().debugDrawFlags;cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_jointBit |cc.PhysicsManager.DrawBits.e_shapeBit;
},onDisable: function() {cc.director.getPhysicsManager().debugDrawFlags = this.debugDrawFlags;
},// LIFE-CYCLE CALLBACKS:onLoad () {this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchBegan, this);this.arrowBodies = [];
},onTouchBegan: function(event) {let touchLoc = event.touch.getLocation();let node = cc.instantiate(this.arrow);node.active = true;let vec = cc.v2(touchLoc).sub(node.position);// 通过反正切函数得到触摸点和arrow出生点之间的夹角角度// 乘以 180/3.14159 是为了把弧度转化为角度node.rotation = -Math.atan2(vec.y, vec.x) * 180 / Math.PI;cc.director.getScene().addChild(node);// 返回向量的长度let distance = vec.mag();// 返回归一化后的向量,再乘以800let velocity = vec.normalize().mulSelf(800);// 设置刚体的线性速度let arrowBody = node.getComponent(cc.RigidBody);arrowBody.linearVelocity = velocity;this.arrowBodies.push(arrowBody);
},update: function (dt) {let dragConstant = 0.1;let arrowBodies = this.arrowBodies;for (let i = 0; i < arrowBodies.length; i++) {let arrowBody = arrowBodies[i];let velocity = arrowBody.linearVelocity;let speed = velocity.mag();if (speed === 0) {continue;}let direction = velocity.normalize();// 将世界坐标系下的(1,0)向量转换为刚体本地坐标系下的向量let pointingDirection = arrowBody.getWorldVector(cc.v2(1, 0));let flightDirection = arrowBody.linearVelocity;let flightSpeed = flightDirection.mag();// 向量归一化,让这个向量的长度为 1flightDirection.normalizeSelf();// 向量之间进行点乘let dot = cc.pDot(flightDirection, pointingDirection);let dragForceMagnitude = (1 - Math.abs(dot)) * flightSpeed * flightSpeed * dragConstant * arrowBody.getMass();// 得到arrowBody尾部的世界坐标let arrowTailPosition = arrowBody.getWorldPoint(cc.v2(-80, 0));// 施加一个力到arrowBody刚体的尾部(世界坐标系)arrowBody.applyForce(flightDirection.mul(-dragForceMagnitude), arrowTailPosition, false);}
},

});

这篇关于CocosCreator物理引擎Demo源码分析(3)-stick-arrow的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1135704

相关文章

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

python-nmap实现python利用nmap进行扫描分析

《python-nmap实现python利用nmap进行扫描分析》Nmap是一个非常用的网络/端口扫描工具,如果想将nmap集成进你的工具里,可以使用python-nmap这个python库,它提供了... 目录前言python-nmap的基本使用PortScanner扫描PortScannerAsync异