Skip to content
This repository has been archived by the owner on Dec 15, 2019. It is now read-only.

Fundamentals

Jasper edited this page Sep 4, 2013 · 9 revisions

Coordinates and Directionality

Positive direction of:

  • x: right
  • y: down
  • angle: clockwise

The Factory Pattern

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

Creating new subtypes

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

Extending subtypes

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

See this example on jsFiddle.

Clone this wiki locally