۱۳۹۱/۰۳/۰۹

Drag کردن اجسام در Box2D

قبلا در مورد Box2D مطلب کوتاهی نوشتم در مثال زیر روش drag کردن اجسام را نشان می دهم.

با تغییر در کد خط 89 یعنی مقدار mouse_joint.maxForce مي توان روي قىرت پرتاب اجسام توسط mouse اثر گذاشت.


package {
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.MouseEvent;
 import Box2D.Dynamics.*;
 import Box2D.Collision.*;
 import Box2D.Collision.Shapes.*;
 import Box2D.Common.Math.*;
 import Box2D.Dynamics.Joints.*;
 public class cratetest extends Sprite {
  public var m_world:b2World;
  public var m_iterations:int = 10;
  public var m_timeStep:Number = 1/30;
  public var mousePVec:b2Vec2 = new b2Vec2();
  public var real_x_mouse:Number;
  public var real_y_mouse:Number;
  public var pixels_in_a_meter = 30;
  public var worldAABB:b2AABB = new b2AABB();
  public var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
  public var mouseJoint:b2MouseJoint;
  public function cratetest() {
   addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
   stage.addEventListener(MouseEvent.MOUSE_DOWN, on_mouse_down);
   stage.addEventListener(MouseEvent.MOUSE_UP, on_mouse_up);
   worldAABB.lowerBound.Set(-100.0, -100.0);
   worldAABB.upperBound.Set(100.0, 100.0);
   m_world = new b2World(worldAABB, gravity, true);
   var body:b2Body;
   var bodyDef:b2BodyDef;
   var boxDef:b2PolygonDef;
   bodyDef = new b2BodyDef();
   bodyDef.position.Set(8.5, 13.5);
   boxDef = new b2PolygonDef();
   var ground_width = 8.5;
   var ground_height = 0.5;
   boxDef.SetAsBox(ground_width, ground_height);
   boxDef.friction = 0.3;
   boxDef.density = 0;
   bodyDef.userData = new floor();
   bodyDef.userData.width = ground_width * 2 * pixels_in_a_meter;
   bodyDef.userData.height = ground_height * 2 * pixels_in_a_meter;
   addChild(bodyDef.userData);
   body = m_world.CreateBody(bodyDef);
   body.CreateShape(boxDef);
   body.SetMassFromShapes();
   for (var i:int = 1; i <=5; i++) {
    bodyDef = new b2BodyDef();
    bodyDef.position.x = Math.random() * 15 + 1;
    bodyDef.position.y = Math.random();
    var crate_width:Number = 1.5;
    var crate_height:Number = 1.5;
    boxDef = new b2PolygonDef();
    boxDef.SetAsBox(crate_width, crate_height);
    boxDef.density = 1.0;
    boxDef.friction = 0.5;
    boxDef.restitution = 0.2;
    bodyDef.userData = new crate();
    bodyDef.userData.width = crate_width * 2 * pixels_in_a_meter;
    bodyDef.userData.height = crate_height * 2* pixels_in_a_meter;
    body = m_world.CreateBody(bodyDef);
    body.CreateShape(boxDef);
    body.SetMassFromShapes();
    addChild(bodyDef.userData);
   }
  }
  public function Update(e:Event):void {
   m_world.Step(m_timeStep, m_iterations);
   if (mouseJoint) {
    var mouseXWorldPhys = mouseX/pixels_in_a_meter;
    var mouseYWorldPhys = mouseY/pixels_in_a_meter;
    var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
    mouseJoint.SetTarget(p2);
   }
   for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) {
    if (bb.m_userData is Sprite) {
     bb.m_userData.x = bb.GetPosition().x * pixels_in_a_meter;
     bb.m_userData.y = bb.GetPosition().y * pixels_in_a_meter;
     bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
    }
   }
  }
  public function on_mouse_down(evt:MouseEvent):void {
   var body:b2Body = GetBodyAtMouse();
   if (body) {
    var mouse_joint:b2MouseJointDef = new b2MouseJointDef;
    mouse_joint.body1 = m_world.GetGroundBody();
    mouse_joint.body2 = body;
    mouse_joint.target.Set(mouseX/pixels_in_a_meter, mouseY/pixels_in_a_meter);
    mouse_joint.maxForce = 10000;
    mouse_joint.timeStep = m_timeStep;
    mouseJoint = m_world.CreateJoint(mouse_joint) as b2MouseJoint;
   }
  }
  public function on_mouse_up(evt:MouseEvent):void {
   if (mouseJoint) {
    m_world.DestroyJoint(mouseJoint);
    mouseJoint = null;
   }
  }
  public function GetBodyAtMouse(includeStatic:Boolean=false):b2Body {
   real_x_mouse = (stage.mouseX)/pixels_in_a_meter;
   real_y_mouse = (stage.mouseY)/pixels_in_a_meter;
   mousePVec.Set(real_x_mouse, real_y_mouse);
   var aabb:b2AABB = new b2AABB();
   aabb.lowerBound.Set(real_x_mouse - 0.001, real_y_mouse - 0.001);
   aabb.upperBound.Set(real_x_mouse + 0.001, real_y_mouse + 0.001);
   var k_maxCount:int = 10;
   var shapes:Array = new Array();
   var count:int = m_world.Query(aabb, shapes, k_maxCount);
   var body:b2Body = null;
   for (var i:int = 0; i < count; ++i) {
    if (shapes[i].m_body.IsStatic() == false || includeStatic) {
     var tShape:b2Shape = shapes[i] as b2Shape;
     var inside:Boolean = tShape.TestPoint(tShape.m_body.GetXForm(), mousePVec);
     if (inside) {
      body = tShape.m_body;
      break;
     }
    }
   }
   return body;
  }
 }
}


  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google
  • Furl
  • Reddit
  • StumbleUpon
  • Donbaleh
  • Technorati
  • Balatarin
  • twitthis

