【问题标题】:how to add walls to a famo.us physics simulation?如何在 famo.us 物理模拟中添加墙壁?
【发布时间】:2014-06-28 12:50:12
【问题描述】:

我有一个带有一些弹跳球的简单物理模拟。 我正在尝试添加“墙”的边界框,但遇到了问题。

任何例子都会很棒:) 同时

查看酷炫的 ascii 艺术文档here

 *    (wall)
 *      |
 *      | (normal)     (origin)
 *      | --->            *
 *      |
 *      |    (distance)
 *      ...................
 *            (100px)
 *
 *      e.g., Wall({normal : [1,0,0], distance : 100})

我的猜测是加一堵墙

@walls.push = new Wall({normal : [1,0,0], distance : 5})

应该是距离原点仅 5 个像素的墙。

我的问题是: - 我们如何设置物理引擎的原点? 我没有看到源属性here in the PhysicsEngine 我应该给它附加一个修饰符吗?

  • 引擎坐标是否在 0~1 范围内?即0.5?还是屏幕像素?

  • 由于墙只需要一个距离(实际上就像一个半径),并且方向由法线设置,它们是否总是面向原点向内? 即不能有一面朝外的墙?

  • 默认墙() 查看源代码,这应该会创建一个视口大小的边界框,但似乎不起作用...

  • Here's a public repo 到目前为止的代码/演示

  • here's a running demo没有墙:(

【问题讨论】:

    标签: meteor famo.us


    【解决方案1】:

    物理引擎默认以原点为中心,并且必须使用上下文大小相对于中心定义墙壁。我没有尝试更改 PhysicsEngine 本身的起源,但无论如何它只是相对于表面上的修改器。

    这是一个工作墙的例子.. 只需点击球给它一些初始速度!

    希望你能从这个例子中得到一些帮助!

    祝你好运!

    var Engine          = require('famous/core/Engine');
    var Surface         = require('famous/core/Surface');
    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 context = Engine.createContext();
    
    var handler = new EventHandler();
    
    var physicsEngine = new PhysicsEngine();
    
    var ball = new Surface ({
      size: [200,200],
      properties: {
        backgroundColor: 'red',
        borderRadius: '100px'
      }
    })
    
    ball.state = new StateModifier({origin:[0.5,0.5]});
    
    ball.particle = new Circle({radius:100});
    
    physicsEngine.addBody(ball.particle);
    
    ball.on("click",function(){
      ball.particle.setVelocity([1,1,0]);
    });
    
    context.add(ball.state).add(ball)
    
    var leftWall    = new Wall({normal : [1,0,0],  distance : window.innerWidth/2.0, restitution : 0.5});
    var rightWall   = new Wall({normal : [-1,0,0], distance : window.innerWidth/2.0, restitution : 0.5});
    var topWall     = new Wall({normal : [0,1,0],  distance : window.innerHeight/2.0, restitution : 0.5});
    var bottomWall  = new Wall({normal : [0,-1,0], distance : window.innerHeight/2.0, restitution : 0.5});
    
    physicsEngine.attach( leftWall,  [ball.particle]);
    physicsEngine.attach( rightWall, [ball.particle]);
    physicsEngine.attach( topWall,   [ball.particle]);
    physicsEngine.attach( bottomWall,[ball.particle]);
    
    Engine.on('prerender', function(){
      ball.state.setTransform(ball.particle.getTransform())
    });
    

    【讨论】:

    • 现在似乎运行良好!我们在流星中的物理类包含方面遇到了一些问题,但它得到了解决。
    【解决方案2】:

    我在上面找到了 johntraver 的答案,它回答了我所有的问题:实现物理引擎。一个小问题是它对我不起作用(0.2.0)。这是因为 contextSize 被设置为 [0,0],所以所有的墙都位于屏幕的中心。这导致我将墙设置变成一个函数并使用 Engine.nextTick() 调用它。这样,当墙壁就位时,上下文就具有大小。然后只是为了踢球,我在 Engine resize 上添加了对同一函数的另一个调用。这还要求在重新创建之前将墙壁分离,以避免创建无限数量的墙壁,而这些墙壁只会变得更小。

    这是我对上述答案的调整:

    /* globals define */
    define(function(require, exports, module) {
        'use strict';
        // import dependencies
    var Engine          = require('famous/core/Engine');
    var Surface         = require('famous/core/Surface');
    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');
    
    
        function wallBounce() {
            var context = Engine.createContext();
    
            var contextSize;// = context.getSize();
    
            var handler = new EventHandler();
    
            var physicsEngine = new PhysicsEngine();
    
            var ball = new Surface ({
              size: [200,200],
              properties: {
                backgroundColor: 'red',
                borderRadius: '100px'
              }
            })
    
            ball.state = new StateModifier({origin:[0.5,0.5]});
    
            ball.particle = new Circle({radius:100});
    
            physicsEngine.addBody(ball.particle);
    
            ball.on("click",function(){
              ball.particle.setVelocity([.1,.13,0]);
            });
    
            context.add(ball.state).add(ball);
            function setWalls() {
                //console.log(contextSize[0]);
                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});
    
                physicsEngine.detachAll();
                physicsEngine.attach( leftWall,  [ball.particle]);
                physicsEngine.attach( rightWall, [ball.particle]);
                physicsEngine.attach( topWall,   [ball.particle]);
                physicsEngine.attach( bottomWall,[ball.particle]);
            };
            Engine.nextTick(setWalls);
            Engine.on('resize',setWalls);
    
            Engine.on('prerender', function(){
              ball.state.setTransform(ball.particle.getTransform())
            });
        };
    
        new wallBounce();
    
    });
    

    【讨论】:

    • 感谢您添加更新。自fam1.0以来我没有看过物理代码。 FWIW 在场景渲染之前获取对象大小的问题也由 John 在此处 stackoverflow.com/questions/23319496/… 解决
    • 谢谢 Rich,我实际上只是看到尝试做另一个例子,更简单的修复就是做 window.innerWidth 和 window.innerHeight
    猜你喜欢
    • 1970-01-01
    • 2012-02-06
    • 2023-03-22
    • 2018-04-10
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多