[Box2D]五.和刚体交互
发布时间:2020-12-15 18:08:49 所属栏目:百科 来源:网络整理
导读:点这看效果 此demo包含以下内容: 1.通过鼠标选择刚体 2.销毁刚体 3.对刚体设置自定义属性(包括皮肤) 4.循环遍历世界中的所有刚体 5.获取刚体信息 详细的解释请看代码 皮肤下载 skin1.swc package {import Box2D.Collision.Shapes.b2PolygonShape;import Box
点这看效果 此demo包含以下内容: 1.通过鼠标选择刚体 2.销毁刚体 3.对刚体设置自定义属性(包括皮肤) 4.循环遍历世界中的所有刚体 5.获取刚体信息 详细的解释请看代码 皮肤下载skin1.swc package { import Box2D.Collision.Shapes.b2PolygonShape; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2Fixture; import Box2D.Dynamics.b2FixtureDef; import Box2D.Dynamics.b2World; import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; [SWF(width="410",height="480")] public class Interact extends Sprite { private var stageWidth:Number = 410; //舞台宽度 private var stageHeight:Number = 480; //舞台高度 private var backgroundColor:uint = 0x333333; //背景色 private var world:b2World; //Box2D世界 private var worldScale:Number = 30; //一米等于30像素 private var timeStep:Number = 1 / 30; //时间步,世界将在每一个时间步被更新 //只是定义了时间步还不够。在每一步,每一个物理实体(physic entity)根据作用 //于自身的作用力来更新(不包括睡眠状态)。处理这项任务的算法叫约束解算器 //(constraint solver)。它是基于循环每一个约束然后解算来进行的,一次一个。 private var velIterations:int = 10; //速率约束解算器 private var posIterations:int = 10; //位置约束解算器 private var info:TextField; //info实时显示头像的坐标,速度,角度 public function Interact() { drawBackground(); createTip(); createInfo(); createWorld(); //创建地面 var floorAsset:DisplayObject = new FloorAsset(); createRectBody( {x:floorAsset.width/2,y:stageHeight - floorAsset.height/2,width:floorAsset.width,height:floorAsset.height,asset:floorAsset,id:"floor"} ); //创建左边界 createRectBody({x:1,y:stageHeight/2,width:2,height:stageHeight,id:"leftBound"}); //创建右边界 createRectBody({x:stageWidth - 1,id:"rightBound"}); //创建砖块 var brickAsset:Sprite = new BrickAsset1(); createRectBody({x:175,y:435,width:brickAsset.width,height:brickAsset.height,asset:brickAsset,type:b2Body.b2_dynamicBody,canDestroy:true,id:"brick1"}); brickAsset = new BrickAsset2(); createRectBody({x:265,id:"brick2"}); brickAsset = new BrickAsset3(); createRectBody({x:220,y:405,id:"brick3"}); brickAsset = new BrickAsset4(); createRectBody({x:220,y:375,id:"brick4"}); brickAsset = new BrickAsset5(); createRectBody({x:205,y:345,id:"brick5"}); brickAsset = new BrickAsset6(); createRectBody({x:220,y:300,id:"brick6"}); //创建头像 var iconAsset:IconAsset = new IconAsset(); createRectBody({x:220,y:80,width:iconAsset.width,height:iconAsset.height,asset:iconAsset,id:"userIcon"}); addEventListener(Event.ENTER_FRAME,onUpdate); stage.addEventListener(MouseEvent.CLICK,onStageClick); } private function drawBackground():void { graphics.beginFill(backgroundColor); graphics.drawRect(0,stageWidth,stageHeight); graphics.endFill(); } private function createTip():void { var tip:TextField = new TextField(); var format:TextFormat = new TextFormat(); format.size = 14; format.color = 0xFFFFFF; tip.autoSize = TextFieldAutoSize.LEFT; tip.defaultTextFormat = format; tip.text = "砖块可销毁(点击它)"; addChild(tip); tip.x = (stageWidth - tip.width) / 2; } private function createInfo():void { info = new TextField(); var format:TextFormat = new TextFormat(); format.size = 14; format.color = 0xFFFFFF; info.autoSize = TextFieldAutoSize.LEFT; info.defaultTextFormat = format; addChild(info); } private function createWorld():void { var gravity:b2Vec2 = new b2Vec2(0,9.81); //重力 //世界中的刚体静止时,可以允许他们进入睡眠状态,睡眠的刚体无需模拟 var sleep:Boolean = true; world = new b2World(gravity,sleep); } private function onStageClick(event:MouseEvent):void { var x:Number = mouseX / worldScale; var y:Number = mouseY / worldScale; //世界的QueryPoint方法查询世界中所有的夹具,找出在点上的夹具, //然后如果有夹具在鼠标点击的点上,我们可以说我们点击了一个夹具。 world.QueryPoint(queryCallback,new b2Vec2(x,y)); } //在鼠标点击的点上的夹具。因为一个点上可以有不止一个的夹具(试 //想一下重叠的staitc类型的刚体),如果你希望检查下一个夹具,那么你需要 //让函数返回true,或者返回false将停止检查。 private function queryCallback(fixture:b2Fixture):Boolean { var touchedBody:b2Body = fixture.GetBody(); var userData:Object = touchedBody.GetUserData(); //获取自定义的刚体信息 if(userData.canDestroy == true) { world.DestroyBody(touchedBody); //销毁刚体 removeChild(userData.asset); } //我们假设只可以有一个夹具在鼠标点击的点上 //所以return false return false; } private function createRectBody(data:Object):void { var bodyDef:b2BodyDef = new b2BodyDef(); //刚体定义 if(data.type != undefined) { bodyDef.type = data.type; //刚体类型默认为静态 } bodyDef.position.Set(data.x/worldScale,data.y/worldScale);//设置刚体坐标,Box2D坐标用米表示 bodyDef.userData = new Object(); if(data.id != undefined) { bodyDef.userData.id = data.id; } if(data.asset != undefined) { bodyDef.userData.asset = data.asset;//为刚体设置皮肤 } if(data.canDestroy != undefined) { bodyDef.userData.canDestroy = data.canDestroy;//点击时,是否能销毁 }else { bodyDef.userData.canDestroy = false; } var polygonShape:b2PolygonShape = new b2PolygonShape(); //创建多边形 polygonShape.SetAsBox(data.width/2/worldScale,data.height/2/worldScale);//轴对称的矩形,半宽长和半高长 var fixtureDef:b2FixtureDef = new b2FixtureDef(); //夹具(fixture)用于将形状绑定到刚体上 if(data.density != undefined) { //密度 fixtureDef.density = data.density; }else { fixtureDef.density = 1; } if(data.restitution != undefined) { //弹性系数 fixtureDef.restitution = data.restitution; }else { fixtureDef.restitution = 0.1; } if(data.friction != undefined) { //摩擦系数 fixtureDef.friction = data.friction; }else { fixtureDef.friction = 0.1; } fixtureDef.shape = polygonShape; var body:b2Body = world.CreateBody(bodyDef); //创建刚体 body.CreateFixture(fixtureDef); if(data.asset != undefined) { addChild(data.asset); data.asset.x = body.GetPosition().x * worldScale; data.asset.y = body.GetPosition().y * worldScale; } } private function onUpdate(e:Event):void { world.Step(timeStep,velIterations,posIterations); world.ClearForces(); //GetBodyList()方法获得世界刚体列表并返回列表的第一个刚体. //使用GetNext()方法获得列表的下一个刚体,但是如果你的刚 //体已经到达了刚体列表的末端,这时GetNext()方法将返回null for (var body:b2Body = world.GetBodyList(); body; body = body.GetNext()) { if(body.GetUserData()) { var x:Number = body.GetPosition().x * worldScale; var y:Number = body.GetPosition().y * worldScale; var angle:Number = body.GetAngle() * 180 / Math.PI; //弧度转为度 if(body.GetUserData().id == "userIcon") { info.text = "头像刚体的属性n坐标: "; info.appendText(x.toFixed(1)); info.appendText(","); info.appendText(y.toFixed(1)); info.appendText("n角度: "); info.appendText(angle.toFixed(1)); info.appendText("n速度: "); //GetLinearVelocity()方法获得刚体中心的线速度,然后返回 //一个b2Vec2对象,它代表水平和垂直速度,单位是米每秒 var v:b2Vec2 = body.GetLinearVelocity(); var vx:Number = v.x * worldScale; info.appendText(vx.toFixed(1)); info.appendText(","); var vy:Number = v.y * worldScale; info.appendText(vy.toFixed(1)); } if(body.GetUserData().asset) { body.GetUserData().asset.x = x; body.GetUserData().asset.y = y; body.GetUserData().asset.rotation = angle; } } } } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |