HTML5 Canvas+Box2D实现物理重力效果

浏览量:756 | 分类:前端开发HTML5/JS | 发布日期:2011-09-28

最近研究了一下著名的box2d,
Box2D引擎很强大,能够用JS实现物理效果,
很适合做游戏开发
但是中文资料实在太少了,看国外关于box2d的文章还要翻墙,
可以看一下Box2d C++版本的中文手册,能了解一下box2d的相关知识

可以看下本文 栗子DEMO
Box2dJS DEMO

下面综合一些知识简单讲解一下

首先创建一个AABB类,设置重力,创建一个有重力的世界

function setupWorld(){
    //1. 设置有效区域大小 - b2AABB 类 (左上角向量,右下角向量)
    worldAABB = new b2AABB();
    worldAABB.minVertex.Set(-1000, -1000);	//左上角
    worldAABB.maxVertex.Set(1000, 1000); 	//右下角

    //2. 定义重力 - 2D向量 - b2Vec2 类 (x,y)
    gravity = new b2Vec2(0, 300);

    //3. 忽略休眠的物体
    var doSleep = true;

    //4. 创建世界 - b2World
    World = new b2World(worldAABB, gravity, doSleep);
}

在世界中添加“刚体”,和重力物体
这里我们添加一个地面盒,4个重力体

定义形状流程:
1.定义形状:Shape = new b2CircleDef()
形状参数:表面摩擦力,弹性,密度
2.物体定义: BodyDef = new b2BodyDef();
物体加入形状 BodyDef.AddShape(Shape);
物体参数: 位置
3.在重力世界创建物体
World = World.CreateBody(Shape);

//addBodys()
function addBodys(){

    //1. 定义形状	b2CircleDef,b2BoxDef,b2PolyDef 类
	var Shape1 = new b2CircleDef();	//Shape1:圆形
	Shape1.radius = 20;					//半径
	Shape1.localPosition.Set(0, 0);		//偏移量
    Shape1.density = 1.0;				//密度
    Shape1.restitution = .3;			//弹性
    Shape1.friction = 1;				//摩擦力
        
	var Shape2 = new b2PolyDef();	//Shape2:多边形
	Shape2.vertexCount = 3;						//顶点数为5
	Shape2.vertices[0] = new b2Vec2(0,-20);		//顶点1
	Shape2.vertices[1] = new b2Vec2(23.10,20);	//顶点2
	Shape2.vertices[2] = new b2Vec2(-23.10,20);	//顶点3
	Shape2.localPosition.Set(0, 30);	//偏移量
    Shape2.density = 1.0;				//密度
    Shape2.restitution = .3;			//弹性
    Shape2.friction = 1;				//摩擦力

	//2. 定义物体	b2BodyDef 类
    var BodyDef1 = new b2BodyDef();
    BodyDef1.position.Set(200, 100);	//设置物体的初始位置
    BodyDef1.AddShape(Shape1);			//物体中加入Shape1
    BodyDef1.AddShape(Shape2);			//物体中加入Shape2

	//3. 将物体添加至world
    Body = World.CreateBody(BodyDef1);	//在世界中创建物体

	
	//...可用同样流程继续添加物体,再定义一块地板
	var Shape3 = new b2BoxDef();	//Shape3:矩形
	
    Shape3.extents.Set(300, 5);			//定义矩形高、宽
	var BodyDef2 = new b2BodyDef();
    BodyDef2.position.Set(200, 500);	//设置物体的初始位置
    BodyDef2.AddShape(Shape3);			//物体中加入Shape3
    Body2 = World.CreateBody(BodyDef2);	//在世界中创建物体
	
	
	// 定义物体
	var vbox =  new b2BoxDef();
	vbox.extents.Set(10,90);
	var bodyVbox = new b2BodyDef();
	bodyVbox.position.Set(150,450);
	bodyVbox.AddShape(vbox);
	vbox.density = 1.0;				//密度
    vbox.restitution = .3;			//弹性
    vbox.friction = 1;				//摩擦力
	bodyVbox = World.CreateBody(bodyVbox);
	
	var vbox1 =  new b2BoxDef();
	vbox1.extents.Set(10,60);
	vbox1.density = 1.0;			//密度
    vbox1.restitution = .3;			//弹性
    vbox1.friction = 1;				//摩擦力
	var bodyVbox1 = new b2BodyDef();
	bodyVbox1.position.Set(200,450);
	bodyVbox1.AddShape(vbox1);
	bodyVbox1 = World.CreateBody(bodyVbox1);
	
	var vbox2 =  new b2BoxDef();
	vbox2.extents.Set(10,30);		
	vbox2.density = 1.0;			//密度
    vbox2.restitution = .3;			//弹性
    vbox2.friction = 1;				//摩擦力
	var bodyVbox2 = new b2BodyDef();
	bodyVbox2.position.Set(280,470); 
	bodyVbox2.AddShape(vbox2);
	bodyVbox2 = World.CreateBody(bodyVbox2);
	
	
}

 

绘制重力世界

//计算和绘制世界的下一帧
function step(){
	var dt = 1/60;
	//迭代次数,影响物体碰撞的计算精度,太高会导致速度过慢
	var iterations = 10;

	//计算dt秒之后世界中物体的位置
	World.Step(dt,iterations);

	//绘制世界
	drawWorld();

}


//绘制世界
function drawWorld(){
	//绘制之前将上一帧的内容清除
	context.clearRect(0, 0, canvasWidth, canvasHeight);
	//遍历世界中的物体
    for (var b = World.m_bodyList; b; b = b.m_next) {
		//遍历物体中的形状
        for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
            this.drawShape(s);	//绘制一个形状
        }
    }
}

上一篇: Html5-Canvas-JS模拟抛物线

下一篇: Mysql Limit 优化,百万至千万级快速分页 复合索引

评论

过客   2011-10-09 21:30:46

你不是用惯了ie6吗。。。。如何研究html5啊

过客   2012-02-02 23:29:51