【问题标题】:How to bounce a sphere off of a wall in Famous Engine?如何在 Famous Engine 中将球体从墙上反弹?
【发布时间】:2015-07-10 08:28:55
【问题描述】:

我创建了一个球体和一个墙并将其添加到物理引擎中。 Sphere 也被赋予了起始速度。

然后我创建了一个圆形和墙壁节点,添加了 DOMElement 组件,并设置了一些尺寸和颜色。

在更新循环期间,节点将它们的位置与其物理对应物——球体和墙同步。

我预计球体会与墙壁发生碰撞,但动画显示球体只是继续穿过墙壁。我想知道发生这种情况的代码有什么问题。

'use strict';

var famous = require('famous');
var DOMElement = famous.domRenderables.DOMElement;
var FamousEngine = famous.core.FamousEngine;
var Node = famous.core.Node;
var math = famous.math;
var physics = famous.physics;
var Particle = physics.Particle;
var Sphere = physics.Sphere;
var Vec3 = math.Vec3;
var Box = physics.Box;
var Wall = physics.Wall;

// Create Simulation.
var simulation = new physics.PhysicsEngine();

// Create Scene.
var scene = FamousEngine.createScene();

/***************************************
 * Add Bodies
 ***************************************/

// Create Sphere.
var mySphere = new Sphere({ mass: 10, radius: 50 });

// Give the sphere some velocity.
mySphere.setVelocity(100, 0)
    .setPosition(0, 250, 0);

// Create Wall.
var rightWall = new Wall({ 
    direction: Wall.LEFT,
    size: [10, 500, 100]
});

rightWall.setPosition(500, 0, 0);

simulation.addBody(rightWall);
simulation.addBody(mySphere);

/***************************************
 * Add Nodes + Components
 ***************************************/

// Create circleNode, which updates its position based on mySphere's position.
var circleNode = scene.addChild();

circleNode
    .setSizeMode('absolute', 'absolute', 'absolute')
    // Match size of sphere
    .setAbsoluteSize(100, 100)
    .setPosition(0, 250, 0)
    .setMountPoint(0, 0);

// Add DOMElement component to circleNode.
var circleDOMElement = new DOMElement(circleNode, { tagName: 'div' })
    .setProperty('background-color', 'pink')
    .setProperty('border-radius', '50px');

// Create a wallNode, which will update its position based on rightWall's position.
var wallNode = scene.addChild();

wallNode
    .setSizeMode('absolute', 'absolute', 'absolute')
    .setAbsoluteSize(10, 500, 100);

var wallDOMElement = new DOMElement(wallNode, { tagName: 'div' })
    .setProperty('background-color', 'lightblue');

/***************************************
 * Create an Update Loop
 ***************************************/

var updateLoop = scene.addComponent({
    onUpdate: function (time) {
        // During update, sync cirlceNode position with sphere,
        // and wallNode position with wall.
        var spherePosition = mySphere.getPosition();
        var wallPosition = rightWall.getPosition();

        circleNode.setPosition(spherePosition.x, spherePosition.y);
        wallNode.setPosition(wallPosition.x, wallPosition.y);

        simulation.update(time);

        scene.requestUpdateOnNextTick(updateLoop);
    }
});

// Kick off loop.
scene.requestUpdate(updateLoop);
FamousEngine.init();

