flash与物理引擎 创建碰撞墙
这个星期因为工作需要快速记录学习box2d的引擎,box2d使用并不是很容易和方便,虽然资料已经很丰富,只是新的版本2.1a不能很好的兼容下面。网上很多代码有效果,但是多少调试起来 过往的案例都会出现出错。使用2.1a版本 发现已经处理了,多少和网上之前写的都不一样。
今晚记录就是四边墙创建如下:
//创建墙 private function createWall(x:Number, y:Number, width:Number, height:Number):void { //演算 var bodyDef:b2BodyDef = new b2BodyDef(); bodyDef.position.Set(x / worldScale, y / worldScale); var box:b2PolygonShape = new b2PolygonShape(); box.SetAsBox(width/2/worldScale, height/2/worldScale); var fixtureDef:b2FixtureDef = new b2FixtureDef(); fixtureDef.shape = box; fixtureDef.friction=0.5;//摩擦力设置 fixtureDef.restitution=0.5;//弹力设置 var body:b2Body = world.CreateBody(bodyDef); body.CreateFixture(fixtureDef); }
今晚发现,原来可以为墙设置摩擦力,密度,弹力。这两个特性
fixtureDef.density=10;//密度设置
fixtureDef.friction=0.5;//摩擦力设置
fixtureDef.restitution=0.5;//弹力设置
那么在拖拽物体的时候 会有一些弹性回弹的效果出现了。
而在使用的过程中 发现拖拽产生延时缓冲,所以网上一些办法是设置两个参数,而至于具体原因还有待继续去深入。
mouseJoinDef.dampingRatio = 0;
mouseJoinDef.frequencyHz = 100;
在写出这个实验的时候,多少有很多疑惑,例如设置密度有什么作用?多少范围为合理,弹力设置值范围多少算合理?
密度*体积=质量 f=ma ,那么多产生的力会不会增大?
这几天书写当中,不妨可以封装一些常见的刚体对象。如box ,circle,wall
function drawBox(x:Number,y:Number,width:Number,height:Number,isDynamic:Boolean):void
function drawCircle(x:Number,y:Number,radius:Number,isDynamic:Boolean):void
function createWall(x:Number, y:Number, width:Number, height:Number):void
同样可以封装一下鼠标拖动,这些方面资料可以参考quickbox2D的作者封装的类。实现的物理效果会很容易,对于一些交互很实用。
剩下还有群组,刷选,等等还没实现。
好,只能继续探讨。
package { import flash.display.Sprite; import flash.events.*; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; import Box2D.Dynamics.Joints.*; import Box2D.Dynamics.Controllers.*; public class HelloWorld extends Sprite { //程序入口,创建一个世界 private var world:b2World = new b2World(new b2Vec2(0,10.0),true); private var worldScale:int = 30;//30像素=1米 private static const vesion:String="box2d for 2.1a"; private var mouseJoint:b2MouseJoint; public function HelloWorld() { debugDraw(); //创建墙 createWall(10,180,20,360); createWall(630,180,20,360); createWall(320,10,640,20); createWall(320,350,640,20); for(var i:int=0;i<10;i++) { drawBox(Math.random()*250,100,20,20,true);//绘制矩形 drawCircle(Math.random()*100,100,20,true);//绘制圆形 } addEventListener(Event.ENTER_FRAME, updateHandler); stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler); } //绘制一个矩形 private function drawBox(x:Number,y:Number,width:Number,height:Number,isDynamic:Boolean):void { var bodyDef:b2BodyDef= new b2BodyDef(); bodyDef.position.Set(x/worldScale, y/worldScale); if (isDynamic) { bodyDef.type = b2Body.b2_dynamicBody; } var box:b2PolygonShape = new b2PolygonShape(); box.SetAsBox(width/2/worldScale, height/2/worldScale); var fixtureDef:b2FixtureDef = new b2FixtureDef(); fixtureDef.shape = box; var body:b2Body = world.CreateBody(bodyDef); body.CreateFixture(fixtureDef); } //绘制一个圆 private function drawCircle(x:Number,y:Number,radius:Number,isDynamic:Boolean):void { var bodyDef:b2BodyDef= new b2BodyDef(); bodyDef.position.Set(x/worldScale, y/worldScale); if (isDynamic) { bodyDef.type = b2Body.b2_dynamicBody;//设置动态类型 } //创建圆形形状 var circle:b2CircleShape=new b2CircleShape(radius/worldScale); var fixtureDef:b2FixtureDef = new b2FixtureDef(); fixtureDef.shape = circle; var body:b2Body = world.CreateBody(bodyDef); body.CreateFixture(fixtureDef); } //创建墙 private function createWall(x:Number, y:Number, width:Number, height:Number):void { //演算 var bodyDef:b2BodyDef = new b2BodyDef(); bodyDef.position.Set(x / worldScale, y / worldScale); var box:b2PolygonShape = new b2PolygonShape(); box.SetAsBox(width/2/worldScale, height/2/worldScale); var fixtureDef:b2FixtureDef = new b2FixtureDef(); fixtureDef.shape = box; fixtureDef.friction=0.5;//摩擦力设置 fixtureDef.restitution=0.5;//弹力设置 var body:b2Body = world.CreateBody(bodyDef); body.CreateFixture(fixtureDef); } private function debugDraw():void { var _debugDraw:b2DebugDraw=new b2DebugDraw(); var sprite:Sprite=new Sprite(); addChild(sprite); _debugDraw.SetSprite(sprite); _debugDraw.SetDrawScale(worldScale); _debugDraw.SetFlags(b2DebugDraw.e_shapeBit); world.SetDebugDraw(_debugDraw); } //交互的过程由四个步骤完成: //第一步:获取鼠标单击处的刚体。 //第二步:创建鼠标关节。 //第三步:控制鼠标关节。 //第四步:销毁鼠标关节。 private function getBodyAtMouse(includeStatic:Boolean=false):b2Body { var mouseXWorldPhys:Number = (mouseX)/worldScale; var mouseYWorldPhys:Number = (mouseY)/worldScale; var mousePVec:b2Vec2 = new b2Vec2(); mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys); var aabb:b2AABB = new b2AABB(); aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001); aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001); var body:b2Body = null; function query(fix:b2Fixture):Boolean { var shape:b2Shape = b2Fixture(fix).GetShape(); if (fix.GetBody().GetType() != b2Body.b2_staticBody || includeStatic) { var inside:Boolean = b2Shape(shape).TestPoint(fix.GetBody().GetTransform(),mousePVec); if (inside) { body = fix.GetBody(); return false; } } return true; } world.QueryAABB(query, aabb); return body; } private function onMouseDownHandler(event:MouseEvent):void { var mouseJoinDef:b2MouseJointDef; var body:b2Body = this.getBodyAtMouse(); if (body) { mouseJoinDef = new b2MouseJointDef(); mouseJoinDef.bodyA = world.GetGroundBody(); mouseJoinDef.bodyB = body; mouseJoinDef.target.Set((mouseX / worldScale), (mouseY / worldScale)); mouseJoinDef.maxForce = 10000; mouseJoinDef.dampingRatio = 0; mouseJoinDef.frequencyHz = 100; this.mouseJoint = (world.CreateJoint(mouseJoinDef) as b2MouseJoint); } stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler); } private function onMouseUpHandler(event:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler); if (this.mouseJoint) { world.DestroyJoint(this.mouseJoint);//销毁鼠标关节 this.mouseJoint = null; } } private function updateHandler(event:Event):void { world.Step(1/30,10,10); //world.ClearForces(); world.DrawDebugData(); //拖拽部分 if (mouseJoint) { var mouseXWorldPhys:Number = mouseX / worldScale; var mouseYWorldPhys:Number = mouseY / worldScale; var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys,mouseYWorldPhys); mouseJoint.SetTarget(p2); } } }}
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow