-
Notifications
You must be signed in to change notification settings - Fork 407
Fundamentals
Positive direction of:
- x: right
- y: down
- angle: clockwise
Many objects in PhysicsJS (such as bodies, behaviors, ...) follow the factory pattern in terms of creation. This involves calling an appropriate factory function with a configuration object that specifies settings for that object. The general pattern looks like this:
var instance = Physics.FACTORY('NAME', { SETTINGS });
For example, when creating a circle body, we can call the .body()
factory and specify the circle properties (x, y, velocity, radius, ...).
var ball = Physics.body('circle', {
x: 140,
y: 100,
radius: 20,
vx: 0.1
});
Factory functions can also be used to create new subtypes, and extend subtypes. To create a new subtype, a function is passed (in place of the configuration) which should return an object to mix into the base. The function will be called immediately, and passed the parent object (like "super").
To handle initialization, the mixins may include an .init()
method that will be called when the new subtype is created, and passed the configuration options for the new instance.
Physics.FACTORY('NEW_NAME', function( parent ){
// shared resources here...
return {
// optional initialization
init: function( options ){
// call parent init method
parent.init.call(this, options);
// ...
},
// mixin methods...
};
});
As an example, look at the circle body's definition.
Physics.body('circle', function( parent ){
var defaults = {
// default config options
};
return {
init: function( options ){
// call parent init method
parent.init.call(this, options);
options = Physics.util.extend({}, defaults, options);
this.geometry = Physics.geometry('circle', {
radius: options.radius
});
this.recalc();
},
recalc: function(){
parent.recalc.call(this);
// moment of inertia
this.moi = this.mass * this.geometry.radius * this.geometry.radius / 2;
}
};
});
Factory functions can be used to extend other subtypes also. This is done similarly to declaring new types, but the second argument specifies the name of the existing subtype:
Physics.FACTORY('NEW_NAME', 'PARENT_NAME', function( parent ){
// parent is of type 'PARENT_NAME'
return {
// optional initialization
init: function( options ){
// call parent init method
parent.init.call(this, options);
// ...
},
// mixin methods...
};
});
For example, suppose we want to extend the "circle" type into a "wheel" type that has a method called .spin()
that will give the object a quick spin in the clockwise direction. We could do that like this:
Physics.body('wheel', 'circle', function( parent ){
return {
// no need for an init
// spin the wheel at desired speed
spin: function( speed ){
// the wheels are spinning...
this.state.angular.vel = speed;
}
};
});
var myWheel = Physics.body('wheel', {
x: 40,
y: 340,
radius: 60
});
world.add( myWheel );
// for example, use jquery to listen for a button click, and spin the wheel on the next step
$('button').on('click', function(){
// wait for the next step before spinning the wheel
world.subscribe('step', function( data ){
myWheel.spin( 0.3 );
// only execute callback once
world.unsubscribe( 'step', data.handler );
});
});