1.物理系统

1.1 2D刚体

刚体是组成物理世界的基本对象。

1.2 2D 碰撞组件

目前引擎支持三种不同的碰撞组件: 盒碰撞组件(BoxCollider2D)圆形碰撞组件(CircleCollider2D) 和 多边形碰撞组件(PolygonCollider2D)。在 属性检查器 上点击 添加组件 按钮,输入碰撞组件的名称即可添加。

在 属性检查器 上点击 添加组件,输入 PolygonCollider2D 可添加多边形碰撞组件。

1.3 3D 物理

物理系统是将游戏世界赋予现实世界的物理属性(重力、推力等),并抽象为刚体模型,使得游戏物体在力的作用下,仿真现实世界的运动及其之间的碰撞过程。即在牛顿经典力学模型基础之上,通过 API 计算游戏物体的运动、旋转和碰撞

Cocos Creator 支持以下几种物理引擎:

  • ammo.js:默认物理引擎,Bullet 物理引擎 的 asm.js/wasm 版本。具备碰撞检测和物理模拟的物理引擎。
  • builtin:内置物理引擎,仅用于碰撞检测的轻量引擎。
  • cannon.js:具有碰撞检测和物理模拟的物理引擎。
  • PhysX: 由 NVIDIA 公司开发的游戏物理引擎。具备碰撞检测和物理模拟的物理引擎。

开发者根据开发对物理特性需求或应用场景选择不同的物理引擎,详情请参考:设置物理引擎。

1.碰撞组件

碰撞组件可用于定义需要进行物理碰撞的物体形状,不同的几何形状拥有不同的属性。碰撞体通常分为以下几种:

  1. 基础碰撞体。常见的包含 盒、球、圆柱、圆锥、胶囊 碰撞体。
  2. 复合碰撞体。可以通过在一个节点身上添加一个或多个基础碰撞体,简易模拟游戏对象形状,同时保持较低的性能开销。
  3. 网格碰撞体。根据物体网格信息生成碰撞体,完全的贴合网格。
  4. 单纯形碰撞体。提供点、线、三角面、四面体碰撞。
  5. 平面碰撞体。可以代表无限平面或半空间。这个形状只能用于静态的、非移动的物体。
  6. 地形碰撞体。一种用于凹地形的特殊支持。

2.刚体组件

刚体是组成物理世界的基本对象,它可以使游戏对象的运动方式受物理控制。例如:刚体可以使游戏对象受重力影响做自由下落,也可以在力和扭矩的作用下,让游戏对象模拟真实世界的物理现象。

让刚体运动起来

针对不同的类型,让刚体运动的方式不同:

  • 对于静态刚体(STATIC),应当尽可能保持物体静止,但仍然可以通过变换(位置、旋转等)来改变物体的位置。
  • 对于运动学刚体(KINEMATIC),应当通过改变变换(位置、旋转等)使其运动。

对于动力学(DYNAMIC)刚体,需要改变其速度,有以下几种方式:

通过重力

刚体组件提供了 UseGravity 属性,需要使用重力时候,需将 UseGravity 属性设置为 true

通过施加力

刚体组件提供了 applyForce 接口,根据牛顿第二定律,可对刚体某点上施加力来改变物体的原有状态。

import { math } from 'cc'rigidBody.applyForce(new math.Vec3(200, 0, 0));

通过扭矩

力与冲量也可以只对旋转轴产生影响,使刚体发生转动,这样的力叫做扭矩。

刚体组件提供了 applyTorque 接口,通过此接口可以施加扭矩到刚体上,因为只影响旋转,所以不需要指定作用点。

rigidBody.applyTorque(new math.Vec3(200, 0, 0));

通过施加冲量

刚体组件提供了 applyImpulse 接口,施加冲量到刚体上的一个点,根据动量守恒,将立即改变刚体的线性速度。 如果冲量施加到的点不是刚体的质心,那么将产生一个扭矩并影响刚体的角速度。

rigidBody.applyImpulse(new math.Vec3(5, 0, 0));

通过改变速度

刚体组件提供了 setLinearVelocity 接口,可用于改变线性速度。

rigidBody.setLinearVelocity(new math.Vec3(5, 0, 0));

刚体组件提供了 setAngularVelocity 接口,可用于改变旋转速度。

rigidBody.setAngularVelocity(new math.Vec3(5, 0, 0));

3.恒力组件

恒力组件是一个工具组件,依赖于刚体组件,每帧都会对一个刚体施加给定的力和扭矩。

4.约束

在物理引擎中,约束 用于模拟物体间的连接情况,如连杆、绳子、弹簧或者布娃娃等。

约束依赖 刚体组件,若节点无刚体组件,则添加约束时,引擎会自动添加刚体组件。

1.4 物理材质

