拯救狗狗系列之物理推线

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

去掉上方方块后:

原理

蜜蜂相连的两帧的的位置分别为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后,蜜蜂就会自动飞向主角,之后就可以看到开篇中蜜蜂推线或者抬线的效果。

相关推荐
LcGero1 个月前
TypeScript 快速上手:泛型与工具类型
typescript·cocos creator·游戏开发
LcGero1 个月前
Cocos Creator 3.x 高维护性打字机对话系统设计与实现
cocos creator·打字机
LcGero1 个月前
Cocos Creator 三端接入穿山甲 SDK
sdk·cocos creator·穿山甲
LcGero1 个月前
Cocos Creator平台适配层框架设计
cocos creator·平台·框架设计
LcGero1 个月前
Cocos Creator 业务与原生通信详解
android·ios·cocos creator·游戏开发·jsb
LcGero1 个月前
TypeScript 快速上手:前言
typescript·cocos creator·游戏开发
Setsuna_F_Seiei1 个月前
CocosCreator 游戏开发 - 多维度状态机架构设计与实现
前端·cocos creator·游戏开发
CodeCaptain4 个月前
cocoscreator 2.4.x 场景运行时的JS生命周期浅析
cocos creator·开发经验
CodeCaptain4 个月前
CocosCreator 3.8.x [.gitignore]文件内容,仅供参考
经验分享·cocos creator
VaJoy5 个月前
Cocos Creator Shader 入门 (21) —— 高斯模糊的高性能实现
前端·cocos creator