求救!!两物体离开后依旧会有碰撞检测

A是一个平台,平台的 physicsPolyCollider的point是动态生成的。
B是人物,通过applyForceToCenter来进行跳跃。
但是当B在A上跳起来时,A上依旧会触发一次于B的onBeginContact。

A的脚本:
const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

// LIFE-CYCLE CALLBACKS:

// onLoad () {}

start () {

}

update(dt) {
    let array = new Array<cc.Vec2>();
    array.push(new cc.Vec2(-50, -50));
    array.push(new cc.Vec2(50, -50));
    array.push(new cc.Vec2(50, 50));
    array.push(new cc.Vec2(-50, 50));
    this.node.getComponent(cc.PhysicsPolygonCollider).points = array;
    this.node.getComponent(cc.PhysicsPolygonCollider).apply();
}

}
B人物的控制脚本:
import { GlobalEventTarget } from “./GlobalEventTarget”;
import {HERO_STATE} from “./HeroState”;
const { ccclass, property } = cc._decorator;

@ccclass
export default class HeroControl extends cc.Component {

direction: number = 0;
speedX: number = 0;
speedY: number = 0;
jumpSpeed: number = 30000;
jumping: boolean = false;
STATE: HERO_STATE = 0;
HeroAnimation = null;

lastContactPoint: cc.Vec2 = new cc.Vec2();
@property(cc.Node)
Mask: cc.Node = null;

@property(cc.Node)
man: cc.Node = null;

onLoad() {
    this.HeroAnimation = this.man.getComponent(cc.Animation);
    this.node.on("ChangeState", this.ChangeState, this);
    this.node.emit("ChangeState", HERO_STATE.STAND);
}

ChangeState(state: HERO_STATE) {
    switch(state){
        case HERO_STATE.STAND:
            this.HeroAnimation.play("stand");
            this.STATE = HERO_STATE.STAND;
            break;
        case HERO_STATE.RUN:
            this.HeroAnimation.play("run");
            this.STATE = HERO_STATE.RUN;
            break;
    }
}

start() {
    cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyPressed, this);
    cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyReleased, this);
}

onEnable() {
    cc.director.getPhysicsManager().enabled = true;
    cc.director.getCollisionManager().enabled = true;
    cc.director.getCollisionManager().enabledDebugDraw = true;
}

onDisable() {
    cc.director.getPhysicsManager().enabled = false;
    cc.director.getCollisionManager().enabled = false;
    cc.director.getCollisionManager().enabledDebugDraw = false;
}

onKeyPressed(event) {
    let keyCode = event.keyCode;
    switch (keyCode) {
        case cc.macro.KEY.a:
        case cc.macro.KEY.left:
            this.speedX = -100;
            this.man.scaleX = -1;
            // GlobalEventTarget.emit('move',this.speedX);
            if(this.STATE==HERO_STATE.RUN){
            }else{
                this.node.emit("ChangeState", HERO_STATE.RUN);
            }
            break;
        case cc.macro.KEY.d:
        case cc.macro.KEY.right:
            this.speedX = 100;
            this.man.scaleX = 1;
            // GlobalEventTarget.emit('move',this.speedX);
            if(this.STATE==HERO_STATE.RUN){
            }else{
                this.node.emit("ChangeState", HERO_STATE.RUN);
            }
            break;
        case cc.macro.KEY.w:
        case cc.macro.KEY.up:
            if (!this.jumping) {
                cc.log("jumping start");
                this.HeroAnimation.play("jumping");
                this.node.getComponent(cc.RigidBody).applyForceToCenter(cc.v2(0, this.jumpSpeed), true);
                this.jumping = true;
            }
            break;
    }
}

onKeyReleased(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.speedX = 0;
            GlobalEventTarget.emit('move', this.speedX);
            this.node.emit("ChangeState", HERO_STATE.STAND);
            break;
    }
}

onBeginContact(contact, selfCollider, otherCollider) {
    cc.log(otherCollider.node.name);
    if (this.lastContactPoint.sub(selfCollider.node.position).magSqr() < 16) {
        return;
    }
    if (contact.getWorldManifold().normal.x == 0 && contact.getWorldManifold().normal.y == -1) {
        cc.log(this.lastContactPoint.sub(selfCollider.node.position).magSqr());
        this.jumping = false;
        // let playerPos = selfCollider.node.
    }
    this.lastContactPoint = selfCollider.node.position; 
}
onEndContact() {
    // this.jumping = true;
}

update(dt) {
    this.node.x += this.speedX * dt;
}

}

暂时的解决方案是判断起跳点与contact时的点是否太近。太近则无视本次contact
不过会导致无法原地连续跳跃。
还是希望有大佬来提供一个更好的解决思路:blush:

我今天也遇到这个问题了,233