2014-03-30 1 views
0

as3 box2d 포트로 phsyics를 구현하려고합니다. 나는 현재 게임에서 특정 스프라이트에 대해 각각 b2body를 가지고 있으며 스프라이트의 위치를 ​​몸 위치에서 올바르게 업데이트 할 수 있습니다. 이 아래 그림에 표시됩니다 (debugDraw는 해당 spirtes에 입혔다 b2bodies의 위치를 ​​보여줍니다. 녹색 사각형은 벽과 바닥이다) 나는 또한 스프라이트의 회전이 반영 갖고 싶어,올바른 오프셋을 찾아서 회전 후 box2D 본문의 위치에 스프라이트를 조정하는 방법

enter image description here

그러나 b2bodies의 회전. 하지만, 스프라이트를 회전 한 후에, b2body 위치로 정확하게 중심을 맞추기 위해 사용하는 오프셋은 더 이상 정확하지 않습니다.

enter image description here

다음과 같이 스프라이트의 위치를 ​​업데이트하는 내 코드입니다 : 내가 올바른 X와 Y가 스프라이트를 회전 한 후 좌표 시스템 (플래시와 Box2D의) 사이의 오프셋을 찾을 수있는 방법

private function Update(update_event:TimerEvent):void 
      { 
       //step physics simulation forward 
       world.Step(0.025,10,10); 



       //update all objects in world 
       for each (var obj:HouseItemPhysicsObject in physicsObjects) 
       { 
        //update object's position from gravity if it is not being dragged 
        if(!obj.isHeld) 
        { 
         /*adjust rotation of sprite along with body -> yourMC.rotation = (yourMCbody.GetAngle() * 180/Math.PI) % 360; */ 
         obj.object.rotation = (obj.pBody.GetAngle() * 180/Math.PI) % 360; 

         if(obj.object.rotation >=5) 
         // set object's x position but adjust for offset between the cooridinate systems 
         obj.x = (obj.pBody.GetPosition().x* scaleFactor)-(obj.object.width/2); 
         //keep in horizontal bounds of screen 
         if(obj.x > GeneralConstants.GAME_WIDTH) 
         { 
          obj.x =GeneralConstants.GAME_WIDTH; 
         } 
         else if(obj.x < 0) 
         { 
          obj.x = 0; 
         } 

         // set object's x position but adjust for offset between the cooridinate systems in Flash and box2d 
         obj.y = (obj.pBody.GetPosition().y * scaleFactor)-(obj.object.height/2); 

         //keep in vertical bounds of the screen 
         if(obj.y > GeneralConstants.GAME_HEIGHT) 
         { 
          obj.y =GeneralConstants.GAME_HEIGHT; 
         } 
         else if(obj.x < 0) 
         { 
          obj.x = 0; 
         } 



         /*Draw shapes to see for debug*/ 
         //obj.DrawDebug(); 
         //trace("OBJECT's X is :" + obj.x + " Y is :" +obj.y); 
         trace("Object's rotation is:" + obj.object.rotation); 
        } 



       } 

       //move debug draw to front of display list 
       m_sprite.parent.setChildIndex(m_sprite, m_sprite.parent.numChildren - 5); 
       world.DrawDebugData(); 
      } 

을 b2Body에 따르면? 도와 주셔서 감사합니다.

EDIT : 명확성을 위해 은 개체 Sprite 클래스를 확장하는 클래스이며, 데이터 부재 _object는 영화 클립의 인스턴스이다. 당신이 물리적 객체의 당신의 스프라이트 속성을 부여 할 경우

+0

아니에요 익숙한 당신이 위치를 업데이트 할 때

obj.offset = new Point(-obj.width * 0.5, -obj.height * 0.5); 

, 단순히 회전에 의해 오프셋 회전에 추가 그리고 저는 연구를 할 수있는 위치에 있지 않습니다 : 그러나 Sprite를 b2body에게 아이처럼 붙일 수있는 능력이 있습니까? 그렇다면 추가하고 잊어 버리십시오. – Vesper

+0

그 시점에서'(obj.pBody.GetAngle() * 180/Math.PI) % 360' 값은 무엇입니까? 음수 값을 반환합니까? – bosnjak

답변

1

Box2D 객체는 기본적으로 가운데에 앵커 포인트를 가지며 플래시 객체의 경우 왼쪽 상단에 있습니다.

// create the image, center it, and add it to a holder Sprite 
var image:Bitmap = new Bitmap(objGraphicsBitmapData); 
image.x    = -image.width * 0.5; 
image.y    = -image.height * 0.5; 
var holder:Sprite = new Sprite; 
holder.addChild(image); 

지금 바로 위치와 회전을 설정 : 적절하게 배치하려면, 당신은 Bitmaps가/Sprite와 것은 그 중심을 무엇이든 랩

쉬운 계정 방법

에이를 취할 필요 당신이 현재하고있는 것처럼 당신은 괜찮습니다.

어려운 방법

개체의 회전에 따라 위치 오프셋을 수동으로 조정해야합니다. 간단한 회전 기능 : -이 일반적으로 new Point(-obj.width * 0.5, -obj.height * 0.5)입니다

public function rotate(p:Point, radians:Number, out:Point = null):Point 
{ 
    // formula is: 
    // x1 = x * cos(r) - y * sin(r) 
    // y1 = x * sin(r) + y * cos(r) 
    var sin:Number = Math.sin(radians); 
    var cos:Number = Math.cos(radians); 
    var ox:Number = p.x * cos - p.y * sin; 
    var oy:Number = p.x * sin + p.y * cos; 

    // we use ox and oy in case out is one of our points 
    if (out == null) 
     out = new Point; 
    out.x = ox; 
    out.y = oy; 
    return out; 
} 

먼저 우리는 개체의 오프셋을 저장해야합니다. 회전이 0 인 동안 이것을 재고해야하며 객체를 회전하면 widthheight 속성이 변경되므로 다음이 올바르게 작동하지 않습니다.

// get our object's position and rotation 
// NOTE: you'll probably need to adjust the position based on your pixels per meter value 
var pos:Point = new Point(obj.pBody.GetPosition().x, obj.pBody.GetPosition().y); // pos in screen coords 
var rotR:Number = obj.pBody.GetAngle();  // rotation in radians 
var rotD:Number = radiansToDegrees(rotR); // rotation in degrees 

// rotate our offset by our rotation 
var offset:Point = rotate(obj.offset, rotR); 

// set our position and rotation 
obj.x   = pos.x + offset.x; 
obj.y   = pos.y + offset.y; 
obj.rotation = rotD; 

다른 유용한 기능 : Box2D의와

public function degreesToRadians(deg:Number):Number 
{ 
    return deg * (Math.PI/180.0); 
} 
public function radiansToDegrees(rad:Number):Number 
{ 
    return rad * (180.0/Math.PI); 
} 
관련 문제