【游客模式】——注册会员,加入11RIA 闪客社区吧!一起见证Flash的再次辉煌……
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
转载:9RIA游戏开发者社区(天地会)
作者:ladeng6666(拉登大叔)
作者博客:http://www.ladeng6666.com/blog/
【Box2D系列教程-导航帖】—拉登大叔出品(总贴)
前些天有人问到Box2D如何实现浮力效果。今天我们就来学习一下。
Box2D浮力效果实现起来并不难。无非就是当刚体接触到水面时,对它施加一个向上的浮力。不过这个浮力受到刚体体积的影响,体积越大,收到的浮力也越大。同时还会因为受力点不在中心位置,而引起角度旋转。
额…。综合这些因素,用b2Body.ApplyForce实现起来似乎有些困难,所以我们要引入一个新的类:b2BuoyancyController。
b2BuoyancyController是b2Controller的一个子类,b2Controller类用来集成一些常用的功能,为用户免去复杂的算法。比如今天我们要学习的浮力效果,就可以用它的子类b2BuoyancyController来实现。
b2BuoyancyController和b2Body刚体不同。它是不可见的Box2D对象,也就是说,b2DebugDraw中不会绘制b2BuoyancyController的实例。但是当它与刚体发生碰撞时,Box2D会自动计算所浮力,并施加到刚体上,进而模拟漂浮效果。
b2BuoyancyController的构造函数非常简单,没有任何参数。
[Actionscript3] 纯文本查看 复制代码 var bc:b2BuoyancyController = new b2BuoyancyController();
它常用的公共属性有:
normal:指定水面法向量的方向,也就垂直水面的方向,通常保持默认的(0,-1)不变。
offset:指定水面的偏移量。注意它的方向与AS3中的y轴方向相反,也就是说如果我们想设置水面位置的y为200,那么offset属性应该是-200/30。
density:设置水的密度。确切的讲,是设置液体介质的密度。我们知道,只有漂浮物的密度小于液体介质的密度时,才可以漂浮在该介质上。(当然,要讲到刚结构的轮船可以漂浮在水上,就要讲到排水量要大于轮船的重量上了,话题就扯远啦,就此打住。)
linearDrag:设置漂浮物在水中移动的阻尼值。或者我们可以把它想象成水的粘稠度。这个属性值越大,漂浮物移动的速度越慢。
angularDrag:设置漂浮物在水中旋转的阻尼值。
velocity:设置水流动的速度。
b2BuoyancyController用起来也很简单,首先创建一个b2BuoyancyController实例。
[Actionscript3] 纯文本查看 复制代码 //实例化b2BuoyancyController对象
fuliController = new b2BuoyancyController();
然后设置它们的一些属性,比如水面的位置、方向、密度等等。
[Actionscript3] 纯文本查看 复制代码 //设置水面的法向量
fuliController.normal.Set(0, -1);
//设置水面的位置
fuliController.offset = -200 / m_physScale;
//设置水的密度,因为我们创建的刚体密度是3,所以水的密度要大于3
fuliController.density = 5.0;
//设置刚体在水中的移动阻尼
fuliController.linearDrag = 10;
//设置刚体在水中的旋转阻尼
fuliController.angularDrag = 6;
然后,将fuliController添加到b2world世界中
[Actionscript3] 纯文本查看 复制代码 //将水面、浮力控制器添加到世界中
world.AddController(fuliController);
创建刚体后,如果希望它与fuliController交互,实现漂浮效果,则用b2BanyancyController.AddBody方法,将漂浮物体添加到fuliController中
[Actionscript3] 纯文本查看 复制代码 //将刚体添加到水面上
fuliController.AddBody(body);
[Actionscript3] 纯文本查看 复制代码 是不是很简单?在下面的效果中,用鼠标拖动刚体,看看浮力的效果是不是很满意?!
完整的代码和注释如下:
[Actionscript3] 纯文本查看 复制代码 package
{
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.Controllers.b2BuoyancyController;
import Box2D.Dynamics.Controllers.b2Controller;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Sprite;
/**
* ...
* @author ladeng6666
*/
public class FuliTest extends Sprite
{
//声明世界变量
private var world:b2World;
//定义浮力控制器,也就是水面
private var fuliController:b2BuoyancyController;
//因为b2BuoyancyController是不可见的,所以我们专门为它定一个图层
private var controllerLayer:Sprite;
//像素和米的转换关系
private const m_physScale:Number = 30;
public function FuliTest()
{
//创建世界
initWorld();
//创建水面,浮力控制器
createController();
//创建刚体
for (var i:int = 0; i < 8; i++) {
createBodies();
}
}
private function createBodies():void
{
//创建刚体
var body:b2Body = LDEasyBox2D.createBox(world, Math.random()*400+50, Math.random()*50+30, Math.random()*20+30, Math.random()*20+30);
//将刚体添加到水面上
fuliController.AddBody(body);
}
//创建水面、即浮力控制器
private function createController():void
{
//实例化b2BuoyancyController对象
fuliController = new b2BuoyancyController();
//设置b2BuoyancyController对象的一些基本属性
//设置水面的法向量
fuliController.normal.Set(0, -1);
//设置水面的位置
fuliController.offset = -200 / m_physScale;
//设置水的密度,因为我们创建的刚体密度是3,所以水的密度要大于3
fuliController.density = 5.0;
//设置刚体在水中的移动阻尼
fuliController.linearDrag = 10;
//设置刚体在水中的旋转阻尼
fuliController.angularDrag = 6;
//将水面、浮力控制器添加到世界中
world.AddController(fuliController);
//因为b2BuoyancyController是不可见的,所以要为水面添加一个图层,专门绘制水面
controllerLayer = new Sprite();
addChild(controllerLayer);
controllerLayer.graphics.lineStyle(1,0x0000ff,1);
controllerLayer.graphics.moveTo(0,200);
controllerLayer.graphics.lineTo(550,200);
controllerLayer.graphics.lineStyle();
controllerLayer.graphics.beginFill(0x0000ff,0.2);
controllerLayer.graphics.drawRect(0, 200, 550, 300);
controllerLayer.graphics.endFill();
}
private function initWorld():void
{
//创建b2World世界
world = LDEasyBox2D.createWorld();
addChild(LDEasyBox2D.createDebug(world));
LDEasyBox2D.createWrapWall(world, this);
LDEasyBox2D.stage = this;
addEventListener(Event.ENTER_FRAME, loop);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseEventHandler);
}
private function mouseEventHandler(e:MouseEvent):void
{
//鼠标按下后拖动刚体,弹起后释放刚体
if (e.type == MouseEvent.MOUSE_DOWN) {
var body:b2Body = LDEasyBox2D.getBodyAtMouse(world);
if (body != null) {
LDEasyBox2D.startDragBody(world, body);
}
}else if (e.type == MouseEvent.MOUSE_UP) {
LDEasyBox2D.stopDragBody(world);
}
}
private function loop(e:Event):void
{
LDEasyBox2D.updateWorld(world);
}
}
}
下载:
OK 2012-09-22 Box2D漂浮效果.rar
(293.15 KB, 下载次数: 2)
|