拯救狗狗系列之物理推线

上篇讲述了如何结合绘制组件和物理组件,来使线条具备刚体属性。本篇将讲述如何对线添加一个方向力,以便可以将画出来的线抬起来,先看效果图:

去掉上方方块后:

原理

蜜蜂相连的两帧的的位置分别为startPos和endPos, 以startPos为起点,以endPos为终点发射一条射线

通过PhysicsSystem2D.instance.raycast接口,找出所画线与射线相交的第一个刚体

typescript 复制代码
/** 检测碰撞 */
private checkRayCast(startPos: math.IVec2Like, endPos: math.IVec2Like): boolean {
    const result = PhysicsSystem2D.instance.raycast(startPos, endPos, ERaycast2DType.Closest) as RaycastResult2D[];
    if (result.length === 0) {
        return false;
    } else {
        // 找出第一个碰撞到的刚体
        if (!this._lineRigidBody) {
            this._lineRigidBody = result[0].collider.node.getComponent(RigidBody2D);
        }
        return true;
    }
}

对检测出的刚体施加一个方向向量,通过刚体applyLinearImpulseToCenter方法,来对刚体施加方向力

typescript 复制代码
...
 _endPos: math.Vec2 = math.Vec2.ZERO;
/** 移动 */ 
public onMove(dt) {
    let dir = this._target.getPosition().subtract(this.node.getPosition()).normalize();
    const startPos = this.node.getPosition();
    this._rigidBody.linearVelocity = v2(dir.x, dir.y).multiplyScalar(this._speed);
    this._endPos.set(startPos.x + this._rigidBody.linearVelocity.x, startPos.y + this._rigidBody.linearVelocity.y);
    if (this.checkRayCast(startPos, this._endPos)) {
        // 检测到碰撞,施加力
        const forceVector = v2(dir.x * this._speed, dir.y * this._speed);
        this._lineRigidBody.applyLinearImpulseToCenter(forceVector, true);
    }
}

蜜蜂组件的完整代码如下:

typescript 复制代码
export default class Enemy extends Component {
    /** 攻击对象 */
    private _target: Node = null;
    public set target(value: Node) {
        this._target = value;        
        this.node.scale.set(this.node.getPosition().x < this._target.getPosition().x ? -0.5 : 0.5, 0.5);
    }
    public get target(): Node {
        return this._target;
    }

    /** 线刚体 */
    private _lineRigidBody: RigidBody2D = null;
    public set lineRigidBody(value: RigidBody2D) {
        this._lineRigidBody = value;
    }

    /** 速度 */
    private _speed: number = 20;
    /** 自身刚体 */
    private _rigidBody: RigidBody2D = null;

    protected onLoad(): void {
        this._rigidBody = this.node.getComponent(RigidBody2D);
    }

    /** 检测碰撞 */
    private checkRayCast(startPos: math.IVec2Like, endPos: math.IVec2Like): boolean {
        const result = PhysicsSystem2D.instance.raycast(startPos, endPos, ERaycast2DType.Closest) as RaycastResult2D[];
        if (result.length === 0) {
            return false;
        } else {
            // 找出第一个碰撞到的刚体
            if (!this._lineRigidBody) {
                this._lineRigidBody = result[0].collider.node.getComponent(RigidBody2D);
            }
            return true;
        }
    }

    _endPos: math.Vec2 = math.Vec2.ZERO;
    /** 移动 */ 
    public onMove(dt) {
        let dir = this._target.getPosition().subtract(this.node.getPosition()).normalize();
        const startPos = this.node.getPosition();
        this._rigidBody.linearVelocity = v2(dir.x, dir.y).multiplyScalar(this._speed);
        this._endPos.set(startPos.x + this._rigidBody.linearVelocity.x, startPos.y + this._rigidBody.linearVelocity.y);
        if (this.checkRayCast(startPos, this._endPos)) {
            // 检测到碰撞,施加力
            const forceVector = v2(dir.x * this._speed, dir.y * this._speed);
            this._lineRigidBody.applyLinearImpulseToCenter(forceVector, true);
        }
    }

    /** 更新 */
    public update(dt: number) {
        this.onMove(dt);
    }
}

当画完线后,直接创建蜜蜂节点,将Enemy组件挂在蜜蜂节点上,并设置攻击目标_target后,蜜蜂就会自动飞向主角,之后就可以看到开篇中蜜蜂推线或者抬线的效果。

相关推荐
成长ing1213819 天前
点击音效系统
前端·cocos creator
blakeyi22 天前
vscode保存自动刷新cocos creator编辑器
ide·vscode·cocos creator·热更新
烧仙草奶茶1 个月前
【cocos creator 3.x】3Dui创建,模型遮挡ui效果
ui·3d·cocos creator·cocos3d
糖墨夕1 个月前
【1】Coco2d creator资源管理注意事项 - meta 文件
前端·cocos creator·cocos2d-x
Setsuna_F_Seiei1 个月前
前端切图仔的一次不务正业游戏开发之旅
前端·游戏·cocos creator
jason_yang2 个月前
转眼间,已是十几年前的游戏代码了
cocos creator·游戏开发·cocos2d-x
成长ing121382 个月前
cocos creator 放大镜效果
前端·cocos creator
烧仙草奶茶3 个月前
【cocos creator】【模拟经营】餐厅经营demo
cocos creator·游戏源码·模拟经营
la_vie_est_belle4 个月前
《Cocos Creator游戏实战》非固定摇杆实现原理
游戏·cocos creator·游戏开发·cocos·非固定摇杆
布鲁克零三四四6 个月前
Cocos Creator导出obj文件用于后端寻路
cocos creator