mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-09-24 08:42:50 +00:00
初始化
This commit is contained in:
110
engine/cocos2d/core/collider/CCBoxCollider.js
Normal file
110
engine/cocos2d/core/collider/CCBoxCollider.js
Normal file
@@ -0,0 +1,110 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* !#en Defines a Box Collider .
|
||||
* !#zh 用来定义包围盒碰撞体
|
||||
* @class Collider.Box
|
||||
*/
|
||||
cc.Collider.Box = cc.Class({
|
||||
properties: {
|
||||
_offset: cc.v2(0, 0),
|
||||
_size: cc.size(100, 100),
|
||||
|
||||
/**
|
||||
* !#en Position offset
|
||||
* !#zh 位置偏移量
|
||||
* @property offset
|
||||
* @type {Vec2}
|
||||
*/
|
||||
offset: {
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.physics.physics_collider.offset',
|
||||
get: function () {
|
||||
return this._offset;
|
||||
},
|
||||
set: function (value) {
|
||||
this._offset = value;
|
||||
},
|
||||
type: cc.Vec2
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Box size
|
||||
* !#zh 包围盒大小
|
||||
* @property size
|
||||
* @type {Size}
|
||||
*/
|
||||
size: {
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.physics.physics_collider.size',
|
||||
get: function () {
|
||||
return this._size;
|
||||
},
|
||||
set: function (value) {
|
||||
this._size.width = value.width < 0 ? 0 : value.width;
|
||||
this._size.height = value.height < 0 ? 0 : value.height;
|
||||
},
|
||||
type: cc.Size
|
||||
}
|
||||
},
|
||||
|
||||
resetInEditor: CC_EDITOR && function (didResetToDefault) {
|
||||
if (didResetToDefault) {
|
||||
var size = this.node.getContentSize();
|
||||
if (size.width !== 0 && size.height !== 0) {
|
||||
this.size = cc.size( size );
|
||||
this.offset.x = (0.5 - this.node.anchorX) * size.width;
|
||||
this.offset.y = (0.5 - this.node.anchorY) * size.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Box Collider.
|
||||
* !#zh 包围盒碰撞组件
|
||||
* @class BoxCollider
|
||||
* @extends Collider
|
||||
* @uses Collider.Box
|
||||
*/
|
||||
/**
|
||||
* !#en
|
||||
* Collider info in world coordinate.
|
||||
* !#zh
|
||||
* 碰撞体的世界坐标系下的信息。
|
||||
* @property {ColliderInfo} world
|
||||
*/
|
||||
var BoxCollider = cc.Class({
|
||||
name: 'cc.BoxCollider',
|
||||
extends: cc.Collider,
|
||||
mixins: [cc.Collider.Box],
|
||||
|
||||
editor: CC_EDITOR && {
|
||||
menu: 'i18n:MAIN_MENU.component.collider/Box Collider',
|
||||
}
|
||||
});
|
||||
|
||||
cc.BoxCollider = module.exports = BoxCollider;
|
106
engine/cocos2d/core/collider/CCCircleCollider.js
Normal file
106
engine/cocos2d/core/collider/CCCircleCollider.js
Normal file
@@ -0,0 +1,106 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* !#en Defines a Circle Collider .
|
||||
* !#zh 用来定义圆形碰撞体
|
||||
* @class Collider.Circle
|
||||
*/
|
||||
cc.Collider.Circle = cc.Class({
|
||||
properties: {
|
||||
_offset: cc.v2(0, 0),
|
||||
_radius: 50,
|
||||
|
||||
/**
|
||||
* !#en Position offset
|
||||
* !#zh 位置偏移量
|
||||
* @property offset
|
||||
* @type {Vec2}
|
||||
*/
|
||||
offset: {
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.physics.physics_collider.offset',
|
||||
get: function () {
|
||||
return this._offset;
|
||||
},
|
||||
set: function (value) {
|
||||
this._offset = value;
|
||||
},
|
||||
type: cc.Vec2
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Circle radius
|
||||
* !#zh 圆形半径
|
||||
* @property radius
|
||||
* @type {Number}
|
||||
*/
|
||||
radius: {
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.physics.physics_collider.radius',
|
||||
get: function () {
|
||||
return this._radius;
|
||||
},
|
||||
set: function (value) {
|
||||
this._radius = value < 0 ? 0 : value;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
resetInEditor: CC_EDITOR && function (didResetToDefault) {
|
||||
if (didResetToDefault) {
|
||||
var size = this.node.getContentSize();
|
||||
var radius = Math.max(size.width, size.height);
|
||||
if (radius !== 0) {
|
||||
this.radius = radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en Circle Collider.
|
||||
* !#zh 圆形碰撞组件
|
||||
* @class CircleCollider
|
||||
* @extends Collider
|
||||
* @uses Collider.Circle
|
||||
*/
|
||||
/**
|
||||
* !#en
|
||||
* Collider info in world coordinate.
|
||||
* !#zh
|
||||
* 碰撞体的世界坐标系下的信息。
|
||||
* @property {ColliderInfo} world
|
||||
*/
|
||||
var CircleCollider = cc.Class({
|
||||
name: 'cc.CircleCollider',
|
||||
extends: cc.Collider,
|
||||
mixins: [cc.Collider.Circle],
|
||||
|
||||
editor: CC_EDITOR && {
|
||||
menu: 'i18n:MAIN_MENU.component.collider/Circle Collider'
|
||||
},
|
||||
});
|
||||
|
||||
cc.CircleCollider = module.exports = CircleCollider;
|
68
engine/cocos2d/core/collider/CCCollider.js
Normal file
68
engine/cocos2d/core/collider/CCCollider.js
Normal file
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* !#en Collider component base class.
|
||||
* !#zh 碰撞组件基类
|
||||
* @class Collider
|
||||
* @extends Component
|
||||
*/
|
||||
var Collider = cc.Class({
|
||||
name: 'cc.Collider',
|
||||
extends: cc.Component,
|
||||
|
||||
properties: {
|
||||
editing: {
|
||||
default: false,
|
||||
serializable: false,
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.collider.editing'
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Tag. If a node has several collider components, you can judge which type of collider is collided according to the tag.
|
||||
* !#zh 标签。当一个节点上有多个碰撞组件时,在发生碰撞后,可以使用此标签来判断是节点上的哪个碰撞组件被碰撞了。
|
||||
* @property tag
|
||||
* @type {Integer}
|
||||
* @default 0
|
||||
*/
|
||||
tag: {
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.physics.physics_collider.tag',
|
||||
default: 0,
|
||||
range: [0, 10e6],
|
||||
type: cc.Integer
|
||||
}
|
||||
},
|
||||
|
||||
onDisable: function () {
|
||||
cc.director.getCollisionManager().removeCollider(this);
|
||||
},
|
||||
|
||||
onEnable: function () {
|
||||
cc.director.getCollisionManager().addCollider(this);
|
||||
}
|
||||
});
|
||||
|
||||
cc.Collider = module.exports = Collider;
|
543
engine/cocos2d/core/collider/CCCollisionManager.js
Normal file
543
engine/cocos2d/core/collider/CCCollisionManager.js
Normal file
@@ -0,0 +1,543 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
import Vec2 from '../value-types/vec2';
|
||||
|
||||
const Contact = require('./CCContact');
|
||||
const CollisionType = Contact.CollisionType;
|
||||
const NodeEvent = require('../CCNode').EventType;
|
||||
|
||||
let _vec2 = new Vec2();
|
||||
|
||||
function obbApplyMatrix (rect, mat4, out_bl, out_tl, out_tr, out_br) {
|
||||
let x = rect.x;
|
||||
let y = rect.y;
|
||||
let width = rect.width;
|
||||
let height = rect.height;
|
||||
|
||||
let mat4m = mat4.m;
|
||||
let m00 = mat4m[0], m01 = mat4m[1], m04 = mat4m[4], m05 = mat4m[5];
|
||||
let m12 = mat4m[12], m13 = mat4m[13];
|
||||
|
||||
let tx = m00 * x + m04 * y + m12;
|
||||
let ty = m01 * x + m05 * y + m13;
|
||||
let xa = m00 * width;
|
||||
let xb = m01 * width;
|
||||
let yc = m04 * height;
|
||||
let yd = m05 * height;
|
||||
|
||||
out_tl.x = tx;
|
||||
out_tl.y = ty;
|
||||
out_tr.x = xa + tx;
|
||||
out_tr.y = xb + ty;
|
||||
out_bl.x = yc + tx;
|
||||
out_bl.y = yd + ty;
|
||||
out_br.x = xa + yc + tx;
|
||||
out_br.y = xb + yd + ty;
|
||||
}
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* Collider Info.
|
||||
* !#zh
|
||||
* 碰撞体信息。
|
||||
* @class ColliderInfo
|
||||
*/
|
||||
/**
|
||||
* !#en
|
||||
* Collider aabb information of last frame
|
||||
* !#zh
|
||||
* 碰撞体上一帧的 aabb 信息
|
||||
* @property {Rect} preAabb
|
||||
*/
|
||||
/**
|
||||
* !#en
|
||||
* Collider aabb information of current frame
|
||||
* !#zh
|
||||
* 碰撞体当前帧的 aabb 信息
|
||||
* @property {Rect} aabb
|
||||
*/
|
||||
/**
|
||||
* !#en
|
||||
* Collider matrix
|
||||
* !#zh
|
||||
* 碰撞体的矩阵信息
|
||||
* @property {Mat4} matrix
|
||||
*/
|
||||
/**
|
||||
* !#en
|
||||
* Collider radius (for CircleCollider)
|
||||
* !#zh
|
||||
* 碰撞体的半径(只对 CircleCollider 有效)
|
||||
* @property {Number} radius
|
||||
*/
|
||||
/**
|
||||
* !#en
|
||||
* Collider position (for CircleCollider)
|
||||
* !#zh
|
||||
* 碰撞体的位置(只对 CircleCollider 有效)
|
||||
* @property {Vec2} position
|
||||
*/
|
||||
/**
|
||||
* !#en
|
||||
* Collider points (for BoxCollider and PolygonCollider)
|
||||
* !#zh
|
||||
* 碰撞体的顶点信息(只对 BoxCollider 和 PolygonCollider 有效)
|
||||
* @property {Vec2[]} points
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* A simple collision manager class.
|
||||
* It will calculate whether the collider collides other colliders, if collides then call the callbacks.
|
||||
* !#zh
|
||||
* 一个简单的碰撞组件管理类,用于处理节点之间的碰撞组件是否产生了碰撞,并调用相应回调函数。
|
||||
*
|
||||
* @class CollisionManager
|
||||
* @uses EventTarget
|
||||
* @example
|
||||
*
|
||||
* // Get the collision manager.
|
||||
* let manager = cc.director.getCollisionManager();
|
||||
*
|
||||
* // Enabled the colider manager.
|
||||
* manager.enabled = true;
|
||||
*
|
||||
* // Enabled draw collider
|
||||
* manager.enabledDebugDraw = true;
|
||||
*
|
||||
* // Enabled draw collider bounding box
|
||||
* manager.enabledDrawBoundingBox = true;
|
||||
*
|
||||
*
|
||||
* // Collision callback
|
||||
* onCollisionEnter: function (other, self) {
|
||||
* this.node.color = cc.Color.RED;
|
||||
* this.touchingNumber ++;
|
||||
*
|
||||
* // let world = self.world;
|
||||
* // let aabb = world.aabb;
|
||||
* // let preAabb = world.preAabb;
|
||||
* // let m = world.matrix;
|
||||
*
|
||||
* // for circle collider
|
||||
* // let r = world.radius;
|
||||
* // let p = world.position;
|
||||
*
|
||||
* // for box collider and polygon collider
|
||||
* // let ps = world.points;
|
||||
* },
|
||||
*
|
||||
* onCollisionStay: function (other, self) {
|
||||
* console.log('on collision stay');
|
||||
* },
|
||||
*
|
||||
* onCollisionExit: function (other, self) {
|
||||
* this.touchingNumber --;
|
||||
* if (this.touchingNumber === 0) {
|
||||
* this.node.color = cc.Color.WHITE;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
let CollisionManager = cc.Class({
|
||||
mixins: [cc.EventTarget],
|
||||
|
||||
properties: {
|
||||
/**
|
||||
* !#en
|
||||
* !#zh
|
||||
* 是否开启碰撞管理,默认为不开启
|
||||
* @property {Boolean} enabled
|
||||
* @default false
|
||||
*/
|
||||
enabled: false,
|
||||
/**
|
||||
* !#en
|
||||
* !#zh
|
||||
* 是否绘制碰撞组件的包围盒,默认为不绘制
|
||||
* @property {Boolean} enabledDrawBoundingBox
|
||||
* @default false
|
||||
*/
|
||||
enabledDrawBoundingBox: false
|
||||
},
|
||||
|
||||
ctor: function () {
|
||||
this._contacts = [];
|
||||
this._colliders = [];
|
||||
this._debugDrawer = null;
|
||||
this._enabledDebugDraw = false;
|
||||
|
||||
cc.director._scheduler && cc.director._scheduler.enableForTarget(this);
|
||||
},
|
||||
|
||||
update: function (dt) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let i, l;
|
||||
|
||||
// update collider
|
||||
let colliders = this._colliders;
|
||||
for (i = 0, l = colliders.length; i < l; i++) {
|
||||
this.updateCollider(colliders[i]);
|
||||
}
|
||||
|
||||
// do collide
|
||||
let contacts = this._contacts;
|
||||
let results = [];
|
||||
|
||||
for (i = 0, l = contacts.length; i < l; i++) {
|
||||
let collisionType = contacts[i].updateState();
|
||||
if (collisionType === CollisionType.None) {
|
||||
continue;
|
||||
}
|
||||
|
||||
results.push([collisionType, contacts[i]]);
|
||||
}
|
||||
|
||||
// handle collide results, emit message
|
||||
for (i = 0, l = results.length; i < l; i++) {
|
||||
let result = results[i];
|
||||
this._doCollide(result[0], result[1]);
|
||||
}
|
||||
|
||||
// draw colliders
|
||||
this.drawColliders();
|
||||
},
|
||||
|
||||
_doCollide: function (collisionType, contact) {
|
||||
let contactFunc;
|
||||
switch (collisionType) {
|
||||
case CollisionType.CollisionEnter:
|
||||
contactFunc = 'onCollisionEnter';
|
||||
break;
|
||||
case CollisionType.CollisionStay:
|
||||
contactFunc = 'onCollisionStay';
|
||||
break;
|
||||
case CollisionType.CollisionExit:
|
||||
contactFunc = 'onCollisionExit';
|
||||
break;
|
||||
}
|
||||
|
||||
let collider1 = contact.collider1;
|
||||
let collider2 = contact.collider2;
|
||||
|
||||
let comps1 = collider1.node._components;
|
||||
let comps2 = collider2.node._components;
|
||||
|
||||
let i, l, comp;
|
||||
for (i = 0, l = comps1.length; i < l; i++) {
|
||||
comp = comps1[i];
|
||||
if (comp[contactFunc]) {
|
||||
comp[contactFunc](collider2, collider1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, l = comps2.length; i < l; i++) {
|
||||
comp = comps2[i];
|
||||
if (comp[contactFunc]) {
|
||||
comp[contactFunc](collider1, collider2);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
shouldCollide: function (c1, c2) {
|
||||
let node1 = c1.node, node2 = c2.node;
|
||||
let collisionMatrix = cc.game.collisionMatrix;
|
||||
return node1 !== node2 && collisionMatrix[node1.groupIndex][node2.groupIndex];
|
||||
},
|
||||
|
||||
initCollider: function (collider) {
|
||||
if (!collider.world) {
|
||||
let world = collider.world = {};
|
||||
world.aabb = cc.rect();
|
||||
world.preAabb = cc.rect();
|
||||
world.matrix = cc.mat4();
|
||||
|
||||
world.radius = 0;
|
||||
|
||||
if (collider instanceof cc.BoxCollider) {
|
||||
world.position = null;
|
||||
world.points = [cc.v2(), cc.v2(), cc.v2(), cc.v2()];
|
||||
}
|
||||
else if (collider instanceof cc.PolygonCollider) {
|
||||
world.position = null;
|
||||
world.points = collider.points.map(function (p) {
|
||||
return cc.v2(p.x, p.y);
|
||||
});
|
||||
}
|
||||
else if (collider instanceof cc.CircleCollider) {
|
||||
world.position = cc.v2();
|
||||
world.points = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateCollider: function (collider) {
|
||||
let offset = collider.offset;
|
||||
let world = collider.world;
|
||||
let aabb = world.aabb;
|
||||
|
||||
let m = world.matrix;
|
||||
collider.node.getWorldMatrix(m);
|
||||
|
||||
let preAabb = world.preAabb;
|
||||
preAabb.x = aabb.x;
|
||||
preAabb.y = aabb.y;
|
||||
preAabb.width = aabb.width;
|
||||
preAabb.height = aabb.height;
|
||||
|
||||
if (collider instanceof cc.BoxCollider) {
|
||||
let size = collider.size;
|
||||
|
||||
aabb.x = offset.x - size.width/2;
|
||||
aabb.y = offset.y - size.height/2;
|
||||
aabb.width = size.width;
|
||||
aabb.height = size.height;
|
||||
|
||||
let wps = world.points;
|
||||
let wp0 = wps[0], wp1 = wps[1],
|
||||
wp2 = wps[2], wp3 = wps[3];
|
||||
obbApplyMatrix(aabb, m, wp0, wp1, wp2, wp3);
|
||||
|
||||
let minx = Math.min(wp0.x, wp1.x, wp2.x, wp3.x);
|
||||
let miny = Math.min(wp0.y, wp1.y, wp2.y, wp3.y);
|
||||
let maxx = Math.max(wp0.x, wp1.x, wp2.x, wp3.x);
|
||||
let maxy = Math.max(wp0.y, wp1.y, wp2.y, wp3.y);
|
||||
|
||||
aabb.x = minx;
|
||||
aabb.y = miny;
|
||||
aabb.width = maxx - minx;
|
||||
aabb.height = maxy - miny;
|
||||
}
|
||||
else if (collider instanceof cc.CircleCollider) {
|
||||
// calculate world position
|
||||
Vec2.transformMat4(_vec2, collider.offset, m);
|
||||
|
||||
world.position.x = _vec2.x;
|
||||
world.position.y = _vec2.y;
|
||||
|
||||
// calculate world radius
|
||||
let mm = m.m;
|
||||
let tempx = mm[12], tempy = mm[13];
|
||||
mm[12] = mm[13] = 0;
|
||||
|
||||
_vec2.x = collider.radius;
|
||||
_vec2.y = 0;
|
||||
|
||||
Vec2.transformMat4(_vec2, _vec2, m);
|
||||
let d = Math.sqrt(_vec2.x * _vec2.x + _vec2.y * _vec2.y);
|
||||
|
||||
world.radius = d;
|
||||
|
||||
aabb.x = world.position.x - d;
|
||||
aabb.y = world.position.y - d;
|
||||
aabb.width = d * 2;
|
||||
aabb.height = d * 2;
|
||||
|
||||
mm[12] = tempx;
|
||||
mm[13] = tempy;
|
||||
}
|
||||
else if (collider instanceof cc.PolygonCollider) {
|
||||
let points = collider.points;
|
||||
let worldPoints = world.points;
|
||||
|
||||
worldPoints.length = points.length;
|
||||
|
||||
let minx = 1e6, miny = 1e6, maxx = -1e6, maxy = -1e6;
|
||||
for (let i = 0, l = points.length; i < l; i++) {
|
||||
if (!worldPoints[i]) {
|
||||
worldPoints[i] = cc.v2();
|
||||
}
|
||||
|
||||
_vec2.x = points[i].x + offset.x;
|
||||
_vec2.y = points[i].y + offset.y;
|
||||
|
||||
Vec2.transformMat4(_vec2, _vec2, m);
|
||||
|
||||
let x = _vec2.x;
|
||||
let y = _vec2.y;
|
||||
|
||||
worldPoints[i].x = x;
|
||||
worldPoints[i].y = y;
|
||||
|
||||
if (x > maxx) maxx = x;
|
||||
if (x < minx) minx = x;
|
||||
if (y > maxy) maxy = y;
|
||||
if (y < miny) miny = y;
|
||||
}
|
||||
|
||||
aabb.x = minx;
|
||||
aabb.y = miny;
|
||||
aabb.width = maxx - minx;
|
||||
aabb.height = maxy - miny;
|
||||
}
|
||||
},
|
||||
|
||||
addCollider: function (collider) {
|
||||
let colliders = this._colliders;
|
||||
let index = colliders.indexOf(collider);
|
||||
if (index === -1) {
|
||||
for (let i = 0, l = colliders.length; i < l; i++) {
|
||||
let other = colliders[i];
|
||||
if (this.shouldCollide(collider, other)) {
|
||||
let contact = new Contact(collider, other);
|
||||
this._contacts.push(contact);
|
||||
}
|
||||
}
|
||||
|
||||
colliders.push(collider);
|
||||
this.initCollider(collider);
|
||||
}
|
||||
|
||||
collider.node.on(NodeEvent.GROUP_CHANGED, this.onNodeGroupChanged, this);
|
||||
},
|
||||
|
||||
removeCollider: function (collider) {
|
||||
let colliders = this._colliders;
|
||||
let index = colliders.indexOf(collider);
|
||||
if (index >= 0) {
|
||||
colliders.splice(index, 1);
|
||||
|
||||
let contacts = this._contacts;
|
||||
for (let i = contacts.length - 1; i >= 0; i--) {
|
||||
let contact = contacts[i];
|
||||
if (contact.collider1 === collider || contact.collider2 === collider) {
|
||||
if (contact.touching) {
|
||||
this._doCollide(CollisionType.CollisionExit, contact);
|
||||
}
|
||||
|
||||
contacts.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
collider.node.off(NodeEvent.GROUP_CHANGED, this.onNodeGroupChanged, this);
|
||||
}
|
||||
else {
|
||||
cc.errorID(6600);
|
||||
}
|
||||
},
|
||||
|
||||
onNodeGroupChanged: function (node) {
|
||||
let colliders = node.getComponents(cc.Collider);
|
||||
|
||||
for (let i = 0, l = colliders.length; i < l; i++) {
|
||||
let collider = colliders[i];
|
||||
if(cc.PhysicsCollider && collider instanceof cc.PhysicsCollider) {
|
||||
continue;
|
||||
}
|
||||
this.removeCollider(collider);
|
||||
this.addCollider(collider);
|
||||
}
|
||||
},
|
||||
|
||||
drawColliders: function () {
|
||||
if (!this._enabledDebugDraw) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._checkDebugDrawValid();
|
||||
|
||||
let debugDrawer = this._debugDrawer;
|
||||
debugDrawer.clear();
|
||||
|
||||
let colliders = this._colliders;
|
||||
|
||||
for (let i = 0, l = colliders.length; i < l; i++) {
|
||||
let collider = colliders[i];
|
||||
|
||||
debugDrawer.strokeColor = cc.Color.WHITE;
|
||||
if (collider instanceof cc.BoxCollider || collider instanceof cc.PolygonCollider) {
|
||||
let ps = collider.world.points;
|
||||
if (ps.length > 0) {
|
||||
debugDrawer.moveTo(ps[0].x, ps[0].y);
|
||||
for (let j = 1; j < ps.length; j++) {
|
||||
debugDrawer.lineTo(ps[j].x, ps[j].y);
|
||||
}
|
||||
debugDrawer.close();
|
||||
debugDrawer.stroke();
|
||||
}
|
||||
}
|
||||
else if (collider instanceof cc.CircleCollider) {
|
||||
debugDrawer.circle(collider.world.position.x, collider.world.position.y, collider.world.radius);
|
||||
debugDrawer.stroke();
|
||||
}
|
||||
|
||||
if (this.enabledDrawBoundingBox) {
|
||||
let aabb = collider.world.aabb;
|
||||
|
||||
debugDrawer.strokeColor = cc.Color.BLUE;
|
||||
|
||||
debugDrawer.moveTo(aabb.xMin, aabb.yMin);
|
||||
debugDrawer.lineTo(aabb.xMin, aabb.yMax);
|
||||
debugDrawer.lineTo(aabb.xMax, aabb.yMax);
|
||||
debugDrawer.lineTo(aabb.xMax, aabb.yMin);
|
||||
|
||||
debugDrawer.close();
|
||||
debugDrawer.stroke();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_checkDebugDrawValid () {
|
||||
if (!this._debugDrawer || !this._debugDrawer.isValid) {
|
||||
let node = new cc.Node('COLLISION_MANAGER_DEBUG_DRAW');
|
||||
node.zIndex = cc.macro.MAX_ZINDEX;
|
||||
cc.game.addPersistRootNode(node);
|
||||
this._debugDrawer = node.addComponent(cc.Graphics);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* !#en
|
||||
* !#zh
|
||||
* 是否绘制碰撞组件的形状,默认为不绘制
|
||||
* @property {Boolean} enabledDebugDraw
|
||||
* @default false
|
||||
*/
|
||||
cc.js.getset(CollisionManager.prototype, 'enabledDebugDraw',
|
||||
function () {
|
||||
return this._enabledDebugDraw;
|
||||
},
|
||||
function (value) {
|
||||
if (value && !this._enabledDebugDraw) {
|
||||
this._checkDebugDrawValid();
|
||||
this._debugDrawer.node.active = true;
|
||||
}
|
||||
else if (!value && this._enabledDebugDraw) {
|
||||
this._debugDrawer.clear(true);
|
||||
this._debugDrawer.node.active = false;
|
||||
}
|
||||
|
||||
this._enabledDebugDraw = value;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
cc.CollisionManager = module.exports = CollisionManager;
|
109
engine/cocos2d/core/collider/CCContact.js
Normal file
109
engine/cocos2d/core/collider/CCContact.js
Normal file
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
var Intersection = require('./CCIntersection');
|
||||
|
||||
var CollisionType = cc.Enum({
|
||||
None: 0,
|
||||
CollisionEnter: 1,
|
||||
CollisionStay: 2,
|
||||
CollisionExit: 3
|
||||
});
|
||||
|
||||
function Contact (collider1, collider2) {
|
||||
this.collider1 = collider1;
|
||||
this.collider2 = collider2;
|
||||
|
||||
this.touching = false;
|
||||
|
||||
var isCollider1Polygon = (collider1 instanceof cc.BoxCollider) || (collider1 instanceof cc.PolygonCollider);
|
||||
var isCollider2Polygon = (collider2 instanceof cc.BoxCollider) || (collider2 instanceof cc.PolygonCollider);
|
||||
var isCollider1Circle = collider1 instanceof cc.CircleCollider;
|
||||
var isCollider2Circle = collider2 instanceof cc.CircleCollider;
|
||||
|
||||
if (isCollider1Polygon && isCollider2Polygon) {
|
||||
this.testFunc = Intersection.polygonPolygon;
|
||||
}
|
||||
else if (isCollider1Circle && isCollider2Circle) {
|
||||
this.testFunc = Intersection.circleCircle;
|
||||
}
|
||||
else if (isCollider1Polygon && isCollider2Circle) {
|
||||
this.testFunc = Intersection.polygonCircle;
|
||||
}
|
||||
else if (isCollider1Circle && isCollider2Polygon) {
|
||||
this.testFunc = Intersection.polygonCircle;
|
||||
this.collider1 = collider2;
|
||||
this.collider2 = collider1;
|
||||
}
|
||||
else {
|
||||
cc.errorID(6601, cc.js.getClassName(collider1), cc.js.getClassName(collider2));
|
||||
}
|
||||
}
|
||||
|
||||
Contact.prototype.test = function () {
|
||||
var world1 = this.collider1.world;
|
||||
var world2 = this.collider2.world;
|
||||
|
||||
if (!world1.aabb.intersects(world2.aabb)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.testFunc === Intersection.polygonPolygon) {
|
||||
return this.testFunc(world1.points, world2.points);
|
||||
}
|
||||
else if (this.testFunc === Intersection.circleCircle) {
|
||||
return this.testFunc(world1, world2);
|
||||
}
|
||||
else if (this.testFunc === Intersection.polygonCircle) {
|
||||
return this.testFunc(world1.points, world2);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
Contact.prototype.updateState = function () {
|
||||
var result = this.test();
|
||||
|
||||
var type = CollisionType.None;
|
||||
if (result && !this.touching) {
|
||||
this.touching = true;
|
||||
type = CollisionType.CollisionEnter;
|
||||
}
|
||||
else if (result && this.touching) {
|
||||
type = CollisionType.CollisionStay;
|
||||
}
|
||||
else if (!result && this.touching) {
|
||||
this.touching = false;
|
||||
type = CollisionType.CollisionExit;
|
||||
}
|
||||
|
||||
return type;
|
||||
};
|
||||
|
||||
|
||||
Contact.CollisionType = CollisionType;
|
||||
|
||||
module.exports = Contact;
|
358
engine/cocos2d/core/collider/CCIntersection.js
Normal file
358
engine/cocos2d/core/collider/CCIntersection.js
Normal file
@@ -0,0 +1,358 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* !#en Intersection helper class
|
||||
* !#zh 辅助类,用于测试形状与形状是否相交
|
||||
* @class Intersection
|
||||
* @static
|
||||
*/
|
||||
var Intersection = {};
|
||||
|
||||
/**
|
||||
* !#en Test line and line
|
||||
* !#zh 测试线段与线段是否相交
|
||||
* @method lineLine
|
||||
* @param {Vec2} a1 - The start point of the first line
|
||||
* @param {Vec2} a2 - The end point of the first line
|
||||
* @param {Vec2} b1 - The start point of the second line
|
||||
* @param {Vec2} b2 - The end point of the second line
|
||||
* @return {boolean}
|
||||
*/
|
||||
function lineLine ( a1, a2, b1, b2 ) {
|
||||
// jshint camelcase:false
|
||||
|
||||
var ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x);
|
||||
var ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x);
|
||||
var u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
|
||||
|
||||
if ( u_b !== 0 ) {
|
||||
var ua = ua_t / u_b;
|
||||
var ub = ub_t / u_b;
|
||||
|
||||
if ( 0 <= ua && ua <= 1 && 0 <= ub && ub <= 1 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Intersection.lineLine = lineLine;
|
||||
|
||||
/**
|
||||
* !#en Test line and rect
|
||||
* !#zh 测试线段与矩形是否相交
|
||||
* @method lineRect
|
||||
* @param {Vec2} a1 - The start point of the line
|
||||
* @param {Vec2} a2 - The end point of the line
|
||||
* @param {Rect} b - The rect
|
||||
* @return {boolean}
|
||||
*/
|
||||
function lineRect ( a1, a2, b ) {
|
||||
var r0 = new cc.Vec2( b.x, b.y );
|
||||
var r1 = new cc.Vec2( b.x, b.yMax );
|
||||
var r2 = new cc.Vec2( b.xMax, b.yMax );
|
||||
var r3 = new cc.Vec2( b.xMax, b.y );
|
||||
|
||||
if ( lineLine( a1, a2, r0, r1 ) )
|
||||
return true;
|
||||
|
||||
if ( lineLine( a1, a2, r1, r2 ) )
|
||||
return true;
|
||||
|
||||
if ( lineLine( a1, a2, r2, r3 ) )
|
||||
return true;
|
||||
|
||||
if ( lineLine( a1, a2, r3, r0 ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Intersection.lineRect = lineRect;
|
||||
|
||||
/**
|
||||
* !#en Test line and polygon
|
||||
* !#zh 测试线段与多边形是否相交
|
||||
* @method linePolygon
|
||||
* @param {Vec2} a1 - The start point of the line
|
||||
* @param {Vec2} a2 - The end point of the line
|
||||
* @param {Vec2[]} b - The polygon, a set of points
|
||||
* @return {boolean}
|
||||
*/
|
||||
function linePolygon ( a1, a2, b ) {
|
||||
var length = b.length;
|
||||
|
||||
for ( var i = 0; i < length; ++i ) {
|
||||
var b1 = b[i];
|
||||
var b2 = b[(i+1)%length];
|
||||
|
||||
if ( lineLine( a1, a2, b1, b2 ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Intersection.linePolygon = linePolygon;
|
||||
|
||||
/**
|
||||
* !#en Test rect and rect
|
||||
* !#zh 测试矩形与矩形是否相交
|
||||
* @method rectRect
|
||||
* @param {Rect} a - The first rect
|
||||
* @param {Rect} b - The second rect
|
||||
* @return {boolean}
|
||||
*/
|
||||
function rectRect ( a, b ) {
|
||||
// jshint camelcase:false
|
||||
|
||||
var a_min_x = a.x;
|
||||
var a_min_y = a.y;
|
||||
var a_max_x = a.x + a.width;
|
||||
var a_max_y = a.y + a.height;
|
||||
|
||||
var b_min_x = b.x;
|
||||
var b_min_y = b.y;
|
||||
var b_max_x = b.x + b.width;
|
||||
var b_max_y = b.y + b.height;
|
||||
|
||||
return a_min_x <= b_max_x &&
|
||||
a_max_x >= b_min_x &&
|
||||
a_min_y <= b_max_y &&
|
||||
a_max_y >= b_min_y
|
||||
;
|
||||
}
|
||||
|
||||
Intersection.rectRect = rectRect;
|
||||
|
||||
/**
|
||||
* !#en Test rect and polygon
|
||||
* !#zh 测试矩形与多边形是否相交
|
||||
* @method rectPolygon
|
||||
* @param {Rect} a - The rect
|
||||
* @param {Vec2[]} b - The polygon, a set of points
|
||||
* @return {boolean}
|
||||
*/
|
||||
function rectPolygon ( a, b ) {
|
||||
var i, l;
|
||||
var r0 = new cc.Vec2( a.x, a.y );
|
||||
var r1 = new cc.Vec2( a.x, a.yMax );
|
||||
var r2 = new cc.Vec2( a.xMax, a.yMax );
|
||||
var r3 = new cc.Vec2( a.xMax, a.y );
|
||||
|
||||
// intersection check
|
||||
if ( linePolygon( r0, r1, b ) )
|
||||
return true;
|
||||
|
||||
if ( linePolygon( r1, r2, b ) )
|
||||
return true;
|
||||
|
||||
if ( linePolygon( r2, r3, b ) )
|
||||
return true;
|
||||
|
||||
if ( linePolygon( r3, r0, b ) )
|
||||
return true;
|
||||
|
||||
// check if a contains b
|
||||
for ( i = 0, l = b.length; i < l; ++i ) {
|
||||
if ( pointInPolygon(b[i], a) )
|
||||
return true;
|
||||
}
|
||||
|
||||
// check if b contains a
|
||||
if ( pointInPolygon(r0, b) )
|
||||
return true;
|
||||
|
||||
if ( pointInPolygon(r1, b) )
|
||||
return true;
|
||||
|
||||
if ( pointInPolygon(r2, b) )
|
||||
return true;
|
||||
|
||||
if ( pointInPolygon(r3, b) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Intersection.rectPolygon = rectPolygon;
|
||||
|
||||
/**
|
||||
* !#en Test polygon and polygon
|
||||
* !#zh 测试多边形与多边形是否相交
|
||||
* @method polygonPolygon
|
||||
* @param {Vec2[]} a - The first polygon, a set of points
|
||||
* @param {Vec2[]} b - The second polygon, a set of points
|
||||
* @return {boolean}
|
||||
*/
|
||||
function polygonPolygon ( a, b ) {
|
||||
var i, l;
|
||||
|
||||
// check if a intersects b
|
||||
for ( i = 0, l = a.length; i < l; ++i ) {
|
||||
var a1 = a[i];
|
||||
var a2 = a[(i+1)%l];
|
||||
|
||||
if ( linePolygon( a1, a2, b ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
// check if a contains b
|
||||
for ( i = 0, l = b.length; i < l; ++i ) {
|
||||
if ( pointInPolygon(b[i], a) )
|
||||
return true;
|
||||
}
|
||||
|
||||
// check if b contains a
|
||||
for ( i = 0, l = a.length; i < l; ++i ) {
|
||||
if ( pointInPolygon( a[i], b ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Intersection.polygonPolygon = polygonPolygon;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* !#en Test circle and circle
|
||||
* !#zh 测试圆形与圆形是否相交
|
||||
* @method circleCircle
|
||||
* @param {Object} a - Object contains position and radius
|
||||
* @param {Object} b - Object contains position and radius
|
||||
* @return {boolean}
|
||||
* @typescript circleCircle(a: {position: Vec2, radius: number}, b: {position: Vec2, radius: number}): boolean
|
||||
*/
|
||||
function circleCircle (a, b) {
|
||||
var distance = a.position.sub(b.position).mag();
|
||||
return distance < (a.radius + b.radius);
|
||||
}
|
||||
|
||||
Intersection.circleCircle = circleCircle;
|
||||
|
||||
|
||||
/**
|
||||
* !#en Test polygon and circle
|
||||
* !#zh 测试矩形与圆形是否相交
|
||||
* @method polygonCircle
|
||||
* @param {Vec2[]} polygon - The Polygon, a set of points
|
||||
* @param {Object} circle - Object contains position and radius
|
||||
* @return {boolean}
|
||||
* @typescript polygonCircle(polygon: Vec2[], circle: {position: Vec2, radius: number}): boolean
|
||||
*/
|
||||
function polygonCircle (polygon, circle) {
|
||||
var position = circle.position;
|
||||
if (pointInPolygon(position, polygon)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (var i = 0, l = polygon.length; i < l; i++) {
|
||||
var start = i === 0 ? polygon[polygon.length - 1] : polygon[i- 1];
|
||||
var end = polygon[i];
|
||||
|
||||
if (pointLineDistance(position, start, end, true) < circle.radius) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Intersection.polygonCircle = polygonCircle;
|
||||
|
||||
/**
|
||||
* !#en Test whether the point is in the polygon
|
||||
* !#zh 测试一个点是否在一个多边形中
|
||||
* @method pointInPolygon
|
||||
* @param {Vec2} point - The point
|
||||
* @param {Vec2[]} polygon - The polygon, a set of points
|
||||
* @return {boolean}
|
||||
*/
|
||||
function pointInPolygon (point, polygon) {
|
||||
var inside = false;
|
||||
var x = point.x;
|
||||
var y = point.y;
|
||||
|
||||
// use some raycasting to test hits
|
||||
// https://github.com/substack/point-in-polygon/blob/master/index.js
|
||||
var length = polygon.length;
|
||||
|
||||
for ( var i = 0, j = length-1; i < length; j = i++ ) {
|
||||
var xi = polygon[i].x, yi = polygon[i].y,
|
||||
xj = polygon[j].x, yj = polygon[j].y,
|
||||
intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
||||
|
||||
if ( intersect ) inside = !inside;
|
||||
}
|
||||
|
||||
return inside;
|
||||
}
|
||||
|
||||
Intersection.pointInPolygon = pointInPolygon;
|
||||
|
||||
/**
|
||||
* !#en Calculate the distance of point to line.
|
||||
* !#zh 计算点到直线的距离。如果这是一条线段并且垂足不在线段内,则会计算点到线段端点的距离。
|
||||
* @method pointLineDistance
|
||||
* @param {Vec2} point - The point
|
||||
* @param {Vec2} start - The start point of line
|
||||
* @param {Vec2} end - The end point of line
|
||||
* @param {boolean} isSegment - whether this line is a segment
|
||||
* @return {number}
|
||||
*/
|
||||
function pointLineDistance(point, start, end, isSegment) {
|
||||
var dx = end.x - start.x;
|
||||
var dy = end.y - start.y;
|
||||
var d = dx*dx + dy*dy;
|
||||
var t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / d;
|
||||
var p;
|
||||
|
||||
if (!isSegment) {
|
||||
p = cc.v2(start.x + t * dx, start.y + t * dy);
|
||||
}
|
||||
else {
|
||||
if (d) {
|
||||
if (t < 0) p = start;
|
||||
else if (t > 1) p = end;
|
||||
else p = cc.v2(start.x + t * dx, start.y + t * dy);
|
||||
}
|
||||
else {
|
||||
p = start;
|
||||
}
|
||||
}
|
||||
|
||||
dx = point.x - p.x;
|
||||
dy = point.y - p.y;
|
||||
return Math.sqrt(dx*dx + dy*dy);
|
||||
}
|
||||
|
||||
Intersection.pointLineDistance = pointLineDistance;
|
||||
|
||||
|
||||
cc.Intersection = module.exports = Intersection;
|
105
engine/cocos2d/core/collider/CCPolygonCollider.js
Normal file
105
engine/cocos2d/core/collider/CCPolygonCollider.js
Normal file
@@ -0,0 +1,105 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* !#en Defines a Polygon Collider .
|
||||
* !#zh 用来定义多边形碰撞体
|
||||
* @class Collider.Polygon
|
||||
*/
|
||||
cc.Collider.Polygon = cc.Class({
|
||||
properties: {
|
||||
threshold: {
|
||||
default: 1,
|
||||
serializable: false,
|
||||
visible: false
|
||||
},
|
||||
|
||||
_offset: cc.v2(0, 0),
|
||||
|
||||
/**
|
||||
* !#en Position offset
|
||||
* !#zh 位置偏移量
|
||||
* @property offset
|
||||
* @type {Vec2}
|
||||
*/
|
||||
offset: {
|
||||
get: function () {
|
||||
return this._offset;
|
||||
},
|
||||
set: function (value) {
|
||||
this._offset = value;
|
||||
},
|
||||
type: cc.Vec2
|
||||
},
|
||||
|
||||
/**
|
||||
* !#en Polygon points
|
||||
* !#zh 多边形顶点数组
|
||||
* @property points
|
||||
* @type {Vec2[]}
|
||||
*/
|
||||
points: {
|
||||
tooltip: CC_DEV && 'i18n:COMPONENT.physics.physics_collider.points',
|
||||
default: function () {
|
||||
return [cc.v2(-50,-50), cc.v2(50, -50), cc.v2(50,50), cc.v2(-50,50)];
|
||||
},
|
||||
type: [cc.Vec2]
|
||||
}
|
||||
},
|
||||
|
||||
resetPointsByContour: CC_EDITOR && function () {
|
||||
var PhysicsUtils = Editor.require('scene://utils/physics');
|
||||
PhysicsUtils.resetPoints(this, {threshold: this.threshold});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* !#en Polygon Collider.
|
||||
* !#zh 多边形碰撞组件
|
||||
* @class PolygonCollider
|
||||
* @extends Collider
|
||||
* @uses Collider.Polygon
|
||||
*/
|
||||
/**
|
||||
* !#en
|
||||
* Collider info in world coordinate.
|
||||
* !#zh
|
||||
* 碰撞体的世界坐标系下的信息。
|
||||
* @property {ColliderInfo} world
|
||||
*/
|
||||
var PolygonCollider = cc.Class({
|
||||
name: 'cc.PolygonCollider',
|
||||
extends: cc.Collider,
|
||||
mixins: [cc.Collider.Polygon],
|
||||
|
||||
editor: CC_EDITOR && {
|
||||
menu: 'i18n:MAIN_MENU.component.collider/Polygon Collider',
|
||||
inspector: 'packages://inspector/inspectors/comps/physics/points-base-collider.js',
|
||||
},
|
||||
});
|
||||
|
||||
cc.PolygonCollider = module.exports = PolygonCollider;
|
31
engine/cocos2d/core/collider/index.js
Normal file
31
engine/cocos2d/core/collider/index.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
require('./CCCollisionManager');
|
||||
require('./CCCollider');
|
||||
require('./CCBoxCollider');
|
||||
require('./CCCircleCollider');
|
||||
require('./CCPolygonCollider');
|
Reference in New Issue
Block a user