I'm learning PhysicsJS, and I tried using union like so:
// Window bounds
var rect1 = Physics.aabb(0, 100, 300, 200);
var rect2 = Physics.aabb(100, 0, 200, 300);
var viewportBounds = Physics.aabb.union(rect1, rect2);
// Constrain bodies to these bounds
world.add(Physics.behavior('edge-collision-detection', {
aabb: viewportBounds,
restitution: 0.99,
cof: 0.99
}));
but the ball just falls through the bottom.
Physics(function(world){
var viewWidth = 300;
var viewHeight = 300;
var renderer = Physics.renderer('canvas', {
el: 'viewport',
width: viewWidth,
height: viewHeight,
meta: false
});
// add the renderer
world.add(renderer);
// render on each step
world.subscribe('step', function(){
world.render();
});
// Window bounds
var rect1 = Physics.aabb(0, 100, 300, 200);
var rect2 = Physics.aabb(100, 0, 200, 300);
var viewportBounds = Physics.aabb.union(rect1, rect2);
// Constrain bodies to these bounds
world.add(Physics.behavior('edge-collision-detection', {
aabb: viewportBounds,
restitution: 0.99,
cof: 0.99
}));
// Add the ball
world.add(
Physics.body('circle', {
x: 0, // x-coordinate
y: 0, // y-coordinate
vx: 0.2, // x-velocity
vy: 0.01, // y-velocity
radius: 2.0
})
);
// ensure objects bounce when edge collision is detected
world.add( Physics.behavior('body-impulse-response') );
// add some gravity
world.add( Physics.behavior('constant-acceleration') );
// subscribe to ticker to advance the simulation
Physics.util.ticker.subscribe(function( time, dt ){
world.step( time );
});
// start the ticker
Physics.util.ticker.start();
});
body {
/*background: #121212;*/
}
.pjs-meta {
display: none;
}
#viewport {
border: 1px solid #666;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='http://wellcaffeinated.net/PhysicsJS/assets/scripts/vendor/physicsjs-0.5.0/physicsjs-full-0.5.0.min.js'></script>
<canvas id="viewport" width="300" height="300"></canvas>
I can't find any code on GitHub or anywhere using it. Can someone lend some guidance, please?
I can't find any code on GitHub or anywhere using it. Can someone lend some guidance, please?
You might try reading the unit tests in the .spec, on Github.
Sample test, which should look very readable even if barely know Javascript:
it("should initialize provided a width/height and point", function() {
var aabb = Physics.aabb( 4, 5, { x: 20, y: 9 } );
matches( aabb, { x: 20, y: 9, hw: 2, hh: 2.5 });
});
spec.js looks to be the test code. Test actually doubles as documentation, and libraries like spec serve to make test code read like documentation. Additionally, test code is, of course, a collection of examples of how to use the code. Enjoy.
Try reading other test code.
Figured it out. I was working with a super old version (physicsjs-0.5.0). I linked to the latest version (physicsjs-0.7.0), which has much more functionality (4,088 new lines of code between those two versions). I had to refactor my code a bit to match the updated spec, but it's all good!
Related
I am pretty new to Matter.js so forgive me if the answer to this is obvious.
I am trying to rotate a body on top of another (static) body and have it roll along that surface.
I need something similar to the car demo but I need there to be zero acceleration to the roll. i.e. every iteration of the loop I should be able to set a rotation amount and have the body rotate that much.
I also need this to able to work with non-eliptical bodies.
I have some code that rotates the body as I would like but I am struggling to make the body roll along the surface based on its rotation.
Any help would be much appreciated. Please see my current code below.
// module aliases
var Engine = Matter.Engine,
Render = Matter.Render,
World = Matter.World,
Bodies = Matter.Bodies,
Body = Matter.Body;
// create an engine
var engine = Engine.create();
// create a renderer
var render = Render.create({
element: document.body,
engine: engine
});
var boxA = Bodies.rectangle(400, 200, 80, 80);
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });
// add all of the bodies to the world
World.add(engine.world, [boxA, ground]);
// run the renderer
Render.run(render);
engine.world.gravity = {x: 0, y:0, scale: 0}; //disable gravity
window.setInterval(function () {
Body.rotate(boxA, 0.01);
Body.translate(boxA, { x: 0, y: 10 });
Engine.update(engine, 1000 / 60);
}, 1000 / 60)
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script>
I created a simple animation in matter.js physics engine, with a few object colliding and falling on the ground.
I noticed that the outcome is always a little different. You can see here: https://jsfiddle.net/95urgeqf/1/
var Engine = Matter.Engine,
Render = Matter.Render,
World = Matter.World,
Bodies = Matter.Bodies,
Body = Matter.Body;
// create an engine
var engine = Engine.create();
// create a renderer
var render = Render.create({
element: document.body,
engine: engine
});
// create two boxes and a ground
var boxA = Bodies.rectangle(400, 200, 80, 80);
var boxB = Bodies.rectangle(450, 50, 80, 80);
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });
var circle1 = Matter.Bodies.circle(400, 200, 20, { isStatic: true }, 300);
var circle2 = Matter.Bodies.circle(600, 300, 20, { isStatic: true }, 300);
var circle3 = Matter.Bodies.circle(200, 400, 20, { isStatic: true }, 300);
Body.setVelocity(boxA, { x: 0, y: -10});
// add all of the bodies to the world
World.add(engine.world, [boxA, boxB, ground, circle1, circle2, circle3]);
// run the engine
Engine.run(engine);
// run the renderer
Render.run(render);
Most noticeable is the square on the left when it touches the ground, it always falls a little different.
My aim is to create an animation that always behaves the same, so the left square should fall on the ground the same, identical, way each time, as long as it has the same params.
You got to use the same seed.
Matter.Common._seed = 12345678;
Anyway your animation can be different on different platforms/browsers due to difference in floating point operations.
If you want exactly the same behavior you need to use fixed point math.
UPD:
Also you need to use seeded random number generator(for example) across all application.
I am using the latest version of PaperJs but when I run the following code from their sample the output is "NaN."
window.onload = function () {
paper.setup('myCanvas');
with (paper) {
// Create a point whose x is between 0 and 50,
// and y is between 0 and 100
var point = new Point(50, 100) * Point.random();
console.log(point);
}
}
The code works online in sketch.paperjs.org but doesn't work when I try locally via the code above or the following (also outputs "NaN"):
// Make the paper scope global, by injecting it into window:
paper.install(window);
window.onload = function () {
// Setup directly from canvas id:
paper.setup('myCanvas');
// Create a point whose x is between 0 and 50,
// and y is between 0 and 100
var point = new Point(50, 100) * Point.random();
console.log(point);
}
The following works, and all my other PaperJs code works; it's just that I can't seem to create a random point per the documentation.
console.log(new Point(50, 100), Point.random());
Outputs:
Point {x: 50, y: 100} Point {x: 0.8624748098043336, y: 0.8705165661914955}
The documenation: http://paperjs.org/tutorials/geometry/mathematical-operations/#random-values
Are you sure you use the paper.js language and not javascript?
Because the multiply operator can't be overloaded in javascript, you have to use pointA.multiply(pointB);.
I'm trying to make an event that changes my shapes stroke color for 5 seconds when a button is clicked, and then the shape returns to original color after the duration.
I am able to do this with clearing the entire stage and redrawing new shapes (which resets their position), but I can't figure it out with the current shapes.
Q. What's the best way to approach making a change to a shapes color, during a Tween?
I was also curious if there's a better way to handling tweening the shapes width? Currently I am relying on ScaleX and ScaleY - but this also changes the stroke's size - which is not desired.
JS Fiddle
HTML
<button id="change">Click to Change Color</button>
<canvas id="demoCanvas" width="500" height="500"></canvas>
JS
var stage,
circle;
function init() {
stage = new createjs.Stage("demoCanvas");
createjs.Ticker.setFPS(60);
createjs.Ticker.addEventListener("tick", stage);
}
function createCircle(){
circle = new createjs.Shape().set({name:"circle"});
circle.graphics.setStrokeStyle(1).beginStroke("#000").beginFill( "#FFF" ).drawCircle(0, 0, 20);
circle.x = 100;
circle.y = 100;
stage.addChild(circle);
createjs.Tween.get(circle, {loop: true})
.to({x: 225, y: 225}, 1000, createjs.Ease.getPowInOut(1))
.to({x: 100, y: 100}, 1000, createjs.Ease.getPowInOut(1));
circle2 = new createjs.Shape().set({name:"circle"});
circle2.graphics.setStrokeStyle(1).beginStroke("#000").beginFill( "#FFF" ).drawCircle(0, 0, 20);
circle2.x = 400;
circle2.y = 400;
stage.addChild(circle2);
createjs.Tween.get(circle2, {loop: true})
.to({scaleX: 2, scaleY: 2, x: 425, y: 125}, 1000, createjs.Ease.getPowInOut(1))
.to({scaleX: 1, scaleY: 1, x: 400, y: 400}, 1000, createjs.Ease.getPowInOut(1));
stage.update();
}
$( "#change" ).click(function() {
// change color
});
$(document).ready(function() {
init();
createCircle();
});
There are a few questions in this post, so I will try to answer them all:
First, a solution to most of your issues is Graphic commands. Commands provide a simple way to store graphic instructions, and change them later. Here is a simple example:
var shape = new createjs.Shape();
var colorCmd = shape.graphics.beginFill("red").command;
var rectCmd = shape.graphics.drawRect(0,0,100,100).command;
// Later
colorCmd.style = "blue";
rectCmd.w = 200;
stage.update(); // Remember to update the stage after changing properties
You can read more about commands on the createjs blog. All commands and their properties are documented in the EaselJS docs.
Change a color: I outlined this in the example above, but the short answer is to adjust the style property of a fill command. If you want to change it instantly, you can just set up a Tween.call:
Example:
createjs.Tween.get(circle, {loop: true})
.to({x: 225, y: 225}, 1000, createjs.Ease.getPowInOut(1))
.call(function(tween) {
colorCmd.style = "rgba(0, 0, 255, 0.5)"; // Change to 50% blue
})
.to({x: 100, y: 100}, 1000, createjs.Ease.getPowInOut(1));
If you want to tween the color, then you could check out the ColorPlugin, which is currently in a "Plugins" branch of TweenJS: https://github.com/CreateJS/TweenJS/tree/Plugins/extras/plugins
// Tween the color from its current value to blue.
// Note that only hex, short hex, HSL, and RGB formats are supported.
createjs.Tween.get(colorCmd).to({style:"#0000ff"});
Change the size: The example above also shows how to modify the values of a drawRect call. You can do the same with any other draw command (including moveTo, lineTo, polyStar, etc).
Scaling also works, and if you want to not scale the stroke, just set the ignoreScale parameter on the stroke style.
shape.graphics.setStrokeStyle(1, null, null, null, true);
I can't figure out how to get the current rotation angle of an arch in jCanvas. layer.rotate only seems to provide me with the original setting of rotate, when I'd really like to change its behavior when it hits a certain angle.
I have an example setup on jsfiddle to demonstrate the problem.
Any insight would be appreciated.
are you looking for this value $('#rot').val()
while (i < 1000) {
setTimeout(function() { rotate() }, 1000);
alert( $('#rot').val());
i += 1;
}
The animateLayer() and animateLayerGroup() methods support the same alternate syntax as jQuery's animate() method, which allows for a step callback:
// Cache canvas element
var $canvas = $("canvas");
// Draw and animate
$canvas.drawArc({
layer: true,
name: 'arcy',
fillStyle: "#000",
x: 100, y: 100,
radius: 50,
start: 135, end: 45
});
$canvas.animateLayer('arcy', {
rotate: 360
}, {
// Use the step callback to run a function on every frame
step: function(now, fx, layer) {
console.log(layer.rotate);
}
});