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

相关文章

IDEA下"File is read-only"可能原因分析及"找不到或无法加载主类"的问题

《IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题》:本文主要介绍IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题,具有很好的参... 目录1.File is read-only”可能原因2.“找不到或无法加载主类”问题的解决总结1.File

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

Dubbo之SPI机制的实现原理和优势分析

《Dubbo之SPI机制的实现原理和优势分析》:本文主要介绍Dubbo之SPI机制的实现原理和优势,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Dubbo中SPI机制的实现原理和优势JDK 中的 SPI 机制解析Dubbo 中的 SPI 机制解析总结Dubbo中

C#继承之里氏替换原则分析

《C#继承之里氏替换原则分析》:本文主要介绍C#继承之里氏替换原则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#里氏替换原则一.概念二.语法表现三.类型检查与转换总结C#里氏替换原则一.概念里氏替换原则是面向对象设计的基本原则之一:核心思想:所有引py

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

PostgreSQL 序列(Sequence) 与 Oracle 序列对比差异分析

《PostgreSQL序列(Sequence)与Oracle序列对比差异分析》PostgreSQL和Oracle都提供了序列(Sequence)功能,但在实现细节和使用方式上存在一些重要差异,... 目录PostgreSQL 序列(Sequence) 与 oracle 序列对比一 基本语法对比1.1 创建序

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见