liabru / matter-js Goto Github PK
View Code? Open in Web Editor NEWa 2D rigid body physics engine for the web ▲● ■
License: MIT License
a 2D rigid body physics engine for the web ▲● ■
License: MIT License
It would be very helpful to have that note about needing pixi.js right there in the RenderPixi documentation section. It was hard to track down. Also, http://brm.io/matter-js-docs/classes/RenderPixi.html points me to Demo.js for usage examples, but I can't find RenderPixi anywhere in Demo.js. If you do end up including it there, including a comment that explains the use of pixi.js could be very clarifying.
Implement sprite scaling in Matter.RenderPixi
the same as it works in Matter.Render
.
Sorry to open this as an issue: I can't find a forum or discussion area that would be more appropriate. Also, fantastic library - by far my favourite JS physics lib.
I have a side-scrolling platform game, where all the platforms are static bodies. I want to include some swinging platforms that act like static bodies (in that they defy gravity), but also like dynamic bodies in that they can have forces applied to them to make them move.
They should also apply force to other bodies to "bash" them along. My initial version used static bodies and translated them every frame, but then they don't have any velocity - so when they strike a player, the player just slides down the edge instead of pinging off it.
Any ideas would be welcome... and thanks again for the library!
Hi there.
I came across this bug when dragging things to the right hand side. As you can see when dragging something to the left everything is fine, but to the right it starts bouncing and then passes through the wall. Do you know what this might be?
Here is my code
Demo.walls = function() {
var _world = _engine.world;
Demo.reset();
World.add(_world, [
Bodies.rectangle(300, 300, 10, 560, { isStatic: true }),
Bodies.rectangle(500, 300, 10, 560, { isStatic: true })
]);
World.add(_world, Bodies.circle(400, 100, 30));
var renderOptions = _engine.render.options;
};
Thanks for all your great work on matter.js, I find it very exciting.
I would expect a restitution value of 1.0 on any object to signify a perfectly elastic collision. However, it appears the elasticity is dependent on the size and shape of the object.
Thus 1.0 could be inelastic or overly elastic; there doesn't seem to be a way for a user to input a value and have a known result. Even 2.0 can be inelastic. It is not dependent on density or friction. Also, if you notice the 3rd box, sometimes it will bounce lower than where it started and sometimes it will bounce higher.
Here's code to repro:
<html>
<head>
<script type="text/javascript" src="Matter.js"></script>
</head>
<body>
<div id="canvas-container"></div>
</body>
</html>
<script>
var container = document.getElementById('canvas-container');
var engine = Matter.Engine.create(container);
engine.world.gravity.y = 1.0;
engine.render.options.showDebug = true;
engine.render.options.showAngleIndicator = true;
Matter.World.add(engine.world, Matter.Bodies.rectangle(240, 155.5, 74, 73, { isStatic: false, density: 0.00005, friction: 1, restitution: 2, angle: 0}));
Matter.World.add(engine.world, Matter.Bodies.rectangle(58, 155.5, 18, 73, { isStatic: false, density: 0.00005, friction: 1, restitution: 1, angle: 0}));
Matter.World.add(engine.world, Matter.Bodies.rectangle(135, 155.5, 18, 73, { isStatic: false, density: 0.00005, friction: 1, restitution: 2, angle: 0}));
Matter.World.add(engine.world, Matter.Bodies.rectangle(225, 272.5, 404, 13, { isStatic: true, density: 0.00005, friction: 1, restitution: 2, angle: 0}));
Matter.World.add(engine.world, Matter.Bodies.rectangle(372.5, 183, 73, 18, { isStatic: false, density: 0.00005, friction: 1, restitution: 2, angle: 0}));
Matter.Engine.run(engine);
</script>
version: matter-0.7.0.js
I'm not quite sure how to describe this so I've made a small video of the problem in action here:
https://www.youtube.com/watch?v=8AMVVBJoc3s&feature=youtu.be
Essentially I've created a custom body from a set of vertices. You can apply force to this body which is dependent on the rotation of the body. In a nut shell, I'm recreating one of those old "lander" style video games (like Gravity Power for the Amiga).
The problem is, my "ship" has a small amount of rotation which is constantly affecting it. This appears to only occur after the force has been applied (via the "thrust" of the engine).
I'm sure I'm missing something obvious here. Apologies for the "help" ticket :(
Nowhere in the documentation is there an actual description of what the class is used for.
A perfect example:
Body
Body of what?
What's the difference between a Body, a Composite, and a World?
"See Demo.js and DemoMobile.js for usage example"
is how the documentation for every external class starts. Why even include that line in the documentation of every external class? The "dry" principle isn't language specific.
If I knew how to actually use matter.js, I would help write the documentation and/or examples demonstrating how each class works- but I've got little point of reference other than the comments in the code... so I can't do much good.
Tested on iphone 5S - When you rotate your phone immediately from landscape to "other landscape" bodies dissapear from the canvas. Basically turn your phone 180 degs from landscape view (not sure if its just demo or the library)
In the sling shot demo i replaced the rock with a soft body.
Now I am receiving the following error at line 4685.
Uncaught TypeError: Cannot read property 'x' of undefined
Vector.add = function(vectorA, vectorB) {
return { x: vectorA.x + vectorB.x, y: vectorA.y + vectorB.y };
};
Have finished using the matter.js 0.8.0 build for a project, very nice. However, did attempt to add support for screen pixel ratio above 1 (such as retina) by hacking the library abit. Would be great to have this supported out of the box.
The cars in the car demo act weirdly when put one on top of the other: they try to throw off each other, seemingly gaining energy out of nothing.
If you need fast moving or thin bodies a simple and robust solution is to sub-step using multiple updates per frame:
See the example here: #5 (comment)
As well as sub-steps also consider:
Currently there is no continuous collision detection (CCD), so fast moving objects pass through other objects.
A description of the problem:
http://www.stencyl.com/help/view/continuous-collision-detection
Solution is to implement a CCD algorithm.
One I'm currently considering is speculative contacts, see here and here.
"we compute the closest distance d between the two objects; the idea is that we want to remove exactly the right amount of velocity from A such that it will be exactly in touching contact with B on the next frame"
I've already implemented the code that extends the AABB based on object velocity.
The next part is to find the closest distance between two objects and remove the required velocity.
When I switch in the Demo.reset function _engine.enableSleeping = true, then the following happens.
Start the page and see the bodies. Then clear the world via the GUI. Then add a body. It just falls thru the wall.
I've got a basic multiplayer implementation of MatterJS going. Essentially I'm taking the body component, converting it to JSON (I tried resurrect-js but got put off with the lack of NPM, json-stringify-safe seemed to handle the circular references ok) then sending it over the wire. On the other machine, I'm creating a new body object then updating it as data is sent.
I couldn't find a built in update function so I simple used lodash's "extend" to overwrite the properties of the object from the re-serialised JSON data.
This seems to work pretty good, the objects stay nicely in sync. The problem is that theirs no interactivity between them. I had a few questions (and would be happy to update the docs with a pull request or create a demo). They are:
Sorry for the dump of questions :( I just couldn't find too much documentation on world serialisation / restoration.
I have added this example to demos, the ball slows down after each collision even with friction=0 and restitution=1, is this an expected behavior?
var ball = Bodies.circle(400, 300, 20, { frictionAir: 0, friction: 0, restitution: 1});
World.add(_world, [ball]);
var a = Math.random() * Math.PI * 2;
Body.applyForce(ball, { x: 0, y: 0 }, {x: 0.2 * Math.cos(a), y: 0.2 * Math.sin(a)});
Circles with a density lower than 0.01 will move a little when they bounce off a static object.
It seems like 0.01 is a pretty high value for density; the effect is magnified on more "normal" values like 0.0001.
<html>
<head>
<script type="text/javascript" src="matter.js"></script>
</head>
<body>
<div id="canvas-container"></div>
</body>
</html>
<script>
var container = document.getElementById('canvas-container');
var engine = Matter.Engine.create(container);
engine.world.gravity.y = 1;
engine.render.options.showDebug = true;
engine.render.options.showAngleIndicator = true;
Matter.World.add(engine.world, Matter.Bodies.circle(180.5, 25.5, 51, { isStatic: false, density: 0.001, friction: 0.1, restitution: 0.5 }));
Matter.World.add(engine.world, Matter.Bodies.circle(380.5, 25.5, 51, { isStatic: false, density: 0.1, friction: 0.1, restitution: 0.5 }));
Matter.World.add(engine.world, Matter.Bodies.rectangle(285.5, 523.5, 502, 102, { isStatic: true, density: 1.0, friction: 0.0, restitution: 1.0 }));
Matter.Engine.run(engine);
</script>
Hello, I'm having a bit of trouble finding the correct way to implement what would essentially be a compound object.
My initial thought was to try and accomplish this via Composites. Another way to describe what I am looking to do would be to have a way to control a group of bodies, with much of the functionality which the Body class has.
for instance:
var sideA = Bodies.rectangle(400, 100, 200, 1, {groupId: 1, isStatic: true});
var sideB = Bodies.rectangle(560, 185, 200, 1, {groupId: 1, isStatic: true});
Body.rotate(sideB, 19.8);
var sideC = Bodies.rectangle(245, 185, 200, 1, {groupId: 1, isStatic: true});
Body.rotate(sideC, 30.4);
var sideD = Bodies.rectangle(245, 360, 200, 1, {groupId: 1, isStatic: true});
Body.rotate(sideD, 19.9);
var sideE = Bodies.rectangle(400, 450, 200, 1, {groupId: 1, isStatic: true});
// flat
var sideF = Bodies.rectangle(552, 370, 200, 1, {groupId: 1, isStatic: true});
Body.rotate(sideF, 30.3);
// I wanna rotate and control the entire group of bodies like this
Body.rotate([sideA, sideB, ... sideF]);
Not asking for this api, this is just the best way I can describe the functionality I am trying to achieve.
Could you please point me in the right direction?
Hi Liam,
Firstly, this is an awesome project. I've been on the hunt for a decent physics engine for a game and this seems better and easier than physics.js and box2dweb.js to get going quickly.
So.. is there a a way to assign dragging only to certain bodies? for example, in your slingshot game, you wouldn't want user to be able to interact with the cans.
Also firing an event on touch to determine which body is being handled would be great, is this built in?
Any help or pointers in the right direction would be much appreciated.
Thanks,
Nic
Take a look at http://jsfiddle.net/We33V/1 . The falling rectangle should fall off the static rectangle.
Compare to http://jsfiddle.net/We33V/2/ , where the top-most falling rectangle falls of the bottom-most non-static rectangle.
Make it easier to create a body that ignores collision and tells whether it is intersecting another body.
Implement transforms for composites
The demos on http://brm.io/matter-js-demo/ use:
engine.render.options.background = "somecolor"
From what I can tell from the documentation, the current method that's supposed to be used is:
engine.render.setBackground( engine.render, "somecolor" );
Of course, right now I can't get either of those to work, but I'm sure that's a user error and is a totally different issue.
Is there any way to make concave polygons with matter.js?
I'm developing a game using SVG ( http://play.esviji.com/ ) and I feel a physics engine could help me on some topics.
All physics engines I've seen use only Canvas rendering, none of them uses SVG.
Is there a way Matter could provide both?
I have following issues
Disable drag event on all shapes accept one shape.
How to create custom shapes. In my case I have to create "C" like random shapes
Plop!
I think it would be cool to be able to listen to events fired by bodies themselves.
For example, the following events could be fired:
'addedToWorld'
-> { body : someBody, world : /* World it has been added to */ }
'removedFromWorld'
-> { body : someBody, world : /* World it has been removed from */ }
'collision'
-> { body : someBody, pair : /* Pair of the collision */ }
'collisionWith{{Someone Else}}'
-> { body : someBody, pair : /* Pair of the collision */ }
The motive behind this is that, when coding a game in which you control a square (a single body), I failed to find an easy way to observe what was happening to the player: Did he collide with something? Did he collide with [this thing]? I was able to do so with the following:
Matter.Events.on(engine, 'collisionActive', function(e) {
var i, pair,
length = e.pairs.length;
for(i = 0; i < length; i++) {
pair = event.pairs[i];
if(!(pair.bodyA.label === 'Player' || pair.bodyB.label === 'Player')) {
continue;
}
//Here body with label 'Player' is in the pair, do some stuff with it
}
});
So to watch a single body I was forced to watch every single collision pair only to find the one I was interested in. Thus, maybe the following would be better:
Matter.Events.on(player.body, 'collision', function(e) {
//player.body is in e.pair, do stuff with it
}
Or:
Matter.Events.on(player.body, 'collisionWith{{Exit}}', player.win);
The event collisionWith
being particular because it would be the first event to my knowledge that can have a parameter.
All of this could be further used with Composites.
Take a look at the following example: http://jsfiddle.net/We33V
The non-static composition of bodies do not fall off the edge as expected.
Demo.js has an extra var Demo = {}; on line 1258, resetting the object, throwing an error when looking for the default demo "mixed". I removed it and had no further issues as of yet.
If only I grab an object and drag it to a position that he is above the other, and start to move the mouse horizontally on the intention to make the object colliding with the walls. At some point the object beyond the wall and disappears.
And the line connecting the cursor and the object is still connected to it, and dissapears only after a click on any screen.
An event system is required for external input into the physics engine.
It should at least include events for
Did not find a way to manually stop the engine. I have tried to cancelAnimationFrame but the engine is still running. Even engine.enabled = false does not seem to have any effect.
I love matterjs but this is a show stopper.
Will.. it may be a dummy question, but I am a newbie of this awesome engine.
But I can not find api for this purpose should I just set rotate to 0 for the body in every frame?
Dynamic Box (A) falling on static Box (B) will collide very differently if it is on the right or left side. If on the right side, it will bounce off as I'd expect. On Box A's left side, it will stay on top of Box (B).
My glancing seems to show that the Resolver.solveVelocity is giving a different bodyB.anglePrev on the second contact, but I'm no expert on why!
See this simple repro case:
<html>
<head>
<script type="text/javascript" src="Matter.js"></script>
</head>
<body>
<div id="canvas-container"></div>
</body>
</html>
<script>
var container = document.getElementById('canvas-container');
var engine = Matter.Engine.create(container);
engine.world.gravity.y = 1;
engine.render.options.showDebug = true;
engine.render.options.showAngleIndicator = true;
Matter.World.add(engine.world, Matter.Bodies.rectangle(285.5, 323.5, 102, 102, { isStatic: true, density: 1.0, friction: 0.0, restitution: 1.0 }));
Matter.World.add(engine.world, Matter.Bodies.rectangle(380.5, 25.5, 102, 102, { isStatic: false, density: 1.0, friction: 0.0, restitution: 1.0 }));
Matter.World.add(engine.world, Matter.Bodies.rectangle(193.5, 25.5, 102, 102, { isStatic: false, density: 1.0, friction: 0.0, restitution: 1.0 }));
Matter.Engine.run(engine);
</script>
Hi!
I don't know if I'm doing that right, but I would like to use the engine in fullscreen. So on window resize, I'm adjusting the world bounds:
engine.world.bounds.max.x = window.width;
engine.world.bounds.max.y = window.height;
When I'm doing that, all the none-static bodies are moving by themselves to the right, without any interaction :/
What's happening? Is there any method to resize the world?
Thanks!
When a body slowly slides off an edge, it does not gain angular momentum as expected.
See: http://jsfiddle.net/Donk/4uwp42e7/
This is caused by lack of detection of such cases where the collision cache needs to be updated.
The project is still in an alpha state and the API has not yet solidified, so documentation is currently patchy as usage can change release to release. Some time is required to improve it before the first non-alpha release.
In the mean time, please use the following resources if you'd like to start using the engine despite the alpha status:
Currently, Mouse.clearSourceEvents() put null on all the event callbacks, but the events are still bound and dispatched. What I suggest:
Mouse.removeElement = function(mouse, element) {
mouse.element = element;
element.removeEventListener('mousemove', mouse.mousemove);
element.removeEventListener('mousedown', mouse.mousedown);
element.removeEventListener('mouseup', mouse.mouseup);
element.removeEventListener("mousewheel", mouse.mousewheel);
element.removeEventListener("DOMMouseScroll", mouse.mousewheel);
element.removeEventListener('touchmove', mouse.mousemove);
element.removeEventListener('touchstart', mouse.mousedown);
element.removeEventListener('touchend', mouse.mouseup);
};
and on Mouse.clearSourceEvents()
Mouse.clearSourceEvents = function(mouse) {
Mouse.removeElement(mouse, mouse.element);
mouse.sourceEvents.mousemove = null;
mouse.sourceEvents.mousedown = null;
mouse.sourceEvents.mouseup = null;
mouse.sourceEvents.mousewheel = null;
mouse.wheelDelta = 0;
};
What do you think?
See /src/body/Body.js:433
body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared;
and /src/body/Body.js:433
body.torque += (offset.x * force.y - offset.y * force.x) * body.inverseInertia;
(After I called applyForce, body doesn't rotate until I changed the position to {x:0,y:250000}.)
MouseConstraint dragBody and dragPoint not set during interaction.
They should become a reference to the body being dragged.
For those with this problem, you should be able to use the property mouseConstraint.constraint.bodyB
until this is resolved.
I'm creating a basketball game, and I need that only the ropes from the basket get affected by the ball's collision.
There's any way to do this?
Thanks
Hi again
I found a little bug when you set the engine's timing.isFixed = true via the options. In this case, no bodies are moving anymore.
Runner.run
......
if (timing.isFixed) {
// fixed timestep
delta = timing.delta;
correction = 1; // possible fix
}
Maybe you can reproduce this behavior and the possible fix helps.
I'm very interested in using matter.js for a project (the demos are very compelling) but I must know something first, hope you're able to help me, when I set an body size or apply a force is it like I'm defining in metres and newtons?
I hope I'm being, at least a little, clear. I would like to elaborate a simulation of some interaction using realistic values. For example, I have this circle with one metre radius and a mass of 30 kilograms over which I would apply 50 newtons in a specified direction. Then I just have to set the relation between metres and pixels before rendering it (myself).
Is it possible with matter?
Hi,
I've started to use matter.js in my game made with pixi.js, but I'd like to use matter.js without using its renderer. This may seem a silly question but how do you create an engine without any rendering ? Actually, I just want to apply objects positions / rotation data to existing pixi sprites.
Thanks a lot !
Hi!
I tried using matter-js for a little spaceship game i made for fun, but my spaceship seems to hit an invisible wall at around x=800.
I have isolated the problem in a codepen here: http://codepen.io/anon/pen/VYzWRa
As you can see my horizontal gravity moves the body to the right but it stops at some arbitrary point. Also, if you try to drag the body with the mouse at this point you can see that it is being effected by a force of some sort.
I love all the options for turning various mechanics on/off but couldn't find one for the little green rubber band that shows up when dragging a shape. can i change the color or hide this easily?
I've been playing with matter.js for quite a while, and I am honestly impressed.
However, I've been trying for hours to get an object whose vertices are updated before running the simulation to simulate properly.
Fiddle: http://jsfiddle.net/FNYB9/
Press 'Create Rectangle', click and drag in the canvas, then hit 'Start Simulation'.
Here's a code example (I've removed as much as I can, getCanvasMousePos
works fine, in case you were wondering):
var startPos, endPos, rect;
$('#canvas').on('mousedown', function(e) {
startPos = getCanvasMousePos($('#canvas')[0], e);
rect = Body.create();
World.add(engine.world, [
rect,
]);
$('#canvas').on('mousemove', function(e) {
e.preventDefault();
endPos = getCanvasMousePos($('#canvas')[0], e);
rect.vertices = [
{x: startPos.x, y: startPos.y},
{x: endPos.x, y: startPos.y},
{x: endPos.x, y: endPos.y},
{x: startPos.x, y: endPos.y},
];
Engine.render(engine);
});
$('#canvas').on('mouseup', function() {
$('#canvas').off();
});
});
...
...
Engine.run(engine);
The result is a rectangle that is the user-defined size, with the start position of the click in the upper-left corner and the end position in the bottom right corner.
However, once the simulation starts, the rectangle falls as expected, until it collides with something, and throws this error:
Uncaught TypeError: Cannot read property 'x' of undefined
I assume this has something to do with what happens on Body.create
?
Other configurations give even weirder results, this one is the best I have so far.
Hi!
Is there a way to modify a body's position before it is drawn?
e.g (Which do not work)
Events.on(_engine, 'tick', function (event){
var circle_pos = circle.position;
circle_pos = {x: circle_pos.x - viewPort.x, y : circle_pos.y - viewPort.y};
});
Where I want to actually do:
context.arc(x - viewPort.x, y - viewPort.y, radius, sAngle, eAngle);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.