物理材质是一种资源,它记录了物体的物理属性,这些信息用来计算碰撞物体受到的摩擦力和弹力等。

1.5 物理事件

触发器与碰撞器

碰撞组件属性 IsTrigger 决定了组件为触发器还是碰撞器。将 IsTrigger 设置为 true 时,组件为触发器。触发器只用于碰撞检测和触发事件,会被物理引擎忽略。默认设置 false,组件为碰撞器,可以结合刚体产生碰撞效果。

1.6 射线检测

射线检测是对一条射线和另一个形状进行 相交性判断,如下图所示。

1.7 物理应用案例

射击苹果——静态网格、凸包、多步模拟(步长调整)

一般的苹果都带有凹面,处理好凹类或带连续平滑不规则曲面的模型都非常棘手,这是因为目前成熟的理论和技术都建立在离散、凸包的世界之上(微积分中用差分近似表示微分就是最典型的范例)。

运动表现与模拟参数有非常大的关系,穿透是最具有代表性的现象,这可以通过缩减步长和增加步数来实现,调整步长有个小技巧:输入分式,即 1/Frame,其中 Frame 表示帧率。

2.粒子系统

粒子系统是游戏引擎特效表现的基础,它可以用于模拟的火、烟、水、云、雪、落叶等自然现象,也可用于模拟发光轨迹、速度线等抽象视觉效果。

3.缓动系统

缓动系统被广泛的应用于游戏开发中,其主要目的之一是用于解决离线动画无法满足需求时的动态动画的问题。

4.地形系统

地形系统以一种高效的方式来展示大自然的山川地貌。开发者可以很方便的使用画刷来雕刻出盆地、山脉、峡谷、平原等地貌。

5.资源管理

Asset Manager 概述

在游戏的开发过程中,一般需要使用到大量的图片、音频等资源来丰富整个游戏内容,而大量的资源就会带来管理上的困难。所以 Creator 提供了 Asset Manager 资源管理模块来帮助开发者管理其资源的使用,大大提升开发效率和使用体验。

5.1 加载资源

1.动态加载 resources

通常我们会把项目中需要动态加载的资源放在 resources 目录下,配合 resources.load 等接口动态加载。你只要传入相对 resources 的路径即可,并且路径的结尾处 不能 包含文件扩展名。

// 加载 Prefab
resources.load("test_assets/prefab", Prefab, (err, prefab) => {const newNode = instantiate(prefab);this.node.addChild(newNode);
});// 加载 AnimationClip
resources.load("test_assets/anim", AnimationClip, (err, clip) => {sthis.node.getComponent(Animation).addClip(clip, "anim");
});

2.加载 SpriteFrame 或 Texture2D

图片设置为 sprite-frame 或 texture 或其他图片类型后,将会在 资源管理器 中生成一个对应类型的资源。但如果直接加载 test_assets/image,得到的类型将会是 ImageAsset。你必须指定路径到具体的子资源,才能加载到图片生成的 SpriteFrame

// 加载 SpriteFrame,image 是 ImageAsset,spriteFrame 是 image/spriteFrame,texture 是 image/texture
resources.load("test_assets/image/spriteFrame", SpriteFrame, (err, spriteFrame) => {this.node.getComponent(Sprite).spriteFrame = spriteFrame;
});
// 加载 texture
resources.load("test_assets/image/texture", Texture2D, (err: any, texture: Texture2D) => {const spriteFrame = new SpriteFrame();spriteFrame.texture = texture;this.node.getComponent(Sprite).spriteFrame = spriteFrame;
});

3.加载图集中的 SpriteFrame

// 加载 SpriteAtlas(图集),并且获取其中的一个 SpriteFrame
// 注意 atlas 资源文件(plist)通常会和一个同名的图片文件(png)放在一个目录下, 所以需要在第二个参数指定资源类型
resources.load("test_assets/sheep", SpriteAtlas, (err, atlas) => {const frame = atlas.getSpriteFrame('sheep_down_0');sprite.spriteFrame = frame;
});

4.加载 FBX 或 glTF 模型中的资源

在将 FBX 模型或 glTF 模型导入编辑器后,会解析出该模型中包含的相关资源如网格,材质,骨骼,动画等,如下图所示:

// 加载模型中的网格资源
resources.load("Monster/monster", Mesh, (err, mesh) => {this.node.getComponent(MeshRenderer).mesh = mesh;
});// 加载模型中的材质资源
resources.load("Monster/monster-effect", Material, (err, material) => {this.node.getComponent(MeshRenderer).material = material;
});// 加载模型中的骨骼
resources.load("Monster/Armature", Skeleton, (err, skeleton) => {this.node.getComponent(SkinnedMeshRenderer).skeleton = skeleton;
});

5.资源批量加载

resources.loadDir 可以加载相同路径下的多个资源:

