您的位置:首页 > 其它

flash与物理引擎:创建碰撞墙

2011-06-12 23:37 375 查看





这个星期因为工作需要快速记录学习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);
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: