【问题标题】:Famo.us - Balls bouncing each otherFamo.us - 球互相弹跳
【发布时间】:2014-07-03 04:51:11
【问题描述】:

我是“物理引擎世界”的新手。我决定使用 Famo.us 进行实验并尝试学习如何使用物理引擎。

如何让球在相互撞击时反弹?我设法添加了球并创建了墙壁。球撞击墙壁时会反弹,但相互撞击时不会反弹,它们只是穿过。我一直在尝试我能找到的任何东西,但不幸的是,缺乏关于 famo.us 文档的信息对我来说有点障碍(因为我仍在学习这些概念)。

另一个我在实践中不太明白的概念是如何为球添加重力。

这就是我想要实现的目标:http://mrdoob.com/projects/chromeexperiments/ball-pool/

这是我目前的代码:

define(function(require, exports, module) {
    var Engine          = require('famous/core/Engine');
    var Surface         = require('famous/core/Surface');
    var ContainerSurface         = require('famous/surfaces/ContainerSurface');
    var EventHandler    = require('famous/core/EventHandler');
    var View            = require('famous/core/View');
    var Transform       = require('famous/core/Transform');

    var StateModifier   = require('famous/modifiers/StateModifier');

    var PhysicsEngine   = require('famous/physics/PhysicsEngine');
    var Body            = require('famous/physics/bodies/Body');
    var Circle          = require('famous/physics/bodies/Circle');
    var Wall            = require('famous/physics/constraints/Wall');
    var Vector          = require('famous/math/Vector');

    var Collision       = require('famous/physics/constraints/Collision');


    var context = Engine.createContext();

    var contextSize;

    var mainSurface = new ContainerSurface ({
        size: [undefined,undefined],
        properties: {
            backgroundColor: '#dddddd'
        }
    });

    mainSurface.on("click",function(){
        addNewBall(1);
        setWalls();
    });


    var handler = new EventHandler();

    var physicsEngine = new PhysicsEngine();

    var balls = [];
    var collision = new Collision();
    function addNewBall(number){
        if(number == undefined) var number = 1;
        for(var i=0; i<number; i++){
            var index = balls.length;
            balls[index] = new Surface ({
              size: [50,50],
              properties: {
                backgroundColor: 'red',
                borderRadius: '50px'
              }
            })

            balls[index].state = new StateModifier({origin:[0.5,0.5]});

            balls[index].particle = new Circle({radius:25});

            //Attempting to add collision
            physicsEngine.attach( collision,  [balls[index]]);

            balls[index].particle.applyForce(new Vector(Math.random(), 1, 0));

            physicsEngine.addBody(balls[index].particle);


            mainSurface.add(balls[index].state).add(balls[index]);
        }
    }

    context.add(mainSurface);
    addNewBall(1);

    //Function to loop through all balls and set the walls
    function setWalls() {
        contextSize = context.getSize();
        var leftWall    = new Wall({normal : [1,0,0],  distance : contextSize[0]/2.0, restitution : .5});
        var rightWall   = new Wall({normal : [-1,0,0], distance : contextSize[0]/2.0, restitution : .5});
        var topWall     = new Wall({normal : [0,1,0],  distance : contextSize[1]/2.0, restitution : .5});
        var bottomWall  = new Wall({normal : [0,-1,0], distance : contextSize[1]/2.0, restitution : .5});

        for(var i=0; i < balls.length; i++){
            physicsEngine.attach( leftWall,  [balls[i].particle]);
            physicsEngine.attach( rightWall, [balls[i].particle]);
            physicsEngine.attach( topWall,   [balls[i].particle]);
            physicsEngine.attach( bottomWall,[balls[i].particle]);
        }
    }


    Engine.nextTick(setWalls);
    Engine.on('resize',setWalls);

    Engine.on('prerender', function(){
        for(var i=0; i < balls.length; i++){
            balls[i].state.setTransform(balls[i].particle.getTransform())
        }
    });
});

【问题讨论】:

  • 你弄明白了吗?我无法使用此处的答案在您的示例中添加碰撞...很想看看您是如何做到的。可以分享一下源码吗?

标签: famo.us


【解决方案1】:

问题出在这一行:

physicsEngine.attach( collision,  [balls[index]]);

.attach 方法采用物理代理 (Collision)、目标数组 (balls) 和 [可选] 源。由于碰撞发生在两个球之间,因此您需要定义碰撞源。同样,您可以在两个粒子之间连接SpringRepulsionDragGravity 等不需要这个。

要定义所有粒子对之间的碰撞,您可以:

for (var i = 0; i < balls.length; i++) {
    physicsEngine.attach(collision, balls, balls[i]);
}

等效地(认为不太理想),您可以使用双 for 循环来明确

for (var i = 0; i < balls.length; i++) {
    for (var j = 0; j < balls.length; j++) {
        if (i !== j) physicsEngine.attach(collision, balls[j], balls[i]);
    }
}

【讨论】:

  • 感谢您的帮助@dmvaldman。它现在工作正常。那是我不太明白的部分。我仍然需要解决重力问题......我在互联网上找到了一个有效的示例(hbsand.com/HappyBoxes),但我无法在我自己的代码上实现它。我一定是错过了什么……但我还没有放弃。我会继续调查。 :)
【解决方案2】:

团队doob?出名了:)

检查您的演示,您似乎现在可以使用它,并且 DMV 还指出了具体细节。但就像另一种方法一样......我将一个演示放在一起(在黑客马拉松中的名人帮助),球相互反弹,墙壁等。

http://famfiziks.meteor.com/battle

来源在这里: https://github.com/dcsan/fambot

【讨论】:

    猜你喜欢
    • 2013-05-23
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 2013-10-28
    • 2020-07-12
    相关资源
    最近更新 更多