微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Matter.JS 约束在对象旋转一定后就像弹弓一样

如何解决Matter.JS 约束在对象旋转一定后就像弹弓一样

我在使用 MatterJS 库进行简单测试时遇到问题。

我想构建一种通过设置其第一个元素的速度和角度来控制的火车(链、蛇)(请参阅下面的代码)。我希望有一些刚度和阻尼,但在应用一些旋转约束后,它开始像弹弓一样展开,然后将两个物体移动到随机方向。

这是某种浮点问题吗?我认为当前的引擎设置等没有问题。可以以某种方式处理吗?

测试片段(包含主要的 Game 类和实用的 keyboard 功能):

function keyboard(value) {
    let key = {};
    key.value = value;
    key.isDown = false;
    key.isUp = true;
    key.press = undefined;
    key.release = undefined;

    key.downHandler = event => {
        if (event.key === key.value) {
            if (key.isUp && key.press) key.press();
            key.isDown = true;
            key.isUp = false;
            event.preventDefault();
        }
    };

    key.upHandler = event => {
        if (event.key === key.value) {
            if (key.isDown && key.release) key.release();
            key.isDown = false;
            key.isUp = true;
            event.preventDefault();
        }
    };

    //Attach event listeners
    const downListener = key.downHandler.bind(key);
    const upListener = key.upHandler.bind(key);
    
    window.addEventListener(
        "keydown",downListener,false
    );
    window.addEventListener(
        "keyup",upListener,false
    );
    
    // Detach event listeners
    key.unsubscribe = () => {
        window.removeEventListener("keydown",downListener);
        window.removeEventListener("keyup",upListener);
    };
    
    return key;
}

const Engine = Matter.Engine,Render = Matter.Render,World = Matter.World,Body = Matter.Body,Bodies = Matter.Bodies,Mouse = Matter.Mouse,Runner = Matter.Runner,Composite = Matter.Composite;

class Game {
    constructor(document) {
        this.engine = Engine.create({
            gravity: {
                y: 0,}
        });

        let position = {x: 100,y: 100};
        this.createleader(position);

        position.x -= 70;
        this.createFollower(position);
        this.attachFollower();

        this.setupControls();
    
        Runner.run(this.engine);

        this.setupRender();    
    }

    createleader = (position) => {
        this.leader = Bodies.rectangle(
            0,64,{
                //restitution: 0.8,position,density: 0.1
            }
        );
        World.addBody(this.engine.world,this.leader);
    }

    createFollower = (position) => {
        this.follower = Bodies.rectangle(
            0,45,density: 0.01,} 
        );
        World.addBody(this.engine.world,this.follower);
    }

    attachFollower = () => {
        let attachTo = [{x: -30,y: -10},{x: -30,y: 10}];
        let attachableAt = [{x: 20,{x: 20,y: 10}];

        this.constraints = attachableAt.map((point,index) => {
            return Matter.Constraint.create({
                bodyA: this.leader,pointA: attachTo[index],bodyB: this.follower,pointB: point,//length: 20,stiffness: 0.01,damping: 0.1
            });
        });
        Composite.add(this.engine.world,[this.leader,this.follower,...this.constraints]);
    }

    setupControls = () => {
        this.right = keyboard('d');

        requestAnimationFrame(this.update);
    }

    setupRender = () => {
        var render = Render.create({
            element: document.body,engine: this.engine,options: {
                width: window.innerWidth,height: window.innerHeight,showAngleIndicator: true,wireframes: true,wireframeBackground: '#000000',showBounds: true,}
        });

        Render.run(render);
    } 

    update = () => {
        if(this.right.isDown) {
            this.leader.angle += 0.001;
        }

        requestAnimationFrame(this.update);
    }
}

function onLoad() {
    game = new Game(document);
}
onLoad();
* {
  padding: 0;
  margin: 0
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script>

重现问题的步骤:

  1. 运行代码
  2. 按住“D”键旋转对象约。 300 度。
  3. 释放“D”键

结果:两个物体都飞走了

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。