۱۳۹۱/۰۳/۰۴

مقدمه اب براستارلینگ - قسمت اول

استارلینگ را می شناسید؟

یک موتور سورس باز برای ساخت بازی در فلش که از قابلیت های جدید فلش پلیر (Stage3D) استفاده می کند.Stage3D عليرغم نامش توانايي ايجاد پروژه های دو بعدی را نیز دارد . در مثال زیر نحوه انجام یک پروژه دوبعدی ساده را باهم مرور می کنیم.

برای راحتی بیشتر بهتر است از نسخه 4.6 فلاش بیلدر استفاده کنید.

ابتدا مانند تصویر زیر یک پروژه اکشن اسکریپت را شروع کنید:


بعد از نامگذاری پروژه و تعیین مسیر ذخیره آن بجای دکمه Finish  روی دکمه Next كليك كنيد.


در تب Source Path مسیر پوشه Starling\src را ىر پوشه کتابخانه استارلینگ که قبلا دانلود کرده اید را وارد نمایید..

خب حالا وقت کد نویسی است خیلی ساده یک نمونه از استارلینگ ایجاد کنید :
package{
 import flash.display.Sprite;
 import starling.core.Starling;
 
 [SWF(width="500", height="500", frameRate="60", backgroundColor="#000000")]
 public class Main extends Sprite{
  private var starling:Starling;
  public function Main(){
   starling = new Starling(Game, stage);
   starling.start();
  }
 }
}

وسپس فایل Game.as :

package{
 import starling.display.Image;
 import starling.display.Sprite;
 import starling.events.Event;
 
 public class Game extends Sprite{
  [Embed(source = "background.png")]
  private static const Background:Class;
 
  [Embed(source = "greencircle.png")]
  private static const GreenCircle:Class;
 
  private var greenCircleVector:Vector.=new Vector.();
  private var xSpeedVector:Vector.=new Vector.();
  private var ySpeedVector:Vector.=new Vector.();
 
  public function Game(){
   addEventListener(Event.ADDED_TO_STAGE,setup);
  }
 
  private function setup(e:Event):void{
   var background:Image = Image.fromBitmap(new Background());
   addChild(background);  
   for(var i:uint=0;i<10;i++){
    var greenCircle:Image=Image.fromBitmap(new GreenCircle());
    greenCircle.x=Math.random()*500;
    greenCircle.y=Math.random()*500;
    var randomDirection:Number=Math.random()*2*Math.PI;
    addChild(greenCircle);
    greenCircleVector.push(greenCircle);
    xSpeedVector.push(2*Math.cos(randomDirection));
    ySpeedVector.push(2*Math.sin(randomDirection));
   } 
   stage.addEventListener(Event.ENTER_FRAME, update);
  }
 
  private function update(e:Event):void{
   for(var i:uint=0;i500){
     greenCircleVector[i].x-=500;
    }
    if(greenCircleVector[i].x<0){
     greenCircleVector[i].x+=500;
    }
    if(greenCircleVector[i].y>500){
     greenCircleVector[i].y-=500;
    }
    if(greenCircleVector[i].y<0){
     greenCircleVector[i].y+=500;
    }
   }
  }
 }
}

در کد بالا به نحوه استفاده از کلاسهای رویداد و اسپرایت که از بسته استارلینگ گرفته شده اند دقت کنید. این کلاسها جایگزین معادل فلش خود شده اند. نمونه اولیه ایجاد شد. در بخش های بعدی کار را برای تولید بازی ادامه خواهیم داد.
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google
  • Furl
  • Reddit
  • StumbleUpon
  • Donbaleh
  • Technorati
  • Balatarin
  • twitthis

۱۳۹۱/۰۲/۲۹

نکاتی در مورد اجسام در Box2D

