注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

清风的博客

我为人人,人人为我。

 
 
 

日志

 
 

Box2D入门基础  

2014-06-18 15:55:17|  分类: 【flash教程】 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Box2D入门基础之一

HelloBox2D.swf:
http://www.68design.net/download/200901/20090104173105763.swf

修改了Box2D提供的那个HelloWorld程序。具体如下:
package 
{
      import Box2D.Collision.*;
       import Box2D.Collision.Shapes.*;
       import Box2D.Common.Math.*;
       import Box2D.Common.*;
       import Box2D.Dynamics.*;
       import flash.events.Event;
       
       import flash.display.Sprite;
       import flash.display.StageScaleMode;
       import flash.events.Event;
       
       /**
       * ...
       * @author ywxgood
       * Blog:http://space.flash8.net/space/?628770
       */
       [SWF(backgroundColor="0x333333",width="550",height="400",frameRate="30")]
       public class HelloBox2D extends Sprite 
       {
              //定义一个边界盒,应尽量定义大一点
              private var worldAABB:b2AABB;
//定义一个虚拟物理世界,所有物理模拟均运行于次虚拟世界
              private var world:b2World;
              //定义比例,Box2D中是一米为长度单位,1m=30像素
              private var rate:Number = 30;
              
              //步长与积分次数
              private var m_timeStep:Number = 1 / rate;
              private var m_iteration:int = 10;
              
              //出现物体的数目
              private var numWidget:int = 10;
              
              //承载刚体
              private var body:b2Body;
              //刚体定义
private var bodyDef:b2BodyDef;
//方形物体定义
              private var boxShape:b2PolygonDef;
              //圆形物体定义
              private var circleShape:b2CircleDef;
              
              public function HelloBox2D()
              {
                     init();
              }
              
              private function init():void
              {
                     stage.scaleMode = StageScaleMode.NO_SCALE;
                     
                     addEventListener(Event.ENTER_FRAME, onFrame);
                     //创建边界盒
                     worldAABB = new b2AABB();
                     worldAABB.lowerBound.Set( -100.0, -100.0);
                     worldAABB.upperBound.Set(100.0, 100.0);
                     //重力加速度(300m/s^2)
                     var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
                     //当物体静止是是否处于休眠而节约cpu时间
                     var doSleep:Boolean = true;
                     //创建虚拟世界
                     world = new b2World(worldAABB, gravity, doSleep);
                     
                     //创建地面
                     createBox(550 / 2, 390,0, 275, 10, true);
                     //左右挡板
                     createBox(0,400/2,0,10,200,true);
                     createBox(550, 400 / 2,0, 10, 200, true);
                     //障碍物
                     createBox(Math.random() * 250 + 100, Math.random() * 150 + 100, Math.random()*360,Math.random() * 50, Math.random() * 50, true);
                     
                     for (var i:int = 0; i < numWidget;i++ )
                     {
                            var tempNum:Number = Math.random();
                            var halfWidth:Number = 10 + Math.random() * 50;
                            var halfHeight:Number = 10 + Math.random() * 50;
                            var xPos:Number = 100+Math.random() * (stage.stageWidth-100);
                            var yPos:Number = 0;
                            var radius:Number = 10 + Math.random() * 30;
                            var angle:Number = Math.random() * 360;
                            if (tempNum>.5)
                            {
                                   //创建方形物体
createBox(xPos,yPos,angle,halfWidth,halfHeight,false);
                            }
                            else
                            {
                                   //创建圆形物体
createCircle(xPos,yPos,radius);
                            }
                     }
              }
              
              private function createBox(xPos:Number,yPos:Number,angle:Number,halfWidth:Number,halfHeight:Number,isStatic:Boolean):void
              {
                     boxShape = new b2PolygonDef();
                     if (isStatic)
                     {
                            boxShape.density = 0.0;
                     }
                     else
                     {
                            boxShape.density = 2.0;
                     }
                     
                     boxShape.friction = 0.3;
                     boxShape.restitution = 0.3;
                     boxShape.SetAsBox(halfWidth / rate, halfHeight / rate);
                     bodyDef = new b2BodyDef();
                     bodyDef.angle = angle;
                     bodyDef.userData = new Box(halfWidth * 2, halfHeight * 2, 0xffffff * Math.random());
                     bodyDef.position.Set(xPos / rate, yPos/rate);
                     body = world.CreateBody(bodyDef);
                     body.CreateShape(boxShape);
                     body.SetMassFromShapes();
                     addChild(bodyDef.userData);
              }
              
              private function createCircle(xPos:Number,yPos:Number,radius:Number):void
              {
                     circleShape = new b2CircleDef();
                     circleShape.density = 7;
                     circleShape.friction = 0.2;
                     circleShape.restitution = 0.2;
                     circleShape.radius = radius / rate;
                     bodyDef = new b2BodyDef();
                     bodyDef.userData = new Ball(radius, 0xffffff * Math.random());
                     //bodyDef.userData.width = radius * 2;
                     //bodyDef.userData.height = radius * 2;
                     bodyDef.position.Set(xPos / rate, yPos / rate);
                     body = world.CreateBody(bodyDef);
                     body.CreateShape(circleShape);
                     body.SetMassFromShapes();
                     addChild(bodyDef.userData);
              }
              
              private function onFrame(e:Event):void
              {
                     world.Step(m_timeStep, m_iteration);
                     for (var b:b2Body = world.m_bodyList; b;b=b.m_next )
                     {
                            if (b.m_userData is Sprite)
                            {
                                   b.m_userData.x = b.GetPosition().x * rate;
                                   b.m_userData.y = b.GetPosition().y * rate;
                                   b.m_userData.rotation = b.GetAngle() * 180 / Math.PI;
                            }
                     }
              }
       }
       
}
说明:Box2D会自动管理各个物体的碰撞,弹跳等物理状态,我们只需要创建各种刚体。创建刚体可以通过b2BodyDef.userData来创建。b2Shape.SetAsBox(width,height)指的是物体的半宽和半高,所以在计算时都要乘以2。由于Box2D本身的限制,运算时要进行长度换算。
代码中的Box和Ball类都是注册中心在其几何中心,我就不提供代码了,这两个类主要是画矩形和圆形,很简单大家自己写。你也可以在FlashIDE中画出自己的方形和圆形来,然后给一个类名,然后从库里链接。

