As3 box2d 复杂刚体外观的运用
很多时候一个多边形外观或圆形外观很难模拟复杂的事物
比如模拟一个鱼缸可能就需要拼接多个外观(b2Fixture)对象
box2d中的用法一个刚体可以绑定多个外观来进行模拟
需要注意的是跟据顶点坐标构建多边形时,都是按顺时针
package
{
import Box2D.Collision.b2WorldManifold;
import Box2D.Collision.Shapes.b2CircleShape;
import Box2D.Collision.Shapes.b2PolygonShape;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.b2Fixture;
import Box2D.Dynamics.b2FixtureDef;
import Box2D.Dynamics.b2World;
import comingx.Ball;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.system.IMEConversionMode;
/**
* ...
* @author My_style
*/
[SWF(width="600",height="480",frameRate="30")]
public class Main extends Sprite
{
[Embed(source = "./assets/container.png")]
private var ContainerImg:Class;
private const PIXEL_TO_METER:int = 30;
private var world:b2World;
private var containerBody:b2Body;
public function Main():void
{
var c:Bitmap = new ContainerImg();
addChild(c);
c.x = stage.stageWidth / 2-c.width/2;
c.y = stage.stageHeight / 2-c.height/2;
creatWorld();
creatBall();
creatContainer();
// creatDebugDraw();
addEventListener(Event.ENTER_FRAME, render);
}
private function creatWorld():void
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
world = new b2World(gravity, true);
world.SetWarmStarting(true);//刚体初始化的时候不受重力影响
}
private function creatContainer():void
{
var coords:Array=[
[[61,55],[77,67],[39,135],[23,124]],
[[23,124],[39,135],[25,220],[6,218]],
[[6,218],[25,220],[44,305],[28,312]],
[[28,312],[44,305],[94,372],[82,384]],
[[82,384],[94,372],[167,413],[161,425]],
[[161,425],[167,413],[250,424],[250,437]],
[[250,438],[250,424],[339,416],[341,429]],
[[341,430],[339,416],[411,383],[418,393]],
[[418,393],[411,383],[464,327],[478,334]],
[[478,334],[464,327],[489,254],[504,252]],
[[504,252],[489,254],[488,183],[504,177]],
[[504,177],[488,183],[470,112],[488,103]],
[[488,103],[470,112],[443,66],[465,63]],
[[77,67],[72,46],[436,43],[443,66]]
];
var containerBodyDef:b2BodyDef = new b2BodyDef();
containerBodyDef.type = b2Body.b2_staticBody;
containerBodyDef.position.Set(40 / PIXEL_TO_METER, 20 / PIXEL_TO_METER);
containerBody = world.CreateBody(containerBodyDef);
creatFixtures(coords);
}
private function creatFixtures(coords:Array):void
{
for (var i:int = 0; i < coords.length; i++ ){
var polygonShape:b2PolygonShape = new b2PolygonShape();
var shapeVertices:Array = creatVerticesArray(coords[i]);
polygonShape.SetAsArray(shapeVertices);
var fixtureDef:b2FixtureDef = new b2FixtureDef();
fixtureDef.density = 1.0;
fixtureDef.friction = 0.5;
fixtureDef.restitution = 1.0;
fixtureDef.shape = polygonShape;
containerBody.CreateFixture(fixtureDef);
}
}
private function creatVerticesArray(coords:Array):Array
{
if (coords.length < 3)
{
throw new Error("初始化顶点错误");
}
var verticeArray:Array = new Array();
for (var i:int = 0; i < coords.length; i++ )
{
var vertice:b2Vec2 = new b2Vec2();
vertice.Set(coords[i][0]/PIXEL_TO_METER, coords[i][1]/PIXEL_TO_METER);
verticeArray.push(vertice);
}
return verticeArray;
}
private function creatBall():void
{
for (var i:int = 0; i < 10; i++ ){
var ballDef:b2BodyDef = new b2BodyDef();
ballDef.type = b2Body.b2_dynamicBody;
ballDef.position.Set(stage.stageWidth / 2 / PIXEL_TO_METER, 100 / PIXEL_TO_METER);
var r:Number = Math.random() * 10 + 10;
var ballShape :b2CircleShape = new b2CircleShape(r/PIXEL_TO_METER);
var fixtureDef:b2FixtureDef = new b2FixtureDef();
fixtureDef.shape = ballShape;
fixtureDef.density = 1.0;
fixtureDef.friction = 0.8;
fixtureDef.restitution = 1;
var ballSprite:Sprite = new Ball(r, i + "");
addChild(ballSprite);
ballDef.userData = ballSprite;
var ballbody:b2Body = world.CreateBody(ballDef);
ballbody.CreateFixture(fixtureDef);
}
}
private function synchorBallSprite():void
{
var body:b2Body = world.GetBodyList();
while (body)
{
if (body.GetDefinition().userData is Ball)
{
var ballSprite:Ball = body.GetDefinition().userData as Ball;
ballSprite.x = body.GetTransform().position.x * PIXEL_TO_METER;
ballSprite.y = body.GetTransform().position.y * PIXEL_TO_METER;
ballSprite.rotation = body.GetTransform().GetAngle() * 180 / Math.PI;
}
body = body.GetNext();
}
}
private function creatDebugDraw():void
{
var debugSprite:Sprite = new Sprite();
addChild(debugSprite);
var debug:b2DebugDraw = new b2DebugDraw();
debug.SetSprite(debugSprite);
debug.SetLineThickness(1);
debug.SetAlpha(1);
debug.SetFillAlpha(.8);
debug.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
debug.SetDrawScale(PIXEL_TO_METER);
world.SetDebugDraw(debug);
}
private function render(e:Event):void
{
var timeStep:Number = 1 / 30;
var interation:int = 10;
synchorBallSprite();
world.Step(timeStep, interation, interation);
world.ClearForces();
//world.DrawDebugData();
}
}
}

浙公网安备 33010602011771号