// 加载 test_assets 目录下所有资源
resources.loadDir("test_assets", function (err, assets) {// ...
});// 加载 test_assets 目录下所有 SpriteFrame,并且获取它们的路径
resources.loadDir("test_assets", SpriteFrame, function (err, assets) {// ...
});

6.预加载资源

因为预加载没有去解析资源,所以需要在预加载完成后配合加载接口进行资源的解析和初始化,来完成资源加载。

resources.preload('test_assets/image/spriteFrame', SpriteFrame);// wait for while
resources.load('test_assets/image/spriteFrame', SpriteFrame, (err, spriteFrame) => {this.node.getComponent(Sprite).spriteFrame = spriteFrame;
});

7.加载远程资源和设备资源

// 远程 url 带图片后缀名
let remoteUrl = "http://unknown.org/someres.png";
assetManager.loadRemote<ImageAsset>(remoteUrl, function (err, imageAsset) {const spriteFrame = new SpriteFrame();const texture = new Texture2D();texture.image = imageAsset;spriteFrame.texture = texture;// ...
});// 用绝对路径加载设备存储内的资源,比如相册
const absolutePath = "/dara/data/some/path/to/image.png";
assetManager.loadRemote<ImageAsset>(absolutePath, function (err, imageAsset) {const spriteFrame = new SpriteFrame();const texture = new Texture2D();texture.image = imageAsset;spriteFrame.texture = texture;// ...
});// 远程音频
remoteUrl = "http://unknown.org/sound.mp3";
assetManager.loadRemote(remoteUrl, function (err, audioClip) {// play audio clip
});// 远程文本
remoteUrl = "http://unknown.org/skill.txt";
assetManager.loadRemote(remoteUrl, function (err, textAsset) {// use string to do something
});

5.2 资源释放

1.自动释放

场景的自动释放可以直接在编辑器中设置。在 资源管理器 选中场景后,属性检查器 中会出现 自动释放资源 选项。

勾选后,点击右上方的 应用 按钮,之后在切换该场景时便会自动释放该场景所有的依赖资源。建议场景尽量都勾选自动释放选项,以确保内存占用较低,除了部分高频使用的场景(例如主场景)。

另外,所有 Asset 实例都拥有成员函数 Asset.addRef 和 Asset.decRef,分别用于增加和减少引用计数。一旦引用计数为零,Creator 会对资源进行自动释放(需要先通过释放检查,具体可参考下部分内容的介绍)

