Coder Social home page Coder Social logo

chipmunk-js's Introduction

Chipmunk for Javascript!

This is a port of the Chipmunk Physics library to Javascript!

Check out the sexy demos! (Surprisingly, works best in Safari)

Caveats

  • It is slower than the C version (duh, its in javascript). Specifically, physics simulations using chipmunk-js runs about 3 times slower than the C equivalent.
  • I haven't implemented chipmunk's spatial hash, and I have no intention to do so.
  • The feature set is lagged a little from the real Chipmunk library. Chipmunk-js currently corresponds to Chipmunk 6.1.1 published in August 2012.

Usage

The API for Chipmunk-js is almost identical to chipmunk-physics. Except:

  • The cp prefix has been replaced by a cp namespace. (Eg, cpvadd(a, b) becomes cp.vadd(a, b).)
  • Most functions are wrapped by their containing objects
  • Some functions took an array-and-length. Arrays are now all simply javascript arrays, and the length argument has been removed. Eg:
cpMomentForPoly(mass, numVerts, *verts, offset);

becomes:

cp.momentForPoly(mass, verts, offset);
  • Lots of trivial getters and setters have been removed.
  • Lists of verticies are described using a flattened JS array of [x1,y1, x2,y2, ...] instead of an array of objects. For example, use [0,0, 0,1, 1,1, 1,0] instead of [cp.v(0,0), cp.v(0,1), cp.v(1,1), cp.v(1,0)].

On a website

<script src="cp.min.js"></script>

<script>
var space = new cp.Space();
space.addBody(new cp.Body(...))
// ...
</script>

If any exceptions are thrown or anything, use cp.js instead of cp.min.js and post the stack trace you get to the issue page.

From nodejs

npm install chipmunk

cp = require('chipmunk');

var space = new cp.Space();
space.addBody(new cp.Body(...))
// ...

Example

This code creates a new space, sets 10 physics iterations per update (these increase simulation stability). Then it adds a bunch of line segments to the space.

In C, this code looked like:

  cpSpace *space = cpSpaceNew();
  space->iterations = 10;
  
  cpVect offset = cpv(-320, -240);
  for(int i=0; i<(bouncy_terrain_count - 1); i++){
    cpVect a = bouncy_terrain_verts[i], b = bouncy_terrain_verts[i+1];
    cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(cpSpaceGetStaticBody(space), cpvadd(a, offset), cpvadd(b, offset), 0.0f));
    cpShapeSetElasticity(shape, 1.0f);
  }

In javascript, the equivalent code is:

  var space = new cp.Space();
  space.iterations = 10;
  
  var offset = cp.v(-320, -240);
  for(var i=0; i<(bouncy_terrain_verts.length - 1); i++){
    var a = bouncy_terrain_verts[i], b = bouncy_terrain_verts[i+1];
    var shape = space.addShape(new cp.SegmentShape(space.staticBody, cp.vadd(a, offset), cp.vadd(b, offset), 0));
    shape.setElasticity(1);
  }

License

Like Chipmunk, chipmunk-js is MIT licensed.

Copyright (c) 2007 Scott Lembcke and Joseph Gentle

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

chipmunk-js's People

Contributors

josephg avatar laercioasano avatar nornagon avatar ricardoquesada avatar robwalch avatar wu-hao avatar yetanotherportfolio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chipmunk-js's Issues

Cannot create a body

I downloaded the cp.min.js file, then tried to create a body. Then I get an error Uncaught TypeError: this.setMass is not a function. I use cp.js and the same error happens. I delete all other libraries that I'm using, and still it doesn't work. To reproduce:

var space = new cp.Space();
var mass = 100;
var radius = 25;
var moment = cp.momentForCircle(mass, 20, radius, cp.vzero);
var body = cp.Body(mass, moment);

image
I am using Chrome.

Body.applyForce is mis-implemented as Body.applyImpulse

This issue serves as a report about a potential bug in the function cp.Body.applyForce. I believe that it is mis-implemented as the function cp.Body.applyForce.

