做软件的网站建设,微网站 无锡,住房城乡建设厅官方网站,无锡seo公司本文大部分内容是基于fengyun1989的博文#xff0c;自己只是加深巩固而已 Box2d是一款用于2d游戏的物理引擎。在这个世界里创造出的物体都更接近于真实世界的物体。 首先#xff0c;在项目添加Box2D.XNA.DLL。 新建一个页面BOX2DLayer并继承于CCLayer 重写init函数#xff0…本文大部分内容是基于fengyun1989的博文自己只是加深巩固而已 Box2d是一款用于2d游戏的物理引擎。在这个世界里创造出的物体都更接近于真实世界的物体。 首先在项目添加Box2D.XNA.DLL。 新建一个页面BOX2DLayer并继承于CCLayer 重写init函数并添加下面这个常量 由于平时我们都是用像素来描述游戏世界的而在box2d里是用“米”进行描述的。所以我们需要进行转化单位。设置一个常量然后在需要的位置上用像素除以它就可以转化成相对应的“米” public static double PTM_RATIO 32.0; 接下来就是开始创造世界了。 Vector2 gravity new Vector2(30.0f, 0.0f);bool doSleep true;world new World(gravity, doSleep); 首先我们需要模拟出一个重力gravity。这里用一个2维矢量模拟重力并设置了一个值doSleep用以指明对象不参与碰撞时是否可以“休眠”。一个休眠的对象将不会花费处理时间直到它与其实对象发生碰撞的时候才会“醒”过来。 这里说明一下物理世界的重力向量gravity。两个参数分别表示物理世界中的X轴和Y轴方向上的重力数值。“” “-”表示重力的方向 X轴正值表示向右Y轴正值表示向上 接下来该是为这个世界添加一些物体的时候了。 我在Android关于box2d应用中看到关于world创建一个物体的步骤 1.创建物体皮肤 PolygonDef 2.创建物体刚体BodyDef 3.通过皮肤和刚体创建一个物体 body bodybody.createBodyBodyDef body.createShapePolygonDef 在wp里略有不同。 BodyDef ballBodyDef new BodyDef();ballBodyDef.type BodyType.Dynamic;//动态类型ballBodyDef.positionnew Vector2((float)(100/PTM_RATIO),(float)(300/PTM_RATIO));ballBodyDef.userDataball;bodyworld.CreateBody(ballBodyDef);CircleShape circlenew CircleShape();circle._radius(float)(26.0/PTM_RATIO);FixtureDef ballShapeDefnew FixtureDef();ballShapeDef.shapecircle;ballShapeDef.density1.0f;//质量0代表静态的物体1代表运动物体ballShapeDef.friction0.0f;//摩擦ballShapeDef.restitution1.0f;//恢复力body.CreateFixture(ballShapeDef); 首先一个BodyDef接下来一个CircleShape 最后一个FixtureDef 相比Android的定义过程不过是将PolygonDef换成了一个Shape并将这个Shape付给一个Fixture最后由这个fixture完成body的创建。 现在详细说明一下上面代码的含义 我们指定body的类型为dynamic body。默认值是static body那意味着那个body不能被移动也不会参与仿真。很明显我们想让篮球参与仿真。 设置body的user data属性为篮球精灵。你可以设置任何东西但是你设置成精灵会很方便特别是当两个body碰撞的时候你可以通过这个参数把精灵对象取出来然后做一些逻辑处理。这里使用了一个不同的shape类型--circle shape。在这里我们需要为这个fixture指定一些参数 其中说明一下这个restitution恢复力。我们都知道在物理世界是能量守恒的。而这个恢复力就是能量守恒的体现之一。如果设置为1则物体在世界里的碰撞是完全弹性碰撞。我们也把球的摩擦力设置为0.这样可以防止球在碰撞的时候由于摩擦损失能量导致来回碰撞的过程中会有一点点偏差。 接下来我们必须为我们的世界设置一个围墙免得球跳出了“屏幕” View Code BodyDef groundBodyDef new BodyDef();groundBodyDef.position new Vector2(0, 0);Body groundBody world.CreateBody(groundBodyDef);PolygonShape groundBox new PolygonShape();//凸多边形FixtureDef boxShapeDef new FixtureDef();boxShapeDef.shape groundBox;groundBox.SetAsEdge(new Vector2(0, 0), new Vector2((float)(winSize.width / PTM_RATIO), 0));groundBody.CreateFixture(boxShapeDef);groundBox.SetAsEdge(new Vector2(0, 0), new Vector2(0, (float)(winSize.height / PTM_RATIO)));groundBody.CreateFixture(boxShapeDef);groundBox.SetAsEdge(new Vector2(0, (float)(winSize.height / PTM_RATIO)), new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)));groundBody.CreateFixture(boxShapeDef);groundBox.SetAsEdge(new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)),new Vector2((float)(winSize.width / PTM_RATIO), 0));groundBody.CreateFixture(boxShapeDef); 详细解释一下上面的代码 首先创建一个body定义结构体并且指定它应该放在左下角。然后使用world对象来创建body对象。注意这里一定要使用world对象来创建不能直接new因为world对象会做一些内存管理操作。 接着为屏幕的每一个边界创建一个多边形shape。这些“shape”仅仅是一些线段。注意我们把像素转换成了“meter”。通过除以之前定义的比率来实现的。 再创建一个fixture定义指定shape为polygon shape。 再使用body对象来为每一个shape创建一个fixture对象。注意一个body对象可以包含许许多多的fixture对象。 在完成上面之后。我们只是定义了物理世界还没开始进行物理模拟。所以还要对world设置物理模拟 world.Step(dt, 10, 10); 此函数表示让物理世界开始进行物理模拟后两个参数含义分别是“速度迭代次数”和“位置迭代次数”。设置他们的范围在8-10之间。这里的数字越小精度越小但是效率更高。数字越大仿真越精确但同时耗时更多。8一般是个折中数值。 这里要注意因为物理世界模拟具有持续性所以应该将设置放在线程中不断让物理世界进行模拟。 在init里添加一个this.schedule(tick)。这里的tick就是一个“线程” 在tick里除了添加物理模拟之外我们要使我们的小球精灵匹配物理仿真。因此我们遍历world对象里面的所有body然后看body的user data属性是否为空如果不为空就可以强制转换成精灵对象。接下来就可以根据body的位置来更新精灵的位置了。 View Code for (Body b world.GetBodyList(); b ! null; b b.GetNext()){if (b.GetUserData() ! null){CCSprite ballData (CCSprite)b.GetUserData();ballData.position new CCPoint((float)(b.GetPosition().X * PTM_RATIO),(float)(b.GetPosition().Y * PTM_RATIO));ballData.rotation -1 * MathHelper.ToDegrees(b.GetAngle());}} 最后在AppDelegate.cs里面的applicationDidFinishLaunching修改场景入口就可以看到效果了。 附上所有代码 View Code 1 class BOX2DLayer:CCLayer2 {3 //定义了一个“像素/米”的比率。当你在cocos2d里面指定一个body在哪个位置时你使用的单位要是米4 public static double PTM_RATIO 32.0;5 6 World world;7 Body body;8 CCSprite ball;9
10 public override bool init()
11 {
12 if (!base.init())
13 return false;
14 //获取窗口大小
15 CCSize winSize CCDirector.sharedDirector().getWinSize();
16
17 CCLabelTTF title CCLabelTTF.labelWithString(Boxing, Arial, 24);
18 title.position new CCPoint(winSize.width / 2, winSize.height / 2 - 50);
19 this.addChild(title, 1);
20
21 ball CCSprite.spriteWithFile(images/ball);
22 ball.position new CCPoint(0, 300);
23 this.addChild(ball);
24
25
26 Vector2 gravity new Vector2(30.0f, 0.0f);
27 bool doSleep true;
28 world new World(gravity, doSleep);
29
30 BodyDef groundBodyDef new BodyDef();
31 groundBodyDef.position new Vector2(0, 0);
32 Body groundBody world.CreateBody(groundBodyDef);
33 PolygonShape groundBox new PolygonShape();//凸多边形
34 FixtureDef boxShapeDef new FixtureDef();
35 boxShapeDef.shape groundBox;
36 groundBox.SetAsEdge(new Vector2(0, 0), new Vector2((float)(winSize.width / PTM_RATIO), 0));
37 groundBody.CreateFixture(boxShapeDef);
38 groundBox.SetAsEdge(new Vector2(0, 0), new Vector2(0, (float)(winSize.height / PTM_RATIO)));
39 groundBody.CreateFixture(boxShapeDef);
40 groundBox.SetAsEdge(new Vector2(0, (float)(winSize.height / PTM_RATIO)),
41 new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)));
42 groundBody.CreateFixture(boxShapeDef);
43 groundBox.SetAsEdge(new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)),
44 new Vector2((float)(winSize.width / PTM_RATIO), 0));
45 groundBody.CreateFixture(boxShapeDef);
46
47 BodyDef ballBodyDef new BodyDef();
48 ballBodyDef.type BodyType.Dynamic;//动态类型
49 ballBodyDef.positionnew Vector2((float)(100/PTM_RATIO),(float)(300/PTM_RATIO));
50 ballBodyDef.userDataball;
51
52 bodyworld.CreateBody(ballBodyDef);
53 CircleShape circlenew CircleShape();
54 circle._radius(float)(26.0/PTM_RATIO);
55
56 FixtureDef ballShapeDefnew FixtureDef();
57 ballShapeDef.shapecircle;
58 ballShapeDef.density1.0f;//质量0代表静态的物体1代表运动物体
59 ballShapeDef.friction0.0f;//摩擦
60 ballShapeDef.restitution1.0f;//恢复力
61 body.CreateFixture(ballShapeDef);
62
63
64 this.schedule(tick);
65 return true;
66 }
67
68 void tick(float dt)
69 {
70 world.Step(dt, 10, 10);
71
72 for (Body b world.GetBodyList(); b ! null; b b.GetNext())
73 {
74 if (b.GetUserData() ! null)
75 {
76 CCSprite ballData (CCSprite)b.GetUserData();
77 ballData.position new CCPoint((float)(b.GetPosition().X * PTM_RATIO),
78 (float)(b.GetPosition().Y * PTM_RATIO));
79 ballData.rotation -1 * MathHelper.ToDegrees(b.GetAngle());
80 }
81 }
82 }
83
84 public static new CCLayer node()
85 {
86 BOX2DLayer layer new BOX2DLayer();
87 if (layer.init())
88 {
89 return layer;
90 }
91 else
92 layer null;
93 return layer;
94 }
95
96 } 转载于:https://www.cnblogs.com/dieaz5/archive/2013/03/23/2977723.html