2011年7月27日 星期三

Box2D flash tutorial III–add MovieClip

繼上一篇我們簡單的試範了如何在Box2D的world建立可動及固定的物件

並利用Box2d內建的Debug用的Shape在晝面上顯了結果

在實務上不會是只用那些簡單的形狀就要發佈實作品

這一篇我們來說明如何把設計的圖連結及Box2D的物件

前一篇我們為了簡化Box2D的基本結構未加上任何的使用者操作

這一篇我們加個Space按鈕,按一下我們就增加一個動態的物件(請先focus在flash上)

先來看一下成果(圖片未做去背處理)

程式如下:

  1: package
  2: {
  3: 	import Box2D.Collision.Shapes.b2CircleShape;
  4: 	import Box2D.Collision.Shapes.b2PolygonShape;
  5: 	import Box2D.Common.Math.b2Vec2;
  6: 	import Box2D.Dynamics.Contacts.b2CircleContact;
  7: 	import Box2D.Dynamics.Joints.*;
  8: 	import Box2D.Dynamics.Joints.b2LineJointDef;
  9: 	import Box2D.Dynamics.b2Body;
 10: 	import Box2D.Dynamics.b2BodyDef;
 11: 	import Box2D.Dynamics.b2DebugDraw;
 12: 	import Box2D.Dynamics.b2FixtureDef;
 13: 	import Box2D.Dynamics.b2World;
 14: 	
 15: 	import assets.BlueBirds;
 16: 	import assets.RedBird;
 17: 	
 18: 	import flash.display.MovieClip;
 19: 	import flash.display.Sprite;
 20: 	import flash.events.Event;
 21: 	import flash.events.KeyboardEvent;
 22: 	import flash.ui.Keyboard;
 23: 	
 24: 	public class Box2DMovieClip extends Sprite
 25: 	{
 26: 		private var _world:b2World;
 27: 		private var scale:uint = 1;
 28: 		
 29: 		public function Box2DMovieClip()
 30: 		{
 31: 			super();
 32: 			this.stage.addEventListener(KeyboardEvent.KEY_DOWN,function(event:KeyboardEvent):void{
 33: 				switch(event.keyCode){
 34: 					case Keyboard.SPACE:
 35: 						dynamicRect();
 36: 						break;
 37: 				}
 38: 			});
 39: 			this.addEventListener(Event.ENTER_FRAME,function():void{
 40: 				_world.Step(1/30,10,10);
 41: 				_world.ClearForces();
 42: 				//_world.DrawDebugData();
 43: 				
 44: 				updateDisplayList();
 45: 			});
 46: 			
 47: 			this._world = new b2World(new b2Vec2(0,30),true);
 48: 			
 49: 			//現在套上實際的Shape 故這裡就用不到了
 50: 			/*var dbgDraw:b2DebugDraw = new b2DebugDraw();
 51: 			dbgDraw=new b2DebugDraw();
 52: 			dbgDraw.SetSprite(this);
 53: 			//dbgDraw.SetDrawScale(30.0);
 54: 			dbgDraw.SetFillAlpha(0.5);
 55: 			dbgDraw.SetLineThickness(1.0);
 56: 			dbgDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
 57: 			
 58: 			_world.SetDebugDraw(dbgDraw);*/
 59: 			
 60: 			this.fixRect();
 61: 			this.dynamicRect();
 62: 		}
 63: 		
 64: 		private function fixRect():void
 65: 		{
 66: 			var bird:RedBird = new RedBird();
 67: 			this.addChild(bird);
 68: 			
 69: 			var bd:b2BodyDef=new b2BodyDef();
 70: 			bd.position.Set(150, 100);
 71: 			bd.userData = bird
 72: 			
 73: 			var rect:b2PolygonShape=new b2PolygonShape();
 74: 			rect.SetAsBox(1, 1);
 75: 			
 76: 			var body:b2Body=_world.CreateBody(bd);
 77: 			
 78: 			var fd:b2FixtureDef=new b2FixtureDef();
 79: 			fd.shape=rect;
 80: 			fd.friction=0.3;
 81: 			fd.density=0;
 82: 			
 83: 			body.CreateFixture(fd);
 84: 		}
 85: 		
 86: 		private function dynamicRect():void
 87: 		{
 88: 			var bird:BlueBirds = new BlueBirds();
 89: 			this.addChild(bird);
 90: 			
 91: 			var x:Number = Math.random() *1000;
 92: 			
 93: 			var bd:b2BodyDef=new b2BodyDef();
 94: 			bd.position.Set(x, 50);
 95: 			bd.type=b2Body.b2_dynamicBody;
 96: 			bd.userData =bird;
 97: 			
 98: 			var rect:b2PolygonShape=new b2PolygonShape();
 99: 			rect.SetAsBox(1, 1);
100: 			
101: 			var body:b2Body=_world.CreateBody(bd);
102: 			
103: 			var fd:b2FixtureDef=new b2FixtureDef();
104: 			fd.shape=rect;
105: 			fd.friction=0.3;
106: 			fd.density=0;
107: 			
108: 			body.CreateFixture(fd);
109: 		}
110: 		
111: 		private function updateDisplayList():void
112: 		{
113: 			for (var bb:b2Body=_world.GetBodyList(); bb; bb=bb.GetNext())
114: 			{
115: 				var viewComp:Sprite=bb.GetUserData() as Sprite;
116: 				if (viewComp)
117: 				{
118: 					viewComp.x=bb.GetPosition().x;
119: 					viewComp.y=bb.GetPosition().y;
120: 					viewComp.rotation=bb.GetAngle() * (180 / Math.PI);
121: 				}
122: 			}
123: 		}
124: 
125: 	}
126: }








這次我們因為要用到實際的設計,所以我先把DebugSprite先註解掉(當然不註解掉仍然可以跑,基於效能問題,建議還是若己經實際的設計,就不要再放上了)   line 42 及line50~58









先在fixeRect及dynamicRect的function中加上我們的在flash定義的Symbol(class)並需要先將其加到場景上,不需去設定座標,因為接下的function可以讓Box2D跟我們的設計物件做連動









接著我們在EnterFrame事件裡除了Box2D世界的滾動的呼叫外,最重的就是Box2D跟設計物件連動的function updateDisplayList









加上這個function後即可看到設計物件如何被Box2D帶著走了









P.S.其中line 15~16的類別是定義在flash裡面的,讀者可自行在flash定義自己喜歡的圖片

沒有留言:

張貼留言