According to Chipmunk documentations, this function applys force $$F$$ to the body, in time $$dt$$. It should be

$$f=F(t)$$

However, in line 1767, cp.js, the function is implemented as

Body.prototype.applyForce = function(force, r)
{
	this.activate();
	this.f = vadd(this.f, force);
	this.t += vcross(r, force);
};

This leads to add $$F(t)$$ cumulatively in every $$dt$$, thus calculating the integration of $F$ over time domain, and that is essentially calculating impulse of the force from the beginning to now

$$I=\int F(t)dt$$

To apply force, the code should be

Body.prototype.applyForce = function(force, r)
{
	this.activate();
	// this.f = vadd(this.f, force);
	this.f = force;
	this.t += vcross(r, force);
};

I hope the team could check and fix this bug. Thanks for your attention.

Cannot move static bodies.

I know you haven't maintained this repo for a while... but i found an issue with static bodies...
I tried creating a static body and moving it and it doesnt seem to work.
I tried also moving the static shape using shape.update() but it also doesn't work
There is no way to move a static shapes?

Bug in Node js

If space don't have static objects, in 2565 lines in cp.js file
if(this.root) subtreeQuery(this.root, bb, func);
this - global node js object, and it have root property. And the condition is true, although this don't cp.BBTree. Additional check on the this instanceof cp.BBTree solves the problem.

Probably wrong context in SpatialIndex.prototype.collideStatic

Probably wrong context is used in SpatialIndex.prototype.collideStatic.

SpatialIndex.prototype.collideStatic = function(staticIndex, func)
{
if(staticIndex.count > 0){
var query = staticIndex.query;

    var self = this;

    this.each(function(obj) {
                    // Wrong call: query(self, obj, new BB(obj.bb_l, obj.bb_b, obj.bb_r, obj.bb_t), func); 
        query.call(self, obj, new BB(obj.bb_l, obj.bb_b, obj.bb_r, obj.bb_t), func);
    });
}

};

bench.js: easy/fast way to answer the question 'did I regress?'

Currently the benchmarks take upwards of 15 minutes to run. It's really hard to determine, for a given change, whether a performance regression was introduced.

Possible solutions:

  1. only run each benchmark 3 times, instead of 9. This might lead to less stable numbers, but if it doesn't then it's a good solution.
  2. define a 'fast' subset of benchmarks that's reasonably representative. You've been tracking the benchmarks over time, so it shouldn't be too hard to pick the few that have reliably indicated overall performance (least-squares analysis perhaps? :))
  3. introduce a single large 'complete' benchmark. Even if it took 20s to run each time, that would only be 9*20s = 3 minutes total.

It would also be nice to be able to easily compute baseline numbers, e.g. by 'node bench.js --did-i-regress' performing a git clone into a temporary directory and running the benchmarks at origin/master, then running with your changes.

Native JS Bindings for Chipmunk

Hi guys,

I am creating JavaScript bindings (to be used in mobile games) for the Chipmunk (the C version), and the JS API that I am generating will be 100% compatible with yours.
So, people will be able to use the same JS API for mobile games, and web games.

The JS bindings for Chipmunk project could be found here:
https://github.com/zynga/jsbindings#readme

And more info about cocos2d+chipmunk JS Bindings here:
https://github.com/cocos2d/cocos2d-iphone/wiki/cocos2d-and-JavaScript

What the best way to be in contact with you ?
My email is: ricardoquesada at gmail

Emscripten

Port the C code to emscripten and benchmark it.

jerky player movement

Hey I am using the "Tank Demo" method of controlling a top down player. That is, a control body is created attached to the player body via pivot and gear constraint, and then when movement controls are pressed I set the velocity of the control body.

Here is how I create and attach my bodies:

var body = new cp.Body(1, Infinity),
    cbody = new cp.Body(Infinity, Infinity),
    cpivot = new cp.PivotJoint(cbody, body, cp.vzero, cp.vzero),
    cgear = new cp.GearJoint(cbody, body, 0, 1);

cpivot.maxBias = 0; //disable join correction
cpivot.maxForce = 10000; //emulate linear friction

