### Global Variables and Initial Setup - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/sensors.html This snippet declares global variables for the canvas, rendering context, p2.js world, and physics bodies. It also includes the initial calls to `init()` and `requestAnimationFrame()` to start the application. ```javascript var w, h, canvas, ctx, world, circleBody, sensorBody; init(); requestAnimationFrame(animate); ``` -------------------------------- ### Installing p2.js Project Dependencies (Shell) Source: https://github.com/schteppe/p2.js/blob/master/README.md This snippet provides the shell commands to clone the p2.js repository, navigate into its directory, install Node.js dependencies using npm, and run the default grunt task for initial setup. It assumes Git, Node.js, NPM, and Grunt are already installed as prerequisites. ```Shell git clone https://github.com/schteppe/p2.js.git; cd p2.js; npm install; # Install dependencies grunt; ``` -------------------------------- ### Global Variables and Initial Setup - p2.js Platformer - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/platformer.html Defines global variables for canvas, context, dimensions, camera, physics world, character body, and collision groups. It also initiates the application by calling the `init()` function and starting the animation loop with `requestAnimationFrame(animate)`. ```JavaScript var canvas; var ctx; var w, h; var cameraPos = [0, 0]; var zoom = 50; var fixedDeltaTime = 1 / 60; var maxSubSteps = 10; var world; var characterBody; var rayDebugData = []; var player; // Collision groups var SCENERY_GROUP = 0x01; var PLAYER_GROUP = 0x02; init(); requestAnimationFrame(animate); ``` -------------------------------- ### Main Script Initialization and Animation Start in JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/interpolation.html This code block declares global variables for canvas elements and p2.js objects, then immediately calls the `init()` function to set up the environment and the `animate()` function to start the continuous physics simulation and rendering loop. ```JavaScript var w, h, canvas, ctx, world, circleBody; init(); animate(); ``` -------------------------------- ### Initializing p2.js World and Canvas in JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/mouseJoint.html This snippet initializes the HTML canvas and sets up the p2.js physics world. It defines global variables for canvas context, dimensions, and p2.js bodies, then calls init() and animate() to start the simulation. ```JavaScript var canvas, ctx, w, h, world, boxBody, planeBody, mouseConstraint, mouseBody; var scaleX = 50, scaleY = -50; init(); requestAnimationFrame(animate); function init(){ // Init canvas canvas = document.getElementById("myCanvas"); w = canvas.width; h = canvas.height; ctx = canvas.getContext("2d"); ctx.lineWidth = 0.05; // Init p2.js world = new p2.World(); // Add a box boxShape = new p2.Box({ width: 2, height: 1 }); boxBody = new p2.Body({ mass:1, position:[0,3], angularVelocity:1 }); boxBody.addShape(boxShape); world.addBody(boxBody); // Add a plane planeShape = new p2.Plane(); planeBody = new p2.Body(); planeBody.addShape(planeShape); world.addBody(planeBody); // Create a body for the cursor mouseBody = new p2.Body(); world.addBody(mouseBody); ``` -------------------------------- ### Global Variables and Game Initialization - p2.js Platformer - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/character.html Declares global variables for canvas, context, dimensions, physics parameters (zoom, speeds, time step), p2.js world objects (world, bodies, arrays for platforms and boxes), and input state. It then calls init() to set up the game and requestAnimationFrame(animate) to start the game loop. ```JavaScript var canvas, ctx, w, h, zoom=50, jumpSpeed=6, walkSpeed=2, timeStep=1/60, maxSubSteps=10, world, characterBody, planeBody, platforms=[], boxes=[]; var buttons = { space: 0, left: 0, right: 0 }; init(); requestAnimationFrame(animate); ``` -------------------------------- ### Installing p2.js via npm for Node.js Source: https://github.com/schteppe/p2.js/blob/master/README.md This command-line snippet provides the instruction to install the p2.js library using npm, the Node.js package manager. This is the standard method for integrating p2.js into Node.js projects, making it available for server-side physics simulations or build processes. ```shell npm install p2 ``` -------------------------------- ### Global Variable Initialization and Event Listener Setup - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/rayreflect.html This snippet initializes global variables required for the canvas context, p2.js world, and raycasting. It also sets up an event listener for a 'reflect' checkbox, which controls a boolean flag used in the raycasting logic. ```JavaScript var canvas, ctx, w, h, world, boxBody, planeBody, planeShape, lineBody, lineShape; var scaleX = 50, scaleY = -50; var start = [0,0]; var end = [0,0]; var direction = [0,0]; var reflect = false; var result = new p2.RaycastResult(); var hitPoint = p2.vec2.create(); var ray = new p2.Ray({ mode: p2.Ray.CLOSEST }); document.getElementById("reflect").addEventListener('change', function(evt){ reflect = document.getElementById("reflect").checked; }); init(); requestAnimationFrame(animate); ``` -------------------------------- ### Initializing a p2.js World with Gravity and Broadphase (JavaScript) Source: https://github.com/schteppe/p2.js/blob/master/docs/files/src_world_World.js.html This example demonstrates how to create a new p2.js World instance, specifying custom gravity and a broadphase algorithm. It then shows how to add a new Body to the created world, which is a fundamental step in setting up a physics simulation. ```JavaScript var world = new World({ gravity: [0, -10], broadphase: new SAPBroadphase() }); world.addBody(new Body()); ``` -------------------------------- ### Initializing p2.js World and Canvas in JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/box.html This function initializes the HTML canvas context and sets up the p2.js physics world. It creates a `p2.World` instance, then adds a `p2.Box` body with a mass and initial position, and a static `p2.Plane` body to simulate a ground. ```JavaScript var canvas, ctx, w, h, world, boxBody, planeBody; init(); requestAnimationFrame(animate); function init(){ // Init canvas canvas = document.getElementById("myCanvas"); w = canvas.width; h = canvas.height; ctx = canvas.getContext("2d"); ctx.lineWidth = 0.05; // Init p2.js world = new p2.World(); // Add a box boxShape = new p2.Box({ width: 2, height: 1 }); boxBody = new p2.Body({ mass: 1, position: [0,3], angularVelocity: 1 }); boxBody.addShape(boxShape); world.addBody(boxBody); // Add a plane planeShape = new p2.Plane(); planeBody = new p2.Body(); planeBody.addShape(planeShape); world.addBody(planeBody); } ``` -------------------------------- ### Raycasting for All Hits with Callback in p2.js - JavaScript Example Source: https://github.com/schteppe/p2.js/blob/master/docs/files/src_world_World.js.html This example shows how to perform a raycast to find all hits, using a callback function to process each hit. It initializes a 'Ray' in 'Ray.ALL' mode and defines a callback to log hit body, shape, point, and distance. The 'result.stop()' method is shown to halt traversal early if desired. ```JavaScript var ray = new Ray({ mode: Ray.ALL, from: [0, 0], to: [10, 0], callback: function(result){ // Print some info about the hit console.log('Hit body and shape: ', result.body, result.shape); // Get the hit point var hitPoint = vec2.create(); result.getHitPoint(hitPoint, ray); console.log('Hit point: ', hitPoint[0], hitPoint[1], ' at distance ' + result.getHitDistance(ray)); // If you are happy with the hits you got this far, you can stop the traversal here: result.stop(); } }); var result = new RaycastResult(); world.raycast(result, ray); ``` -------------------------------- ### Initializing p2.js World and Canvas in JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/circle.html This function initializes the HTML canvas context and the p2.js physics world. It sets up a circle body with a p2.Circle shape and a plane body with a p2.Plane shape, adding both to the world. ```JavaScript function init(){ // Init canvas canvas = document.getElementById("myCanvas"); w = canvas.width; h = canvas.height; ctx = canvas.getContext("2d"); ctx.lineWidth = 0.05; // Init p2.js world = new p2.World(); // Add a circle circleShape = new p2.Circle({ radius: 1 }); circleBody = new p2.Body({ mass:1, position:[0,3] }); circleBody.addShape(circleShape); world.addBody(circleBody); // Add a plane planeShape = new p2.Plane(); planeBody = new p2.Body(); planeBody.addShape(planeShape); world.addBody(planeBody); } ``` -------------------------------- ### Global Variable Initialization for p2.js Raycasting - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/raycasting.html Initializes global variables for canvas context, dimensions, p2.js world, physics bodies, and raycasting objects (RaycastResult, Ray in CLOSEST, ALL, ANY modes). These variables are essential for setting up the physics simulation and its visual representation. ```JavaScript var canvas, ctx, w, h, world, boxBody, planeBody; var scaleX = 50, scaleY = -50; var start = [0,0]; var end = [0,0]; var result = new p2.RaycastResult(); var hitPoint = p2.vec2.create(); var rayClosest = new p2.Ray({ mode: p2.Ray.CLOSEST }); var rayAll = new p2.Ray({ mode: p2.Ray.ALL, callback: function(result){ drawRayResult(result, rayAll); } }); var rayAny = new p2.Ray({ mode: p2.Ray.ANY }); var raycastOptions = {}; ``` -------------------------------- ### Starting the p2.js Animation Loop Source: https://github.com/schteppe/p2.js/blob/master/examples/dom/index.html This single line initiates the animation loop by calling `requestAnimationFrame` with the `update` function. This begins the continuous process of physics simulation and DOM element synchronization, making the physics world visually interactive. ```JavaScript requestAnimationFrame(update); ``` -------------------------------- ### Setting Up a Basic Physics Scene with p2.js Source: https://github.com/schteppe/p2.js/blob/master/README.md This snippet demonstrates how to initialize a p2.js physics world, create dynamic and static bodies (a circle and a ground plane), attach shapes to them, and add them to the world for simulation. It also includes an animation loop to advance the simulation over time, using `requestAnimationFrame` for smooth rendering. ```js // Create a physics world, where bodies and constraints live var world = new p2.World({ gravity:[0, -9.82] }); // Create an empty dynamic body var circleBody = new p2.Body({ mass: 5, position: [0, 10] }); // Add a circle shape to the body var circleShape = new p2.Circle({ radius: 1 }); circleBody.addShape(circleShape); // ...and add the body to the world. // If we don't add it to the world, it won't be simulated. world.addBody(circleBody); // Create an infinite ground plane body var groundBody = new p2.Body({ mass: 0 // Setting mass to 0 makes it static }); var groundShape = new p2.Plane(); groundBody.addShape(groundShape); world.addBody(groundBody); // To animate the bodies, we must step the world forward in time, using a fixed time step size. // The World will run substeps and interpolate automatically for us, to get smooth animation. var fixedTimeStep = 1 / 60; // seconds var maxSubSteps = 10; // Max sub steps to catch up with the wall clock var lastTime; // Animation loop function animate(time){ requestAnimationFrame(animate); // Compute elapsed time since last render frame var deltaTime = lastTime ? (time - lastTime) / 1000 : 0; // Move bodies forward in time world.step(fixedTimeStep, deltaTime, maxSubSteps); // Render the circle at the current interpolated position renderCircleAtPosition(circleBody.interpolatedPosition); lastTime = time; } // Start the animation loop requestAnimationFrame(animate); ``` -------------------------------- ### Implementing p2.js Physics Animation Loop Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/raycasting.html The `animate` function sets up the main simulation loop using `requestAnimationFrame`. It calculates the delta time, clamps it, and then steps the p2.js physics world forward. After the physics update, it calls the `render` function to draw the scene. ```JavaScript var lastTime, timeStep = 1 / 60, maxSubSteps = 5; // Animation loop function animate(time){ requestAnimationFrame(animate); var dt = lastTime ? (time - lastTime) / 1000 : 0; dt = Math.min(1 / 10, dt); lastTime = time; // Move physics bodies forward in time world.step(timeStep, dt, maxSubSteps); // Render scene render(time); } ``` -------------------------------- ### Updating Ray Start and End Points - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/raycasting.html Dynamically updates the start and end coordinates of a ray based on the current time, making the ray move across the canvas. This creates an animated ray for demonstration purposes. ```JavaScript function drawRays(time){ start[0] = -3; start[1] = Math.sin(time / 1000) * 4; end[0] = 5; } ``` -------------------------------- ### Drawing a Ray on Canvas - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/raycasting.html Renders a straight line segment on the canvas, representing a ray, from a specified start point to an end point. This function is used to visually represent the path of the raycast. ```JavaScript function drawRay(start, end){ // Draw line ctx.beginPath(); ctx.moveTo(start[0], start[1]); ctx.lineTo(end[0], end[1]); ctx.stroke(); } ``` -------------------------------- ### Initializing Game World and Character - p2.js Platformer - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/platformer.html Sets up the HTML canvas, initializes the p2.js physics world, adds static scenery elements (boxes and circles), and creates a kinematic character body. It also instantiates a `p2.KinematicCharacterController` for player movement and attaches event listeners for keyboard input to control the character. ```JavaScript function init(){ // Init canvas canvas = document.getElementById("myCanvas"); w = canvas.width; h = canvas.height; ctx = canvas.getContext("2d"); ctx.lineWidth = 1 / zoom; // Init world world = new p2.World(); // Add some scenery addStaticBox(-3, 3, 0, 3, 1); addStaticBox(0, -1, 0, 7, 1); addStaticBox(-6, 0, Math.PI / 4, 1, 7); addStaticBox(4, 2, 0, 1, 6); addStaticCircle(-9, 1, 1, 2); // Add a character body var characterShape = new p2.Box({ width: 1, height: 1.5, collisionGroup: PLAYER_GROUP }); characterBody = new p2.Body({ mass: 0, position:[0,3], fixedRotation: true, damping: 0, type: p2.Body.KINEMATIC }); characterBody.addShape(characterShape); world.addBody(characterBody); // Create the character controller player = new p2.KinematicCharacterController({ world: world, body: characterBody, collisionMask: SCENERY_GROUP, velocityXSmoothing: 0.0001, timeToJumpApex: 0.4, skinWidth: 0.1 }); // Update the character controller after each physics tick. world.on('postStep', function(){ rayDebugData.length = 0; player.update(world.lastTimeStep); }); // Store ray debug data player.on('raycast', function(evt){ rayDebugData.push( evt.ray.from[0], evt.ray.from[1], evt.ray.to[0], evt.ray.to[1] ); }); // Set up key listeners var left = 0, right = 0; window.addEventListener('keydown', function(evt){ switch(evt.keyCode){ case 38: // up key case 32: player.setJumpKeyState(true); break; // space key case 39: right = 1; break; // right key case 37: left = 1; break; // left key } player.input[0] = right - left; }); window.addEventListener('keyup', function(evt){ switch(evt.keyCode){ case 38: // up case 32: player.setJumpKeyState(false); break; case 39: right = 0; break; case 37: left = 0; break; } player.input[0] = right - left; }); } ``` -------------------------------- ### Utility Function for Getting Current Time in JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/interpolation.html This utility function returns the current time in seconds, calculated by dividing the milliseconds returned by `new Date().getTime()` by 1000. It is used to measure time elapsed between animation frames for physics updates. ```JavaScript function time(){ return new Date().getTime() / 1000; } ``` -------------------------------- ### Initializing p2.js World and Pixi.js Stage in JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/pixijs/box.html This snippet initializes both the p2.js physics world by adding a box and a static plane, and the Pixi.js rendering environment. It sets up the renderer, stage, and a container for content, applying transformations to align Pixi.js coordinates with the physics world (flipping the Y-axis and zooming). Finally, it draws the initial representation of the box. ```JavaScript function init(){ // Init p2.js world world = new p2.World(); // Add a box boxShape = new p2.Box({ width: 2, height: 1 }); boxBody = new p2.Body({ mass:1, position:[0,2], angularVelocity:1 }); boxBody.addShape(boxShape); world.addBody(boxBody); // Add a plane planeShape = new p2.Plane(); planeBody = new p2.Body({ position:[0,-1] }); planeBody.addShape(planeShape); world.addBody(planeBody); // Pixi.js zoom level zoom = 100; // Initialize the stage renderer = PIXI.autoDetectRenderer(600, 400), stage = new PIXI.Stage(0xFFFFFF); // We use a container inside the stage for all our content // This enables us to zoom and translate the content container = new PIXI.DisplayObjectContainer(), stage.addChild(container); // Add the canvas to the DOM document.body.appendChild(renderer.view); // Add transform to the container container.position.x = renderer.width/2; // center at origin container.position.y = renderer.height/2; container.scale.x = zoom; // zoom in container.scale.y = -zoom; // Note: we flip the y axis to make "up" the physics "up" // Draw the box. graphics = new PIXI.Graphics(); graphics.beginFill(0xff0000); graphics.drawRect(-boxShape.width/2, -boxShape.height/2, boxShape.width, boxShape.height); // Add the box to our container container.addChild(graphics); } ``` -------------------------------- ### Drawing Debug Ray on Canvas - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/platformer.html A utility function to draw a line segment on the canvas, typically used for visualizing raycasts or debug information. It takes start and end coordinates and draws a line between them using the current canvas context stroke style. ```JavaScript function drawRay(startX, startY, endX, endY){ ctx.beginPath(); ctx.moveTo(startX, startY); ctx.lineTo(endX, endY); ctx.stroke(); ctx.closePath(); } ``` -------------------------------- ### Initializing p2.js Voronoi Physics Demo - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/demos/voronoi.html This snippet initializes a p2.js WebGL renderer and sets up a physics world with gravity. It then generates 50 random sites within a bounding box, computes a Voronoi diagram, and converts each cell into a p2.js `Convex` body. These bodies are added to the world with initial velocities and mass, along with two static `Plane` bodies to act as boundaries. ```JavaScript // Create demo application var app = new p2.WebGLRenderer(function(){ // Create the world var world = new p2.World({ gravity : [0,-5] }); this.setWorld(world); var voronoi = new Voronoi(); var bbox = { xl: -2, // left xr: 2, // right yt: -2, // top yb: 2 // bottom }; var sites = []; for(var i=0; i<50; i++){ // generate points within the bbox var site = { x: bbox.xl + Math.random() * (bbox.xr - bbox.xl), y: bbox.yb + Math.random() * (bbox.yt - bbox.yb) }; sites.push(site); } var diagram = voronoi.compute(sites, bbox); for (var i = 0; i < diagram.cells.length; i++) { var cell = diagram.cells[i]; var vertices = []; for (var j = 0; j < cell.halfedges.length; j++) { var edge = cell.halfedges[j].getStartpoint(); vertices.push([ edge.x - cell.site.x, -(edge.y - cell.site.y) ]); } var body = new p2.Body({ position: [cell.site.x + 15, -cell.site.y ], velocity: [-15, 5], mass: 1 }); body.addShape(new p2.Convex({ vertices: vertices })); world.addBody(body); } var planeBody = new p2.Body({ position: [0, -3] }); planeBody.addShape(new p2.Plane()); world.addBody(planeBody); var planeBody2 = new p2.Body({ position: [-5, 0], angle: -Math.PI / 2 }); planeBody2.addShape(new p2.Plane()); world.addBody(planeBody2); // Start demo this.frame(0, 0, 12, 12); }); ``` -------------------------------- ### Main Animation and Physics Loop - p2.js - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/platformer.html The core animation loop that runs continuously using `requestAnimationFrame`. It calculates the delta time, advances the p2.js physics world simulation using `world.step()`, calls the `render()` function to draw the scene, and updates debug information. ```JavaScript var lastTime; // Animation loop function animate(time){ requestAnimationFrame(animate); // Compute elapsed time since last frame var deltaTime = lastTime ? (time - lastTime) / 1000 : 0; deltaTime = Math.min(1 / 10, deltaTime); // Move physics bodies forward in time world.step(fixedDeltaTime, deltaTime, maxSubSteps); // Render scene render(); updateDebugLog(); lastTime = time; } ``` -------------------------------- ### Initializing a TopDownVehicle with Wheels - p2.js JavaScript Source: https://github.com/schteppe/p2.js/blob/master/docs/files/src_objects_TopDownVehicle.js.html This example demonstrates how to create a TopDownVehicle instance, add a chassis body to the world, and then attach and configure front and back wheels. It shows how to set side friction for wheels, apply a steer value to the front wheel, and set engine force and brake force for the back wheel. ```JavaScript // Create a dynamic body for the chassis var chassisBody = new Body({ mass: 1 }); var boxShape = new Box({ width: 0.5, height: 1 }); chassisBody.addShape(boxShape); world.addBody(chassisBody); // Create the vehicle var vehicle = new TopDownVehicle(chassisBody); // Add one front wheel and one back wheel - we don't actually need four :) var frontWheel = vehicle.addWheel({ localPosition: [0, 0.5] // front }); frontWheel.setSideFriction(4); // Back wheel var backWheel = vehicle.addWheel({ localPosition: [0, -0.5] // back }); backWheel.setSideFriction(3); // Less side friction on back wheel makes it easier to drift vehicle.addToWorld(world); // Steer value zero means straight forward. Positive is left and negative right. frontWheel.steerValue = Math.PI / 16; // Engine force forward backWheel.engineForce = 10; backWheel.setBrakeForce(0); ``` -------------------------------- ### Drawing a Ray on Canvas Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/rayreflect.html This utility function draws a simple line segment on the canvas, representing a ray. It takes two 2D vector arrays, `start` and `end`, as input, defining the ray's origin and termination point. This is used for visualizing ray paths. ```JavaScript function drawRay(start, end){ // Draw line ctx.beginPath(); ctx.moveTo(start[0], start[1]); ctx.lineTo(end[0], end[1]); ctx.stroke(); } ``` -------------------------------- ### Initializing p2.js WebGL Renderer and Physics Demo Source: https://github.com/schteppe/p2.js/blob/master/demos/control.html This comprehensive snippet initializes the p2.js WebGL renderer, sets up a physics world with zero gravity, and populates it with dynamic boxes and static walls. It defines a controllable character and a kinematic control body, linking them with revolute and gear constraints. A postStep event handler is implemented to manage character movement and rotation based on mouse input, providing an interactive control demo. ```JavaScript var postStepHandler; var size = 6; // Create demo application var app = new p2.WebGLRenderer({ setup: function(){ // Create the physics world var world = new p2.World({ gravity : [0, 0] }); this.setWorld(world); // Add some boxes for(var i=0; i<10; i++){ var boxBody = new p2.Body({ mass: 0.5, damping: 0.99, angularDamping: 0.99, position: [ (Math.random() - 0.5) * size, (Math.random() - 0.5) * size ], angle: (Math.random() - 0.5) * Math.PI * 2 }); boxBody.addShape(new p2.Box({ width: 0.4, height: 0.4 })); world.addBody(boxBody); } // Add walls createStaticBox(world, -size/2, 0, 0.1, size) createStaticBox(world, size/2, 0, 0.1, size) createStaticBox(world, 0, -size/2, size, 0.1) createStaticBox(world, 0, size/2, size, 0.1) // Character var characterBody = new p2.Body({ mass: 1 }); var characterShape = new p2.Circle({ radius: 0.5 }); characterBody.addShape(characterShape); world.addBody(characterBody); // Control body var controlBody = new p2.Body({ type: p2.Body.KINEMATIC, collisionResponse: false }); var controlShape = new p2.Circle({ radius: 0.1 }); controlBody.addShape(controlShape); world.addBody(controlBody); // Constrain control to character var constraint = new p2.RevoluteConstraint(controlBody, characterBody, { localPivotA: [0, 0], localPivotB: [0, 0], maxForce: 40 }); constraint.setMaxBias(0); // emulate friction world.addConstraint(constraint); var gear = new p2.GearConstraint(controlBody, characterBody, { maxTorque: 100 }); gear.setMaxBias(0); world.addConstraint(gear); var mouseDelta = p2.vec2.create(); world.on('postStep', postStepHandler = function(){ // turn the control body p2.vec2.subtract(mouseDelta, app.mousePosition, characterBody.position); controlBody.angularVelocity = 10 * shortestArc(characterBody.angle, Math.atan2(mouseDelta[1], mouseDelta[0])); // drive towards the mouse if(p2.vec2.distance(app.mousePosition, characterBody.position) < 0.5){ p2.vec2.set(controlBody.velocity, 0, 0); } else { p2.vec2.copy(controlBody.velocity, mouseDelta); p2.vec2.normalize(controlBody.velocity, controlBody.velocity); p2.vec2.scale(controlBody.velocity, controlBody.velocity, 3); } }); this.frame(0, 0, 7, 7); }, teardown: function(){ world.off('postStep', postStepHandler); } }); ``` -------------------------------- ### ContactEquationPool Constructor and Prototype Setup - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/docs/files/src_utils_ContactEquationPool.js.html This code defines the constructor for `ContactEquationPool`, which calls the `Pool` constructor to inherit its properties. It also correctly sets up the prototype chain, ensuring `ContactEquationPool` instances inherit methods from `Pool` and have the correct constructor reference. ```JavaScript function ContactEquationPool() { Pool.apply(this, arguments); } ContactEquationPool.prototype = new Pool(); ContactEquationPool.prototype.constructor = ContactEquationPool; ``` -------------------------------- ### Retrieving New Body Overlaps in OverlapKeeper (JavaScript) Source: https://github.com/schteppe/p2.js/blob/master/docs/files/src_utils_OverlapKeeper.js.html This method retrieves a list of newly started overlaps between Body objects. It first gets new overlaps at the shape level using getNewOverlaps and then processes them to return unique body pairs using getBodyDiff. The result array is populated with these body pairs. ```JavaScript OverlapKeeper.prototype.getNewBodyOverlaps = function(result){ this.tmpArray1.length = 0; var overlaps = this.getNewOverlaps(this.tmpArray1); return this.getBodyDiff(overlaps, result); }; ``` -------------------------------- ### Initializing p2.js WebGL Renderer and World in JavaScript Source: https://github.com/schteppe/p2.js/blob/master/demos/constraints.html This snippet initializes the p2.js WebGL renderer and sets up the physics world with a specified gravity. It also configures the solver iterations for the world. This is a foundational step for any p2.js simulation. ```JavaScript var N = 10, // Number of circles r = 0.1; // circle radius // Create demo application var app = new p2.WebGLRenderer(function(){ var world = new p2.World({ gravity : [0,-15] }); this.setWorld(world); world.solver.iterations = N; ``` -------------------------------- ### Setting Up p2.js World with Restitution Examples (JavaScript) Source: https://github.com/schteppe/p2.js/blob/master/demos/restitution.html This code initializes a p2.js physics world with gravity and sets up a WebGL renderer. It then creates three distinct ball-platform systems, each demonstrating different restitution properties through `p2.ContactMaterial` configurations: perfect restitution (bounce), zero restitution (no bounce), and soft contact with custom stiffness and relaxation. ```JavaScript // Create demo application var app = new p2.WebGLRenderer(function(){ // Create a World var world = new p2.World({ gravity: [0, -10] }); this.setWorld(world); var ballBody1 = new p2.Body({ position: [-2,1], mass: 1, damping: 0, // Remove damping from the ball, so it does not lose energy angularDamping: 0 }); // Create a material for the circle shape var circleShape1 = new p2.Circle({ radius: 0.5, material: new p2.Material() }); ballBody1.addShape(circleShape1); // Add ball to world world.addBody(ballBody1); // Create a platform that the ball can bounce on var platformShape1 = new p2.Box({ width: 1, height: 1, material: new p2.Material() }); var platformBody1 = new p2.Body({ position:[-2,-1], }); platformBody1.addShape(platformShape1); world.addBody(platformBody1); // Create contact material between the two materials. // The ContactMaterial defines what happens when the two materials meet. // In this case, we use some restitution. world.addContactMaterial(new p2.ContactMaterial(platformShape1.material, circleShape1.material, { restitution: 1, stiffness: Number.MAX_VALUE // We need infinite stiffness to get exact restitution })); // Create another ball var circleShape2 = new p2.Circle({ radius: 0.5, material: new p2.Material() }); var ballBody2 = new p2.Body({ position: [0, 1], mass: 1, damping: 0, angularDamping: 0 }); ballBody2.addShape(circleShape2); world.addBody(ballBody2); // Create another platform var platformShape2 = new p2.Box({ width: 1, height: 1, material: new p2.Material() }); var platformBody2 = new p2.Body({ position: [0, -1], }); platformBody2.addShape(platformShape2); world.addBody(platformBody2); world.addContactMaterial(new p2.ContactMaterial(platformShape2.material, circleShape2.material, { restitution: 0 // This means no bounce! })); // New ball var circleShape3 = new p2.Circle({ radius: 0.5, material: new p2.Material() }); var ballBody3 = new p2.Body({ position: [2, 1], mass: 1, damping: 0, angularDamping: 0 }); ballBody3.addShape(circleShape3); world.addBody(ballBody3); var planeShape3 = new p2.Box({ width: 1, height: 1, material: new p2.Material() }); var plane3 = new p2.Body({ position:[2, -1], }); plane3.addShape(planeShape3); world.addBody(plane3); world.addContactMaterial(new p2.ContactMaterial(planeShape3.material, circleShape3.material, { restitution: 0, stiffness: 200, // This makes the contact soft! relaxation: 0.1 })); }); ``` -------------------------------- ### Getting Heightfield Segment Index in p2.js Source: https://github.com/schteppe/p2.js/blob/master/docs/files/src_shapes_Heightfield.js.html Calculates the index of the heightfield segment corresponding to a given X-coordinate. It divides the X-component of the `position` by the `elementWidth` and floors the result to get an integer index. ```JavaScript Heightfield.prototype.getSegmentIndex = function(position){ return Math.floor(position[0] / this.elementWidth); }; ``` -------------------------------- ### Initializing Game World and Objects - p2.js Platformer - JavaScript Source: https://github.com/schteppe/p2.js/blob/master/examples/canvas/character.html Sets up the HTML canvas and its 2D rendering context. It initializes the p2.js physics world, defines materials for ground, character, and boxes, and then creates and adds the main character, a ground plane, multiple static platforms, and movable boxes to the world. It also configures contact materials to define friction properties between different object types and sets up event listeners for beginContact, preSolve, and endContact to handle platform pass-through logic. ```JavaScript function init(){ // Init canvas canvas = document.getElementById("myCanvas"); w = canvas.width; h = canvas.height; ctx = canvas.getContext("2d"); ctx.lineWidth = 1/zoom; // Init world world = new p2.World(); world.defaultContactMaterial.friction = 0.5; world.setGlobalStiffness(1e5); // Init materials var groundMaterial = new p2.Material(), characterMaterial = new p2.Material(), boxMaterial = new p2.Material(); // Add a character body characterShape = new p2.Box({ width: 0.5, height: 1, material: characterMaterial }); characterBody = new p2.Body({ mass: 1, position:[0,3], fixedRotation: true, damping: 0.5 }); characterBody.addShape(characterShape); world.addBody(characterBody); // Add a ground plane planeShape = new p2.Plane({ material: groundMaterial }); planeBody = new p2.Body({ position:[0,-1] }); planeBody.addShape(planeShape); world.addBody(planeBody); // Add platforms var platformPositions = [[2,0],[0,1],[-2,2]]; for(var i=0; i characterBody.position[1]){ passThroughBody = otherBody; } else if(platformIndex != -1){ currentPlatform = platforms[platformIndex]; } }); // Disable any equations between the current passthrough body and the character world.on('preSolve', function (evt){ if(currentPlatform) characterBody.velocity[0] += currentPlatform.velocity[0]; for(var i=0; i