box2d 绘制圆
在讓剛體聽我的——ApplyForce、ApplyImpulse、SetLinearVelocity一節中,來自天地會的sxl001問道如何創建圓形的邊界(Round Boundary),好吧,我用這個教程來回答他。
實際上Box2D中沒有專門創建圓弧的API (b2CircleDef創建的是實體圓形不是圓弧),所以試圖尋找這樣一個API的同學就放棄吧。結束了?坑爹啊!
哈哈,既然沒有圓弧API,我就想其他的方法嘛。還記得Box2D多邊形剛體的創建方法嘛?我們可以利用組合法,把多個形狀組合起來形成一個這你的形狀,當然也可以包括圓弧,下面的圖可以更好的解釋這一點。
圖中我用12個線段組合起來模擬一個圓形,當然你可以用24個、36個線段等等。線段數越多,圓形就越標準,同時也越消耗CPU,所以能模擬出圓形效果就可以了,不用追求完美。現在,你應該有思路了吧:
效果如下,點擊舞臺任意位置,創建剛體:
我在下面的代碼中做了詳細的注釋并highlight,我就不再講解了,大家看代碼吧!
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | package { ????import Box2D.Collision.b2AABB; ????import Box2D.Collision.Shapes.b2CircleDef; ????import Box2D.Collision.Shapes.b2PolygonDef; ????import Box2D.Collision.Shapes.b2ShapeDef; ????import Box2D.Common.Math.b2Vec2; ????import Box2D.Dynamics.b2Body; ????import Box2D.Dynamics.b2BodyDef; ????import Box2D.Dynamics.b2DebugDraw; ????import Box2D.Dynamics.b2World; ????import flash.display.Sprite; ????import flash.events.Event; ????import flash.events.MouseEvent; ????/** ???? * http://www.ladeng6666.com ???? * @author ladeng6666 ???? */ ????publicclassMainextendsSprite ????{ ????????privatevarworld:b2World; ????????privatevarbody:b2Body; ????????publicfunctionMain() ????????{ ????????????//創建box2D世界 ????????????createWorld(); ????????????//創建box2D調試圖 ????????????createDebug(); ????????????//創建剛體 ????????????createStuff(stage.stageWidth/2,0); ????????????//創建圓形邊界 ????????????createCircleGround(); ????????????//偵聽事件 ????????????addEventListener(Event.ENTER_FRAME,loop); ????????????stage.addEventListener(MouseEvent.MOUSE_DOWN,onStageMouseDown); ????????} ????????privatefunctiononStageMouseDown(e:MouseEvent):void ????????{ ????????????//在鼠標位置隨機創建一個圓形或矩形剛體 ????????????createStuff(mouseX,mouseY,Math.random()>0.5); ????????} ????????privatefunctionloop(e:Event):void ????????{ ????????????world.Step(1/30,10); ????????} ????????privatefunctioncreateWorld():void ????????{ ????????????//1.創建一個環境 ????????????varenvironment:b2AABB=newb2AABB(); ????????????environment.lowerBound=newb2Vec2(-100,-100); ????????????environment.upperBound=newb2Vec2(100,100); ????????????//2.聲明重力 ????????????vargravity:b2Vec2=newb2Vec2(0,10); ????????????//3.睡著的對象是否模擬 ????????????vardoSleep:Boolean=true; ????????????//4.創建b2World世界 ????????????world=newb2World(environment,gravity,doSleep); ????????} ????????privatefunctioncreateDebug():void ????????{ ????????????vardebugSprite:Sprite=newSprite(); ????????????addChild(debugSprite); ????????????vardebugDraw:b2DebugDraw=newb2DebugDraw(); ????????????debugDraw.m_sprite=debugSprite; ????????????debugDraw.m_drawScale=30.0; ????????????debugDraw.m_fillAlpha=0.5; ????????????debugDraw.m_lineThickness=1.0; ????????????debugDraw.m_drawFlags=b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit; ????????????world.SetDebugDraw(debugDraw); ????????} ????????privatefunctioncreateStuff(posX:Number,posY:Number,isBox:Boolean=true):void ????????{ ????????????//1.創建剛體需求b2BodyDef ????????????varbodyRequest:b2BodyDef=newb2BodyDef(); ????????????bodyRequest.position.Set(posX/30,posY/30);//記得米和像素的轉換關系 ????????????//2.Box2D世界工廠更具需求創建createBody()生產剛體 ????????????body=world.CreateBody(bodyRequest); ????????????//3.創建敢提形狀需求b2ShapeDef的子類 ????????????if(isBox){ ????????????????//創建矩形剛體形狀需求 ????????????????varshapeBoxRequest:b2PolygonDef=newb2PolygonDef(); ????????????????shapeBoxRequest.density=3; ????????????????shapeBoxRequest.friction=0.3; ????????????????shapeBoxRequest.restitution=0.2; ????????????????shapeBoxRequest.SetAsBox(1,1); ????????????????body.CreateShape(shapeBoxRequest); ????????????}else{ ????????????????//創建圓形剛體形狀需求 ????????????????varshapeCircleRequest:b2CircleDef=newb2CircleDef(); ????????????????shapeCircleRequest.density=3; ????????????????shapeCircleRequest.friction=0.3; ????????????????shapeCircleRequest.restitution=0.2; ????????????????shapeCircleRequest.radius=1; ????????????????body.CreateShape(shapeCircleRequest); ????????????} ????????????body.SetMassFromShapes(); ????????} ????????privatefunctioncreateCircleGround():void ????????{ ????????????varcenterX:Number=stage.stageWidth/2; ????????????varcenterY:Number=stage.stageHeight/2; ????????????//1.創建剛體需求b2BodyDef ????????????varbodyRequest:b2BodyDef=newb2BodyDef(); ????????????bodyRequest.position.Set(centerX/30,centerY/30);//記得米和像素的轉換關系 ????????????//2.Box2D世界工廠更具需求創建createBody()生產剛體 ????????????body=world.CreateBody(bodyRequest); ????????????//3.創建敢提形狀需求b2ShapeDef的子類 ????????????//定義線段的個數 ????????????varsegmentNum:Number=36; ????????????//定義圓形邊界的半徑 ????????????varradius:Number=200; ????????????//根據半徑和個數計算線段的長度 ????????????varsegmentlength:Number=radius *Math.sin(Math.PI/segmentNum); ????????????//for循環創建segmentNum個線段,合成圓形邊界 ????????????for(vari:int=0;i<segmentNum;i++){ ????????????????//定義形狀需求 ????????????????varshapeRequest:b2PolygonDef=newb2PolygonDef(); ????????????????//形狀的質量、摩擦系數、硬度 ????????????????shapeRequest.density=0; ????????????????shapeRequest.friction=0.3; ????????????????shapeRequest.restitution=0.2; ????????????????//計算每個線段的角度、坐標 ????????????????varangle:Number=i/segmentNum *Math.PI*2; ????????????????varbx:Number=radius *Math.cos(angle); ????????????????varby:Number=radius *Math.sin(angle); ????????????????//創建有方向的矩形剛體,合成總的圓形剛體 ????????????????shapeRequest.SetAsOrientedBox(5/30,segmentlength/30,newb2Vec2(bx/30,by/30),angle); ????????????????//4.b2Body剛體工廠根據需求createShape生產形狀 ????????????????body.CreateShape(shapeRequest); ????????????} ????????????body.SetMassFromShapes(); ????????} ????} } |
?源代碼下載
轉載于:https://www.cnblogs.com/cooka/p/3559614.html
總結
- 上一篇: 一个技术人的知识管理方法论
- 下一篇: UNIX环境高级编程笔记