index.html页面
<?php ?> <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" > <title>Box2d Test</title> <script src="js/Box2d.min.js" type="text/javascript" charset="UTF-8"></script> <script src="js/box2d.js" type="text/javascript" charset="UTF-8"></script> </head> <body onload="init();"> <canvas id="canvas" width="640" height="480" style="border: 1px solid black;">Your browser does not support HTML5 Canvas</canvas> </body> </html>
box2d.js页面
var world; var scale = 30;//在canvas上的30像素表示Box2d世界中的1米 function init() { var gravity = new Box2D.Common.Math.b2Vec2(0,9.8);//表明重力加速度为9.8m/s平方,方向向下 var allowSleep = true;//允许静止的物体进入休眠状态,休眠物体不参与物理仿真计算 world = new Box2D.Dynamics.b2World(gravity,allowSleep); createFloor(); //创建一些具有简单形状的物体 createRectangularBody(); createCircularBody(); createSimplePolygonBody(); createComplexbody(); createResoluteJoint(); createSpecialBody(); listenForContact(); setupDebugDraw(); animate(); } function drawSpecialBody() { var positon = specialBody.GetPosition(); var angle = specialBody.GetAngle(); //移动并旋转物体 context.translate(positon.x*scale,positon.y*scale); context.rotate(angle); //绘制实心的圆面 context.fillStyle = "rgb(200,150,250);"; context.beginPath(); context.arc(0,0,30,0,2*Math.PI,false); context.fill(); //绘制两个矩形的眼睛 context.fillStyle = "rgb(255,255,255);"; context.fillRect(-15,-15,10,5); context.fillRect(5,-15,10,5); //绘制向上或向下的圆弧,根据生命值决定是否微笑 context.strokeStyle = "rgb(255,255,255);"; context.beginPath(); if(specialBody.GetUserData().life > 100){ context.arc(0,0,10,Math.PI,2*Math.PI,true); }else{ context.arc(0,10,10,Math.PI,2*Math.PI,false); } context.stroke(); context.rotate(-angle); context.translate(-positon.x*scale,-positon.y*scale); } var specialBody; function createSpecialBody() { var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.position.x = 450/scale; bodyDef.position.y = 0/scale; specialBody = world.CreateBody(bodyDef); specialBody.SetUserData({name:"special",life:250});//设置物体的自定义属性 var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); fixtureDef.density = 1.0; fixtureDef.friction = 0.5; fixtureDef.restitution = 0.5; fixtureDef.shape = new Box2D.Collision.Shapes.b2CircleShape(30/scale); var fixture = specialBody.CreateFixture(fixtureDef); } function listenForContact() { /* Box2D.Dynamics.b2ContactListener 对象的方法 BeginContact():两个物体开始接触时被调用 EndContact():两个物体结束接触时被调用 PostSolve():求解器完成后调用,进行碰撞检测时很有用 PreSolve():在求解器求解前调用 */ var listener = new Box2D.Dynamics.b2ContactListener; listener.PostSolve = function(contact,impulse){ var body1 = contact.GetFixtureA().GetBody(); var body2 = contact.GetFixtureB().GetBody(); if(body1 == specialBody || body2 == specialBody){ var impulseAlongNormal = impulse.normalImpulses[0]; specialBody.GetUserData().life -= impulseAlongNormal; console.log("The special body was in a collision with impulse",impulseAlongNormal,"and its life has now become", specialBody.GetUserData().life); } }; world.SetContactListener(listener); } //创建转动关节 function createResoluteJoint() { //定义第一个物体 var bodyDef1 = new Box2D.Dynamics.b2BodyDef(); bodyDef1.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef1.position.x = 480/scale; bodyDef1.position.y = 50/scale; var body1 = world.CreateBody(bodyDef1); var fixtureDef1 = new Box2D.Dynamics.b2FixtureDef(); fixtureDef1.density = 1.0; fixtureDef1.friction = 0.5; fixtureDef1.restitution = 0.5; fixtureDef1.shape = new Box2D.Collision.Shapes.b2PolygonShape(); fixtureDef1.shape.SetAsBox(50/scale,10/scale); body1.CreateFixture(fixtureDef1); var bodyDef2 = new Box2D.Dynamics.b2BodyDef(); bodyDef2.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef2.position.x = 470/scale; bodyDef2.position.y = 50/scale; var body2 = world.CreateBody(bodyDef2); //创建第二个载具并向物体中添加多边形形状 var fixtureDef2 = new Box2D.Dynamics.b2FixtureDef(); fixtureDef2.density = 1.0; fixtureDef2.friction = 0.5; fixtureDef2.restitution = 0.5; fixtureDef2.shape = new Box2D.Collision.Shapes.b2PolygonShape(); var points = [ new Box2D.Common.Math.b2Vec2(0,0), new Box2D.Common.Math.b2Vec2(40/scale,50/scale), new Box2D.Common.Math.b2Vec2(50/scale,100/scale), new Box2D.Common.Math.b2Vec2(-50/scale,100/scale), new Box2D.Common.Math.b2Vec2(-40/scale,50/scale) ]; fixtureDef2.shape.SetAsArray(points,points.length); body2.CreateFixture(fixtureDef2); //创建接合点连接body1和body2 var jointDef = new Box2D.Dynamics.Joints.b2RevoluteJointDef(); var jointCenter = new Box2D.Common.Math.b2Vec2(470/scale,50/scale); jointDef.Initialize(body1,body2,jointCenter);//指出接入物及接入点 world.CreateJoint(jointDef);//创建接入点 并加入世界 } //创建由两个物体组成的物体 function createComplexbody() { var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.position.x = 350/scale; bodyDef.position.y = 50/scale; var body = world.CreateBody(bodyDef); var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); fixtureDef.density = 1.0; fixtureDef.friction = 0.5; fixtureDef.restitution = 0.7; fixtureDef.shape = new Box2D.Collision.Shapes.b2CircleShape(40/scale); body.CreateFixture(fixtureDef); fixtureDef.shape = new Box2D.Collision.Shapes.b2PolygonShape(); var points = [ new Box2D.Common.Math.b2Vec2(0,0), new Box2D.Common.Math.b2Vec2(40/scale,50/scale), new Box2D.Common.Math.b2Vec2(50/scale,100/scale), new Box2D.Common.Math.b2Vec2(-50/scale,100/scale), new Box2D.Common.Math.b2Vec2(-40/scale,50/scale) ]; fixtureDef.shape.SetAsArray(points,points.length); body.CreateFixture(fixtureDef); } function createSimplePolygonBody() { var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.position.x = 230/scale; bodyDef.position.y = 50/scale; var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); fixtureDef.density = 1; fixtureDef.friction = 0.5; fixtureDef.restitution = 0.2; fixtureDef.shape = new Box2D.Collision.Shapes.b2PolygonShape(); var points = [ new Box2D.Common.Math.b2Vec2(0,0), new Box2D.Common.Math.b2Vec2(40/scale,50/scale), new Box2D.Common.Math.b2Vec2(50/scale,100/scale), new Box2D.Common.Math.b2Vec2(-50/scale,100/scale), new Box2D.Common.Math.b2Vec2(-40/scale,50/scale) ]; fixtureDef.shape.SetAsArray(points,points.length); var body = world.CreateBody(bodyDef); var fixture = body.CreateFixture(fixtureDef); /* 所有的坐标都是相对于物体原点的.第一个点(0,0)开始于物体的原点,将被放置在物体的位置(230,50). 无须闭合多边形,Box2D会自动帮我们完成它. 所有的顶点必须以顺时针方向定义 */ } function createRectangularBody() { var bodydef =new Box2D.Dynamics.b2BodyDef(); bodydef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodydef.position.x = 40 / scale; bodydef.position.y = 100 / scale; var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); fixtureDef.density = 1;//密度 fixtureDef.friction = 0.5;//摩擦系数 fixtureDef.restitution = 0.8;//弹性恢复系数 fixtureDef.shape = new Box2D.Collision.Shapes.b2PolygonShape(); fixtureDef.shape.SetAsBox(30/scale,50/scale); var body = world.CreateBody(bodydef); var fixture = body.CreateFixture(fixtureDef); } function createCircularBody() { var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.position.x = 130/scale; bodyDef.position.y = 100/scale; var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); fixtureDef.density = 1; fixtureDef.friction = 0.5; fixtureDef.restitution = 0.7; fixtureDef.shape = new Box2D.Collision.Shapes.b2CircleShape(30/scale); var body = world.CreateBody(bodyDef); var fixture = body.CreateFixture(fixtureDef); } var timeStep = 1 / 60; //按照Box2D手册建议的迭代数,速度是8,位置是3 var velocityIterations = 8; var positionIterations = 3; function animate() { world.Step(timeStep,velocityIterations,positionIterations); world.ClearForces(); world.DrawDebugData(); if(specialBody && specialBody.GetUserData().life <= 0){ world.DestroyBody(specialBody);//将物体从世界中移除 specialBody = undefined; console.log("The special body was destroyed"); } if(specialBody){ drawSpecialBody(); } setTimeout(animate,timeStep); } function createFloor() { var bodyDef = new Box2D.Dynamics.b2BodyDef; bodyDef.type = Box2D.Dynamics.b2Body.b2_staticBody; bodyDef.position.x = 640/2/scale; bodyDef.position.y = 450/scale; //fixture用来向body添加shape以实现碰撞检测 var fixtureDef = new Box2D.Dynamics.b2FixtureDef; fixtureDef.density = 1.0; fixtureDef.friction = 0.5; fixtureDef.restitution = 0.2; fixtureDef.shape = new Box2D.Collision.Shapes.b2PolygonShape; fixtureDef.shape.SetAsBox(320/scale,10/scale); var body = world.CreateBody(bodyDef); var fixture = body.CreateFixture(fixtureDef); } var context; function setupDebugDraw() { context = document.getElementById(‘canvas‘).getContext(‘2d‘); var debugDraw = new Box2D.Dynamics.b2DebugDraw(); //使用canvas绘图环境来绘制调试画面 debugDraw.SetSprite(context); //设置绘图比例 debugDraw.SetDrawScale(scale); //填充的透明度为0.3 debugDraw.SetFillAlpha(0.3); //线条的宽度为1 debugDraw.SetLineThickness(1.0); //绘制所有的shape和joint debugDraw.SetFlags(Box2D.Dynamics.b2DebugDraw.e_shapeBit | Box2D.Dynamics.b2DebugDraw.e_jointBit); //设置调制绘图模式 world.SetDebugDraw(debugDraw); }
原文地址:http://quietnight.blog.51cto.com/7163892/1917952