0

I have created a Sphere and a Wall and added it to the physics engine. The Sphere was is also given a starting velocity.

I then created a circle and wall Node, added DOMElement components, and set some dimensions and color.

During the update loop, the Nodes sync their position with their physical counterparts -- Sphere and Wall.

I expected the sphere to collide with the wall, but the animation shows that the Sphere simply continues through the wall. I'm wondering what is wrong with my code that this is occurring.

'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();
louis w
  • 117
  • 1
  • 1
  • 9

1 Answers1

1

Constraints are needed to apply to the Wall and the Sphere. In this case, you can use Collision

var Collision = physics.Collision;

Replace

rightWall.setPosition(500, 0, 0);

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

With

rightWall.setPosition(500, 0, 0);

simulation.addBody(mySphere);

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

Also, fix mount point of circle to the center

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

Bonus: Add Left Wall to keep the particle on the screen

// 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);

Example Working Snippet

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>
talves
  • 13,993
  • 5
  • 40
  • 63