cgear.errorBias = 0; //attempt to fully correct the joint each step
cgear.maxBias = 1.2; //but limit the angular correction
cgear.maxForce = 50000; //emulate angular friction

space.addBody(body);
space.addBody(cbody);
space.addConstraint(cpivot);
space.addConstraint(cgear);

Each frame I step the space and update my sprites like so:

space.step(dt); //dt is time since last frame in seconds

//go through each changed shape
space.activeShapes.each(function(shape) {
    var spr = shape.sprite; //I set this when the shape is created so I have the ref here
    spr.position.x = shape.body.p.x;
    spr.position.y = shape.body.p.y;
    spr.rotation = shape.body.a;
});

What I am seeing is jerky movement. Specifically there are micro teleportations as the player moves. I have tried everything I can think of, but I can't figure out why the movement isn't smooth. Happen to have any ideas?

NoCollide collides.

NoCollide

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
ReferenceError: Exception is not defined
    at [object Object].begin (/Users/jeremya/Source/Chipmunk-js/bench.js:6541:2)

Performance boost 10-16%

Hi,

I'm writting a 2d math library: js-2dmath to do a real test, I choose to rewrite some of your code (cpVec2 atm) and use mine. The speed boost was so good... I'm really happy but...

There is a problem, js-2dmath use arrays and Chipmunk-js objects/prototypes.
So before PR and cleanup are you really interested ? it's a hard change.

Another possibility is to use falafel to rewrite the code, dont know if it's really possible...

These are my numbers

Firefox (10%)

  • normal: "time to beat: " 18642.66666666667
  • js-2dmath: "time to beat: " 16883.666666666668

Chrome (16%)

  • normal: time to beat: 42554
  • js-2dmath: time to beat: 36557.66666666667

Test my fork with

git clone https://github.com/llafuente/Chipmunk-js
cd Chipmunk-js && npm install
firefox benchmark/bench.html

Does not pass google closure advanced mode

Google closure compiler advanced mode obfuscate codes.
commercial release has the need to protect their code

Please look into this to make chipmunk viable for commercial release

regarding Collision Callback

        box1.shape.setCollisionType(3);
        box2.shape.setCollisionType(8);
        Space.addCollisionHandler(3,8, null, function(){alert(1)});

Alert is called

But real world application requires a target for function to call

        box1.shape.setCollisionType(3);
        box2.shape.setCollisionType(8);

        box1.hi = "hello";
        box1.sayHi = function(){
            alert(this.hi);
        };

        Space.addCollisionHandler(3,8, null, box1.sayHi);

you get undefined, because what ever object calling "sayHi()" it does not have .hi attribute

Any idea how to fix this?
In cocos2d-html5, our callback handler function accepts a function with a target like

X.addCallback(target, obj.func)

Typescript Type Definitions?

These would not only let Typescript users use chipmunk-js conveniently, it'd also let some other languages like F# and Scala (which I'm using) interop more conveniently. Given that chipmunk-js follows the C library pretty closely, it should be pretty straightforward (if tedious) to mark out the type signatures for the various functions and methods.

Possible optimization: Array-based vectors

Why? When I was looking for a better 3D matrix lib a few months ago, glMatrix was the all-around winner in these benchmarks. Apparently using Arrays instead of Objects is a big win in JS. Vectors in chipmunk-js currently aren't very OO-like, so this change might be reasonable...

Pros: faster! (and less cumbersome IMHO)

Cons: unlike Chipmunk-C conventions; requires 146 changes; will break any code that manipulates .x/.y

I might be willing to try this in my fork. Any thoughts?

Don't set window.cp global if exports exists

Hi,

In my opinion CP shouldn't set the window.cp global if module.exports exists. i.e. If someone is using commonJS module system, they probably don't want the global being there and will instead 'require' in the lib as needed.

So the top should look something like:

var cp;
if(typeof exports === 'undefined'){
    cp = {};
    if(typeof window === 'object'){
        window.cp = cp;
    }
} else {
    cp = exports;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.