0

based on how to add walls to a famo.us physics simulation? there is a ball that will bounce off of walls

How do you go about adding a repulsion to the particle so that it will never hit the walls?

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 Repulsion       = require('famous/physics/forces/Repulsion');

module.exports = function () {

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

    var replusion = new Repulsion();
    ball.particle.applyForce(replusion);

    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 : contextSize[0]/2.0, restitution : 0.5});
    var rightWall   = new Wall({normal : [-1,0,0], distance : contextSize[0]/2.0, restitution : 0.5});
    var topWall     = new Wall({normal : [0,1,0],  distance : contextSize[1]/2.0, restitution : 0.5});
    var bottomWall  = new Wall({normal : [0,-1,0], distance : contextSize[1]/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())
    });
};

My first thought is to add repulsion to the ball's particle, but that doesn't seem to be working.

Has anyone done this or is there good documentation for this type of behavior?

Community
  • 1
  • 1
Dan Baker
  • 1,757
  • 3
  • 21
  • 36

1 Answers1

0

I've played around and I think I have a somewhat better idea now.

This code with two balls (particles) in the same physics engine will repel ( one will chase the other around )

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.4,0.3]});

ball.particle = new Circle({radius:100});

var ball2 = new Surface ({
  size: [200,200],
  properties: {
    backgroundColor: 'green',
    borderRadius: '100px'
  }
})

ball2.state = new StateModifier({origin:[0.3,0.3]});

ball2.particle = new Circle({radius:100});

var leftWall    = new Wall({normal : [1,0,0],  distance : contextSize[0]/4.0, restitution : 0.3});
var rightWall   = new Wall({normal : [-1,0,0], distance : contextSize[0]/4.0, restitution : 0.3});
var topWall     = new Wall({normal : [0,1,0],  distance : contextSize[1]/4.0, restitution : 0.3});
var bottomWall  = new Wall({normal : [0,-1,0], distance : contextSize[1]/4.0, restitution : 0.3});

physicsEngine.attach( leftWall,  [ball.particle, ball2.particle]);
physicsEngine.attach( rightWall, [ball.particle, ball2.particle]);
physicsEngine.attach( topWall,   [ball.particle, ball2.particle]);
physicsEngine.attach( bottomWall,[ball.particle, ball2.particle]);

physicsEngine.addBody(ball.particle); 

physicsEngine.addBody(ball2.particle);

The repulsion has to be added to the PE with a target and source, both of which must already exist in the engine.

var replusion = new Repulsion({strength: 90});
physicsEngine.attach(replusion, [ball2.particle], ball.particle);

ball.on("click",function(){
  ball.particle.setVelocity([1,0,0]);
});


ball2.on("click",function(){
  ball2.particle.setVelocity([1,1,0]);
});

context.add(ball.state).add(ball)
context.add(ball2.state).add(ball2)

Engine.on('prerender', function(){
  ball.state.setTransform(ball.particle.getTransform())
  ball2.state.setTransform(ball2.particle.getTransform())
});
Dan Baker
  • 1,757
  • 3
  • 21
  • 36
  • 2
    You can also use the Circle as a modifier without the `'prerender'` event updating the positions. `context.add(ball.particle).add(ball)` – BlinkyTop Aug 07 '14 at 19:48