creator v2.4.6
文件: assets/cases/Collider/Platform/HeroControl.js
疑问: 看不懂 onCollisionEnter里面的 2nd step 3rd step
示例运行界面:
cc.Class({
extends: cc.Component,
properties: {
speed: cc.v2(0, 0),// 当前速度
maxSpeed: cc.v2(2000, 2000),// 最大限速
gravity: -1000,// 模拟重力加速度
drag: 1000,// 模拟水平阻力加速度
direction: 0,// 左右方向 -1 0 1
jumpSpeed: 300,// 起跳速度
_lastSpeedY: 0,//上一帧的速度
},
// use this for initialization
onLoad: function () {
//add keyboard input listener to call turnLeft and turnRight
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyPressed, this);
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyReleased, this);
this.collisionX = 0;
this.collisionY = 0;
this.jumping = true;
this.prePosition = cc.v2();
this.preStep = cc.v2();
this.touchingNumber = 0;
},
onEnable: function () {
cc.director.getCollisionManager().enabled = true;
cc.director.getCollisionManager().enabledDebugDraw = true;
},
onDisable: function () {
cc.director.getCollisionManager().enabled = false;
cc.director.getCollisionManager().enabledDebugDraw = false;
},
onKeyPressed: function (event) {
let keyCode = event.keyCode;
switch (keyCode) {
case cc.macro.KEY.a:
case cc.macro.KEY.left:
this.direction = -1;
break;
case cc.macro.KEY.d:
case cc.macro.KEY.right:
this.direction = 1;
break;
case cc.macro.KEY.w:
case cc.macro.KEY.up:
if (!this.jumping) {
this.jumping = true;
this.speed.y = this.jumpSpeed > this.maxSpeed.y ? this.maxSpeed.y : this.jumpSpeed;
this._lastSpeedY = this.jumpSpeed > this.maxSpeed.y ? this.maxSpeed.y : this.jumpSpeed;
}
break;
}
},
onKeyReleased: function (event) {
let keyCode = event.keyCode;
switch (keyCode) {
case cc.macro.KEY.a:
case cc.macro.KEY.left:
case cc.macro.KEY.d:
case cc.macro.KEY.right:
this.direction = 0;
break;
}
},
onCollisionEnter: function (other, self) {
this.node.color = cc.Color.RED;
this.touchingNumber++;
// 1st step
// get pre aabb, go back before collision
var otherAabb = other.world.aabb;
var otherPreAabb = other.world.preAabb.clone();
var selfAabb = self.world.aabb;
var selfPreAabb = self.world.preAabb.clone();
// 2nd step
// forward x-axis, check whether collision on x-axis
// 正向x轴,检查x轴上是否有碰撞
selfPreAabb.x = selfAabb.x;
otherPreAabb.x = otherAabb.x;
if (cc.Intersection.rectRect(selfPreAabb, otherPreAabb)) {
if (this.speed.x < 0 && (selfPreAabb.xMax > otherPreAabb.xMax)) {
this.node.x = otherPreAabb.xMax - this.node.parent.x;
this.collisionX = -1;
}
else if (this.speed.x > 0 && (selfPreAabb.xMin < otherPreAabb.xMin)) {
this.node.x = otherPreAabb.xMin - selfPreAabb.width - this.node.parent.x;
this.collisionX = 1;
}
this.speed.x = 0;
other.touchingX = true;
return;
}
// 3rd step
// forward y-axis, check whether collision on y-axis
// 正向y轴,检查y轴上是否有碰撞
selfPreAabb.y = selfAabb.y;
otherPreAabb.y = otherAabb.y;
if (cc.Intersection.rectRect(selfPreAabb, otherPreAabb)) {
if (this.speed.y < 0 && (selfPreAabb.yMax > otherPreAabb.yMax)) {
this.node.y = otherPreAabb.yMax - this.node.parent.y;
this.jumping = false;
this.collisionY = -1;
}
else if (this.speed.y > 0 && (selfPreAabb.yMin < otherPreAabb.yMin)) {
this.node.y = otherPreAabb.yMin - selfPreAabb.height - this.node.parent.y;
this.collisionY = 1;
}
this.speed.y = 0;
this._lastSpeedY = 0;
other.touchingY = true;
}
},
onCollisionStay: function (other, self) {
if (this.collisionY === -1) {
if (other.node.group === 'Platform') {
var motion = other.node.getComponent('PlatformMotion');
if (motion) {
this.node.x += motion._movedDiff;// 跟移动的平台保持相对静止
}
}
// this.node.y = other.world.aabb.yMax;
// var offset = cc.v2(other.world.aabb.x - other.world.preAabb.x, 0);
// var temp = cc.affineTransformClone(self.world.transform);
// temp.tx = temp.ty = 0;
// offset = cc.pointApplyAffineTransform(offset, temp);
// this.node.x += offset.x;
}
},
onCollisionExit: function (other) {
this.touchingNumber--;
if (this.touchingNumber === 0) {
this.node.color = cc.Color.WHITE;
}
if (other.touchingX) {
this.collisionX = 0;
other.touchingX = false;
}
else if (other.touchingY) {
other.touchingY = false;
this.collisionY = 0;
this.jumping = true;
}
},
update: function (dt) {
if (this.jumping) {
this.speed.y += this.gravity * dt;
if (Math.abs(this.speed.y) > this.maxSpeed.y) {
this.speed.y = this.speed.y > 0 ? this.maxSpeed.y : -this.maxSpeed.y;
}
}
if (this.direction === 0) {
if (this.speed.x > 0) {
this.speed.x -= this.drag * dt;
if (this.speed.x <= 0) this.speed.x = 0;
}
else if (this.speed.x < 0) {
this.speed.x += this.drag * dt;
if (this.speed.x >= 0) this.speed.x = 0;
}
}
else {
this.speed.x += (this.direction > 0 ? 1 : -1) * this.drag * dt;
if (Math.abs(this.speed.x) > this.maxSpeed.x) {
this.speed.x = this.speed.x > 0 ? this.maxSpeed.x : -this.maxSpeed.x;
}
}
if (this.speed.x * this.collisionX > 0) {
this.speed.x = 0;
}
this.prePosition.x = this.node.x;
this.prePosition.y = this.node.y;
this.preStep.x = this.speed.x * dt;
this.preStep.y = this.speed.y * dt;
this.node.x += this.speed.x * dt;
if (this._lastSpeedY === 0 || this.speed.y === 0 || this._lastSpeedY / Math.abs(this._lastSpeedY) === this.speed.y / Math.abs(this.speed.y)) {
// 起点、顶点、落点、同向
this.node.y += (this._lastSpeedY + this.speed.y) * dt / 2;
// s = (vt + v0) * t / 2
}
else {
// 异向的
this.node.y += - this._lastSpeedY / this.gravity / 2 * this._lastSpeedY + this.speed.y / this.gravity / 2 * this.speed.y;
// s = (v1^2 - v0^2)/(2*a)
}
this._lastSpeedY = this.speed.y;
},
});


,我是这个案例这块处理看不懂,不是不知道这个回调函数