Box2D入门基础之二

ClickBox2DNew.swf:
http://www.68design.net/download/200901/20090104173531974.swf


前一篇中主要是程序自动随机创建物体,现在加入鼠标事件,在鼠标单击地面时产生随机物体。具体代码如下:
package 
{
      import Box2D.Collision.Shapes.*;
       import Box2D.Collision.*;
       import Box2D.Common.*;
       import Box2D.Common.Math.*;
       import Box2D.Dynamics.*;
       
       import flash.display.Sprite;
       import flash.display.StageScaleMode;
       import flash.display.StageAlign;
       import flash.events.Event;
       import flash.events.MouseEvent;
       /**
       * ...
       * @author ywxgood
       * Blog:http://space.flash8.net/space/?628770
       */
       [SWF(backgroundColor="0x333333",width="550",height="400",frameRate="30")]
       public class ClickBox2DNew extends Sprite
       {
              private var world:b2World;
              private var physScale:Number = 30.0;
              private var m_timeStep:Number = 1.0 / 30.0;
              private var m_iteration:int = 10;
              
              private var body:b2Body;
              private var bodyDef:b2BodyDef;
              private var boxShape:b2PolygonDef;
              private var circleShape:b2CircleDef;
              
              public function ClickBox2DNew()
              {
                     stage.align = StageAlign.TOP_LEFT;
                     stage.scaleMode = StageScaleMode.NO_SCALE;
                     init();
              }
              
              private function init():void
              {
                     addEventListener(Event.ENTER_FRAME, onFrame);
                     addEventListener(MouseEvent.MOUSE_DOWN, onDown);
                     
                     var worldAABB:b2AABB = new b2AABB();
                     worldAABB.lowerBound.Set( -100.0, -100.0);
                     worldAABB.upperBound.Set(100.0, 100.0);
                     var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
                     var doSleep:Boolean = true;
                     world = new b2World(worldAABB, gravity, doSleep);
                     
                     //创建地面
                     createBox(550 / 2, 390,0, 275, 10, true);
                     //左右挡板
                     createBox(0,400/2,0,10,200,true);
                     createBox(550, 400 / 2,0, 10, 200, true);
                     //障碍物
                     createBox(Math.random() * 250 + 100, Math.random() * 150 + 100, Math.random()*360,Math.random() * 50, Math.random() * 50, true);
                     createBox(Math.random() * 250 + 100, Math.random() * 150 + 100, Math.random()*360,Math.random() * 50, Math.random() * 50, true);
              }
              
              private function onFrame(e:Event):void
              {
                     world.Step(m_timeStep, m_iteration);
                     for (var b:b2Body = world.m_bodyList; b;b=b.m_next )
                     {
                            if (b.m_userData is Sprite)
                            {
                                   b.m_userData.x = b.GetPosition().x * physScale;
                                   b.m_userData.y = b.GetPosition().y * physScale;
                                   b.m_userData.rotation = b.GetAngle() * 180 / Math.PI;
                            }
                     }
              }
              
              private function onDown(e:MouseEvent):void
              {
                     
                     var tempNum:Number = Math.random();
                     var halfWidth:Number = 10 + Math.random() * 50;
                     var halfHeight:Number = 10 + Math.random() * 50;
                     var xPos:Number = 100+Math.random() * (stage.stageWidth-100);
                     var yPos:Number = 0;
                     var radius:Number = 10 + Math.random() * 30;
                     var angle:Number = Math.random() * 360;
                     if (tempNum>.5)
                     {
                            createBox(xPos,yPos,angle,halfWidth,halfHeight,false);
                     }
                     else
                     {
                            createCircle(xPos,yPos,radius);
                     }
              }
              
              private function createCircle(xPos:Number,yPos:Number,radius:Number):void
              {
                     circleShape = new b2CircleDef();
                     circleShape.density = 7;
                     circleShape.friction = 0.3;
                     circleShape.restitution = 0.4;
                     circleShape.radius = radius / physScale;
                     bodyDef = new b2BodyDef();
                     bodyDef.userData = new Ball(radius, 0xffffff * Math.random());
                     //bodyDef.userData.width = radius * 2;
                     //bodyDef.userData.height = radius * 2;
                     bodyDef.position.Set(xPos / physScale, yPos / physScale);
                     body = world.CreateBody(bodyDef);
                     body.CreateShape(circleShape);
                     body.SetMassFromShapes();
                     addChild(bodyDef.userData);
              }
              
              private function createBox(xPos:Number,yPos:Number,angle:Number,halfWidth:Number,halfHeight:Number,isStatic:Boolean):void
              {
                     boxShape = new b2PolygonDef();
                     if (isStatic)
                     {
                            boxShape.density = 0.0;
                     }
                     else
                     {
                            boxShape.density = 2.0;
                     }
                     
                     boxShape.friction = 0.3;
                     boxShape.restitution = 0.4;
                     boxShape.SetAsBox(halfWidth / physScale, halfHeight / physScale);
                     bodyDef = new b2BodyDef();
                     bodyDef.angle = angle;
                     bodyDef.userData = new Box(halfWidth * 2, halfHeight * 2, 0xffffff * Math.random());
                     bodyDef.position.Set(xPos / physScale, yPos/physScale);
                     body = world.CreateBody(bodyDef);
                     body.CreateShape(boxShape);
                     body.SetMassFromShapes();
                     addChild(bodyDef.userData);
              }
       }
       
}
说明:虽然是由主类监听单击事件,但在Box2D虚拟世界里是没有没有可以显示的类的~只要单击虚拟世界中任何一个物体就会触发单击事件,即产生一个随机方形或者圆形。

  评论这张
 
阅读(107)| 评论(3)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017