Box2d يك موتور سورس باز شبیه ساز فیزیک در فلاش است که دارای یک نسخه ++C هم مي باشد.
یکی از مفاهیم کلیدی در این موتور مفهموم بادی یا جسم است که در حقیقت یک موجودیت واحد بدون انعطاف است و به سه صورت زیر دیده می شود.

1- جسم غیر ایستا : این نوع جسم تحت تاثیر نیروهای محیطی قرار می گیرد و به برخوردها واکنش نشان می دهد.
2- جسم ایستا : دقیقا بر عکس جسم غیر ایستا است. تحت اثر هیچ نیرویی قرار نمی گیرد و کاملا بی حرکت است.
3 - جسم کینماتیک : در حقیفت یک نوع ترکیبی است از یک طرف مانند جسم ایستا به نیروهای محیطی واکنش نشان نمی دهد و از طرفی دیگر مانند جسم غیر ایستا متحرک است. یعنی با سرعتی مشخص در یک مسیر خطی حرکت می کند .

مثال زیر مطلب را بهتر شرح می دهد:



package {
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.utils.Timer;
 import flash.events.TimerEvent;
 import Box2D.Dynamics.*;
 import Box2D.Collision.*;
 import Box2D.Collision.Shapes.*;
 import Box2D.Common.Math.*;
 public class Main extends Sprite {
  private var world:b2World=new b2World(new b2Vec2(0,5),true);
  private var worldScale:Number=30;
  private var timer:Timer=new Timer(1000);
  public function Main() {
   debugDraw();
   for (var i:int=0; i<10; i++) {
    // building 10 kinematic spheres
    // five on the left side of the stage moving right
    // five on the right side of the stage moving left
    kinematicSphere(640*(i%2),50+40*i,10,(1-2*(i%2))*(Math.random()*10+5));
   }
   addEventListener(Event.ENTER_FRAME,updateWorld);
   // I will make a dynamic sphere fall from the top of the stage
   // at every second
   timer.start();
   timer.addEventListener(TimerEvent.TIMER,addSphere);
  }
  private function addSphere(e:TimerEvent):void {
   dynamicSphere(320,-10,10);
  }
  private function dynamicSphere(pX:int,pY:int,r:Number):void {
   var bodyDef:b2BodyDef=new b2BodyDef();
   bodyDef.position.Set(pX/worldScale,pY/worldScale);
   bodyDef.type=b2Body.b2_dynamicBody;
   var circleShape:b2CircleShape=new b2CircleShape(r/worldScale);
   var fixtureDef:b2FixtureDef=new b2FixtureDef();
   fixtureDef.shape=circleShape;
   var theDynamic:b2Body=world.CreateBody(bodyDef);
   theDynamic.CreateFixture(fixtureDef);
  }
  private function kinematicSphere(pX:int,pY:int,r:Number,hV):void {
   var bodyDef:b2BodyDef=new b2BodyDef();
   bodyDef.position.Set(pX/worldScale,pY/worldScale);
   // ************************** HERE IS THE MAGIC LINE ************************** \\
   bodyDef.type=b2Body.b2_kinematicBody;
   var circleShape:b2CircleShape=new b2CircleShape(r/worldScale);
   var fixtureDef:b2FixtureDef=new b2FixtureDef();
   fixtureDef.shape=circleShape;
   var theKinematic:b2Body=world.CreateBody(bodyDef);
   theKinematic.CreateFixture(fixtureDef);
   // look, I can set a linear velocity
   theKinematic.SetLinearVelocity(new b2Vec2(hV,0));
  }
  private function debugDraw():void {
   var debugDraw:b2DebugDraw=new b2DebugDraw();
   var debugSprite:Sprite=new Sprite();
   addChild(debugSprite);
   debugDraw.SetSprite(debugSprite);
   debugDraw.SetDrawScale(worldScale);
   debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
   debugDraw.SetFillAlpha(0.5);
   world.SetDebugDraw(debugDraw);
  }
  private function updateWorld(e:Event):void {
   world.Step(1/30,10,10);
   world.ClearForces();
   for (var b:b2Body = world.GetBodyList(); b; b = b.GetNext()) {
    // changing kinematic sphere linear velocity if it touches stage edges
    if (b.GetType()==b2Body.b2_kinematicBody) {
     var xSpeed:Number=b.GetLinearVelocity().x;
     var xPos:Number=b.GetWorldCenter().x*worldScale;
     if ((xPos<10&&xSpeed<0) || (xPos>630&&xSpeed>0)) {
      xSpeed*=-1;
      b.SetLinearVelocity(new b2Vec2(xSpeed,0));
     }
    }
    else {
     if (b.GetWorldCenter().y*worldScale>480) {
      world.DestroyBody(b);
     }
    }
   }
   world.DrawDebugData();
  }
 }
}
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google
  • Furl
  • Reddit
  • StumbleUpon
  • Donbaleh
  • Technorati
  • Balatarin
  • twitthis