【问题讨论】:

    标签: famous-engine


    【解决方案1】:

    需要对 Wall 和 Sphere 应用约束。在这种情况下,您可以使用Collision

    var Collision = physics.Collision;
    

    替换

    rightWall.setPosition(500, 0, 0);
    
    simulation.addBody(rightWall);
    simulation.addBody(mySphere);
    

    rightWall.setPosition(500, 0, 0);
    
    simulation.addBody(mySphere);
    
    var collision = new Collision([mySphere,rightWall]);
    simulation.addConstraint(collision);
    

    另外,将圆的安装点固定在中心

    circleNode
      .setSizeMode('absolute', 'absolute', 'absolute')
      // Match size of sphere
      .setAbsoluteSize(100, 100)
      .setPosition(0, 250, 0)
      .setMountPoint(0.5, 0.5);
    

    奖励:添加左墙以保持粒子在屏幕上

    // Create Walls.
    var rightWall = new Wall({ 
      direction: Wall.LEFT
    });
    var leftWall = new Wall({ 
      direction: Wall.RIGHT
    });
    
    leftWall.setPosition(0, 0, 0);
    rightWall.setPosition(500, 0, 0);
    
    simulation.addBody(mySphere);
    var collision = new Collision([mySphere,rightWall,leftWall]);
    simulation.addConstraint(collision);
    

    示例工作片段

    var FamousEngine = famous.core.FamousEngine;
    var DOMElement = famous.domRenderables.DOMElement;
    var Node = famous.core.Node;
    var math = famous.math;
    var physics = famous.physics;
    var Sphere = physics.Sphere;
    var Wall = physics.Wall;
    var Collision = physics.Collision;
    
    // Create Scene.
    var scene = FamousEngine.createScene();
    var rootNode = scene.addChild();
    
    // Create Simulation.
    var simulation = new physics.PhysicsEngine();
    
    
    /***************************************
     * Add Bodies
     ***************************************/
    
    // Create Sphere.
    var mySphere = new Sphere({
      mass: 100,
      radius: 50
    });
    
    // Give the sphere some velocity.
    mySphere.setVelocity(500, 0)
      .setPosition(0, 70, 0);
    
    // Create Wall.
    var rightWall = new Wall({
      direction: Wall.LEFT
    });
    var leftWall = new Wall({
      direction: Wall.RIGHT
    });
    
    leftWall.setPosition(0, 0, 0);
    rightWall.setPosition(300, 0, 0);
    
    //simulation.addBody(rightWall);
    simulation.addBody(mySphere);
    var collision = new Collision([mySphere, rightWall, leftWall]);
    simulation.addConstraint(collision);
    
    /***************************************
     * Add Nodes + Components
     ***************************************/
    
    // Create circleNode, which updates its position based on mySphere's position.
    var circleNode = scene.addChild();
    
    circleNode
      .setSizeMode('absolute', 'absolute', 'absolute')
      // Match size of sphere
      .setAbsoluteSize(100, 100)
      .setPosition(0, 70, 0)
      .setMountPoint(0.5, 0.5);
    circleNode.addUIEvent('click');
    circleNode.addComponent({
      onReceive: function(type, event) {
        if (type === 'click') {
          console.log('setting velocity');
          mySphere.setVelocity(1000, 0);
        }
      },
    });
    
    // Add DOMElement component to circleNode.
    var circleDOMElement = new DOMElement(circleNode, {
        tagName: 'div'
      })
      .setProperty('background-color', 'lightblue')
      .setProperty('text-align', 'center')
      .setProperty('line-height', '100px')
      .setProperty('border-radius', '50px');
    circleDOMElement.setContent('click');
    // Create a wallNode, which will update its position based on rightWall's position.
    var wallNode = scene.addChild();
    
    wallNode
      .setSizeMode('absolute', 'absolute', 'absolute')
      .setAbsoluteSize(10, 130, 0);
    
    var wallDOMElement = new DOMElement(wallNode, {
        tagName: 'div'
      })
      .setProperty('background-color', 'lightblue');
    
    /***************************************
     * Create an Update Loop
     ***************************************/
    var updateLoop = rootNode.addComponent({
      onUpdate: function(time) {
        // During update, sync cirlceNode position with sphere,
        // and wallNode position with wall.
        var spherePosition = mySphere.getPosition();
        var wallPosition = rightWall.getPosition();
    
        circleNode.setPosition(spherePosition.x, spherePosition.y);
        wallNode.setPosition(wallPosition.x, wallPosition.y);
    
        simulation.update(time);
    
        rootNode.requestUpdateOnNextTick(updateLoop);
      }
    });
    
    // Kick off loop.
    rootNode.requestUpdate(updateLoop);
    FamousEngine.init();
                html,
                body {
                  width: 100%;
                  height: 100%;
                  margin: 0px;
                  padding: 0px;
                }
                body {
                  position: absolute;
                  -webkit-transform-style: preserve-3d;
                  transform-style: preserve-3d;
                  -webkit-font-smoothing: antialiased;
                  -webkit-tap-highlight-color: transparent;
                  background-color: black;
                  -webkit-perspective: 0;
                  perspective: none;
                  overflow: hidden;
                }
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <title>Physics Famous0.6.2</title>
      <link rel="icon" href="favicon.ico?v=1" type="image/x-icon">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <script src="http://code.famo.us/famous/0.6.2/famous.min.js"></script>
      <style>
      </style>
    </head>
    
    <body>
    </body>
    
    </html>

    【讨论】:

    • 使用碰撞很有意义。
    猜你喜欢
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    相关资源
    最近更新 更多