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
不过会导致无法原地连续跳跃。
还是希望有大佬来提供一个更好的解决思路
我今天也遇到这个问题了,233