【Cocos Creator实战教程(5)】——打砖块(物理引擎,碰撞检测)

lili

发布日期: 2018-11-25 22:52:54 浏览量: 1779
评分:
star star star star star star star star star star
*转载请注明来自write-bug.com

1. 知识点

  1. 物理引擎
  2. 碰撞检测

2. 步骤

2.1 准备工作

搭一个游戏背景

2.2 小球运动

再建一个物理层,用来装游戏里的带有物理属性的东西,设置锚点为左下角

  • wall:墙//小球碰到就会反弹的那种墙
  • ground:地面//球碰到地面,这局游戏就结束了
  • brick_layout:砖块布局//这个单词我们之前讲过了就不讲了
  • ball:球//就是球
  • paddle:桨//这里特指那个可以控制移动的白色长方形

这个wall肯定是要有碰撞属性的,在属性面板,添加一个物理组件 (物理->rigidbody)。

因为我们的墙有上,左,右三面,所以再添加三个碰撞组件(一个节点可以有多个碰撞组件)。

编辑一下

地面同理,小球同理,托盘同理 。(这里把地面和墙分开是为了后面墙和地面可能有不同的逻辑)

现在已经编辑了几个物理节点的碰撞包围盒,但还没有编辑他们的物理属性(cc.RigidBody)

先从小球开始,点击ball节点,在属性检查器可以看到

Cocos Creator从1.5版本开始支持Box2D物理游戏引擎,Box2D是一个优秀的刚体模拟框架,关于Box2D的知识可以去网络上自行了解。

把第一个参数勾选,代表启用碰撞回调,可以在脚本里写回调函数

Bullet:高速运动的物体(子弹)开启,避免穿透,这里不用勾选

type选择Dynamic,

  • static:不会受到力的影响,不会受到速度影响,指的是物理引擎,我们依然可以通过移动节点来改变位置 。

  • kinematic:不受力的影响,会受到速度影响 。

  • dynamic:受力影响,受速度影响 。

  • animated:和动画结合使用。

Gravity Scale设置为0(标准是1,数值代表比例),也就是没有重力。

设置线速度(1000,1000)

在下面的碰撞组件里,设置Friction (摩擦系数)等于0(没有摩擦力),Restitution(弹性系数)等于1(没有动量损耗)

因为小球是我们的主角,左右的碰撞都是对球来说的,所以碰撞属性都在小球这一方设置就可以了。

另外要设置wall,ground,paddle,brick的type为static
brick的tag为1,
ground的tag为2,
paddle的tag为3,
wall的tag位4

下面来看脚本

BrickLayout.js

  1. cc.Class({
  2. extends: cc.Component,
  3. properties: {
  4. padding: 0,
  5. spacing: 0,
  6. cols: 0,
  7. brickPrefab: cc.Prefab,
  8. bricksNumber: 0,
  9. },
  10. init(bricksNumber) {
  11. this.node.removeAllChildren();
  12. this.bricksNumber = bricksNumber;
  13. for (let i = 0; i < this.bricksNumber; i++) {
  14. let brickNode = cc.instantiate(this.brickPrefab);
  15. brickNode.parent = this.node;
  16. brickNode.x = this.padding + (i % this.cols) * (brickNode.width + this.spacing) + brickNode.width / 2;
  17. brickNode.y = -this.padding - Math.floor(i / this.cols) * (brickNode.height + this.spacing) - brickNode.height / 2;
  18. }
  19. }
  20. });

2.3 添加砖块

自己写了一个动态添加砖块的布局脚本,传入需要添加的砖块数量就可以动态加入的布局节点中。

2.4 结束界面

完善好游戏逻辑,我使用了MVC模式编写脚本。

3. 总结

至此,我便给大家简要的介绍了一下物理引擎,更多的功能需要大家自己探索实践。

列出几个大家常问的问题:

3.1如何移动刚体?

当我们的一个节点上有一个刚体,我们要进行移动。一般我们都会通过节点的setPosition进行移动,但是刚体不会被影响,不管是Static、还是Dynamic还是Kinematic都不会被影响
我们可以通过
1、瞬时动作cc.place来进行移动而且不会影响刚体原本的运动轨迹
2、Action的所有动作。cc.moveBy;cc.moveTo;等等

3.2 碰撞组件和物理组件有什么不同?

碰撞组件没有类型之分,只要相交就会发生碰撞事件,如果不对碰撞进行处理,那就没有任何影响。物理碰撞组件分类型,因为他们先会绑定刚体。如果刚体类型不同则会有不同的效果。
和Dynamtic类型刚体绑定的PhysicsBoxCollider会受重力影响,可以设置速度
和Static类型刚体绑定的物理组件,不会受重力影响,不可以设置速度,可以通过设置位置让其移动
和Kinematic类型刚体绑定的物理组件,不受重力影响,可以设置速度

例如,本文中我们就是用了物理碰撞组件,所以刚体类型选择上要有一定技巧。

在现实开发情况下,拾取道具和横像动作例如进攻多用碰撞组件 ,而竖向动作例如弹跳多用物理碰撞组件。

3.3 三种物理组件有什么不同?

绑定了Dynamic(运动)类型的物理组件不能穿透绑定了Static(静态)类型的物理组件
绑定了Dynamic类型的物理组件不能穿透绑定了Kinematic类型的物理组件
Static和Kinematic不会触发碰撞事件,Static和Static;Kinematic和Kinematic不会触发碰撞事件;

所以,因为我们不能将ball选为kinematic,尽管此游戏我们忽略了重力。

3.4 物理组件如何进行碰撞回调?

首先RigidBody要开启碰撞监听
然后当前节点下有如下函数

  1. 在函数碰撞体刚开始接触时调用一次
  2. onBeginContatctfunctioncontactselfColliderotherCollider){}
  3. 在两个碰撞体结束接触时被调用一次
  4. onEndContactfucntion(contact,setCollider,otherCollider){}
  5. 每次要处理碰撞体接触逻辑是被调用
  6. onPreSolvefunction(contact,selfCollider,otherCollider){}
  7. 每次处理完碰撞体接触时被调用
  8. onPostSolve:fucntion(contact,selfCollider,otherCollider){}

3.5 碰撞组件的回调

  1. var manager = cc.director.getCollisionManager();
  2. manager.enabled = true;
  3. 脚本里面先开启碰撞监听,因为默认是关闭
  4. 然后有以下函数:
  5. //当碰撞产生时调用
  6. onCollisionEnterfunction(other,self){
  7. }
  8. //在碰撞产生后,在碰撞结束前,每次计算完碰撞结果后调用
  9. onCollisionStay:function(other,self){}
  10. //当碰撞结束后调用
  11. onCollisionExit;function(other,self){}

部分素材来源于网络,欢迎提问

上传的附件 cloud_download cocos creator第五课.zip ( 702.13kb, 50次下载 )
eject