start () {resources.load('images/background', Texture2D, (err, texture) => {this.texture = texture;// 当需要使用资源时,增加其引用texture.addRef();// ...});
}onDestroy () {// 当不需要使用资源时,减少引用// Creator 会在调用 decRef 后尝试对其进行自动释放this.texture.decRef();
}

自动释放的优势在于不用显式地调用释放接口,开发者只需要维护好资源的引用计数,Creator 会根据引用计数自动进行释放。这大大降低了错误释放资源的可能性,并且开发者不需要了解资源之间复杂的引用关系。对于没有特殊需求的项目,建议尽量使用自动释放的方式来释放资源。

2.手动释放

当项目中使用了更复杂的资源释放机制时,可以调用 Asset Manager 的相关接口来手动释放资源。例如:

assetManager.releaseAsset(texture);

3.资源的动态引用

当开发者在编辑器中没有对资源做任何设置,而是通过代码动态加载资源并设置到场景的组件上,则资源的引用关系不会记录在序列化数据中,引擎无法统计到这部分的引用关系,这些引用关系就是动态引用。

如果开发者在项目中使用动态加载资源来进行动态引用,例如:

resources.load('images/background/spriteFrame', SpriteFrame, function (err, spriteFrame) {self.getComponent(Sprite).spriteFrame = spriteFrame;
});

此时会将 SpriteFrame 资源设置到 Sprite 组件上,引擎不会做特殊处理,SpriteFrame 的引用计数仍保持 0。如果动态加载出来的资源需要长期引用、持有,或者复用时,建议使用 addRef 接口手动增加引用计数。例如:

resources.load('images/background/spriteFrame', SpriteFrame, function (err, spriteFrame) {self.getComponent(Sprite).spriteFrame = spriteFrame;spriteFrame.addRef();
});

增加引用计数后,可以保证该资源不会被提前错误释放。而在不需要引用该资源以及相关组件,或者节点销毁时,请 务必记住 使用 decRef 移除引用计数,并将资源引用设为 null,例如:

this.spriteFrame.decRef();
this.spriteFrame = null;

5.3 下载与解析

Asset Manager 底层使用了多条加载管线来加载和解析资源,每条管线中都使用了 downloader 和 parser 模块,也就是下载器和解析器。开发者可以通过 assetManager.downloader 和 assetManager.parser 来访问。

CocosCreater 教程(下)相关推荐

  1. Web前端-JavaScript基础教程下

    Web前端-JavaScript基础教程下 <script>有6个属性: async对外部脚本有效,可以用来异步操作,下载东西,不妨碍其他操作. charset为src属性指定字符集. d ...

  2. Hyperledger Fabric 2.0 官方文档中文版 第6章 教程(下)

    Hyperledger Fabric 2.0 官方文档中文版 第6章 教程下 总目录 6.教程(下) 使用CouchDB 为什么使用CouchDB? 在Hyperledger Fabric中启用Cou ...

  3. 酷狗音乐的爬取,基于python,从无到有完整教程-下:功能代码讲解

    酷狗音乐的爬取,从无到有完整教程-下:功能代码讲解 是的我又回来了,这次是代码的讲解哦. 参数项生成 上一章我们提到,在包含了歌曲url,歌曲信息的请求中,有几个参数项的值是随机数就可以,但是,你仔细 ...

  4. 最详细的***教程 下

    第十七章------关于后门和*** 简单说明: 后门一般是指一个系统或是应用软件存在的一些设计缺陷,或是设计人员为了方便解决问题而特别留下的后门,总之无论怎么样?如果后门被其他人知道,或是在发布软件 ...

  5. 高等代数第3版下 [丘维声 著] 2015年版_机器学习与线性代数简明教程(下)

    机器学习与线性代数简明教程(上) 线性代数在机器学习(ML)和深度学习(DL)中是必不可少的.即使我们努力为许多理论创建精确的机器学习模型,线性代数仍然是这些研究中的重要工具. 正交矩阵 如果方形矩阵 ...

  6. 动力节点-javaweb项目入门到实战教程-下

    继续上文的内容,are you ready?let's go !!! 熟悉的配方搭配精美的视频:动力节点最新JavaWeb视频教程,javaweb零基础入门到精通IDEA版-持续更新中_哔哩哔哩_bi ...

  7. 【win】Photoshop+蓝湖插件安装小白教程(下)

    本教程为Photoshop安装及蓝湖插件安装教程,windows系统下.本篇紧跟上篇,讲蓝湖插件的下载安装和使用. 蓝湖 Photoshop插件安装: 1.首先下载蓝湖photoshop插件,插件ma ...

  8. 天龙八部TLBB从0到1搭建教程-下

    首先我们要知道一个完整的游戏的端包括 服务器端和补丁文件 tlbb.tar.gz为服务器端文件,大小应该在50-60左右 补丁的话看版本的修改情况未定,有大有小 tlbb.tar.gz解压之后会的文件 ...

  9. jenkins 入门教程(下)

    接上回继续学习jenkins,这次主要来看一些疑难杂症: 一.yum install安装方式 除了直接java -jar jenkins.war方式,还可以用yum安装,这种方式下提供了更多的可配置选 ...

最新文章

  1. 二十一.HTTP属性管理
  2. li变成行内块级元素之后,每一个li之间会有间隙,这是为什么?
  3. 【一雪前耻!】两种方法判断大小端模式
  4. HDFS的工作机制,HDFS写数据流程,HDFS读数据流程(来自学习资料)
  5. 清洁责任–摆脱均等,compareTo和toString
  6. $ajax不能识别,JQuery/JS Ajax功能无法识别
  7. MVVM下listbox默认显示最后一行
  8. 5分钟弄懂Docker
  9. b+树的增删改查_考研计算机 | 如何理解m阶B树?
  10. Linux服务器配置多台虚拟主机
  11. 小D课堂 - 新版本微服务springcloud+Docker教程_6-05 高级篇幅之高并发情况下
  12. php网站代码报告,使用Checkstyle报告(来自CodeSniffer)可视化PHP代码
  13. layui树形表格treetable
  14. 微分几何笔记(9) —— 切丛,余切丛
  15. 软件工程第一次阅读作业
  16. 黑马培训---分享点干货二 IOS面试非技术性问题
  17. linux C之srand函数
  18. 论文阅读 - Fame for sale: efficient detection of fake Twitter followers - Cresci - 2015数据集介绍
  19. php 抓取搜狗页面,爬虫解决方案之爬取“搜狗引擎”
  20. 初识 PS CS6(十三)___用快速选择工具择图

热门文章

  1. m3u8.sqlite文件转视频工具
  2. 我对软件测试行业的看法
  3. 关于primarykey 和key的注意事项
  4. 双评价技术指南2020_双评价技术指南试评价培训交流会成功召开
  5. 腾讯Q2财报:腾讯云数据库收入同比增长超过30%
  6. 指挥控制智能化现状与发展
  7. 快捷键及Dos命令学习总结
  8. Python根据Excel名单实现文件夹下文件批量改名
  9. 【源码篇】Kafka客户端发送消息
  10. 网络安全:细致分析与防范策略