2013-06-23 61 views
0

我試圖創造一些像牛頓的搖籃。但是當一個球擊中另一個球時,所有的球同時向相同的方向移動。我怎樣才能決定這個問題?我應該在createFixtureDef中創建球的另一個物理選項嗎?或者我需要使用一些特定的算法來轉換球之間的脈衝?牛頓在andengine上的搖籃,box2d

public class MainActivity extends SimpleBaseGameActivity implements IAccelerationListener, IOnAreaTouchListener
{

private static final int CAMERA_WIDTH = 720; 
private static final int CAMERA_HEIGHT = 480; 
private BitmapTextureAtlas mBitmapTextureAtlas; 

final String TAG = "States"; 
private Scene mScene; 

protected ITiledTextureRegion mBoxFaceTextureRegion; 
protected ITiledTextureRegion mCircleFaceTextureRegion; 

protected PhysicsWorld mPhysicsWorld; 
@Override 
public EngineOptions onCreateEngineOptions() { 
    final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT); 

    return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, 
      new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera); 
} 

@Override 
protected void onCreateResources() { 
    BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/"); 

    this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 64, 64, TextureOptions.BILINEAR); 
    this.mBoxFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "face_box_tiled.png", 0, 0, 2, 1); // 64x32 
    this.mCircleFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "face_circle_tiled.png", 0, 32, 2, 1); // 64x32 
    this.mBitmapTextureAtlas.load(); 

} 

@Override 
protected Scene onCreateScene() { 
    this.mEngine.registerUpdateHandler(new FPSLogger()); 

    this.mScene = new Scene(); 
    this.mScene.setBackground(new Background(0, 0, 0)); 
    //this.mScene.setOnSceneTouchListener(this); 

    this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false); 



    this.initJoints(mScene); 


    this.mScene.registerUpdateHandler(this.mPhysicsWorld); 
    this.mScene.setOnAreaTouchListener(this); 

    return this.mScene; 
} 

private void initJoints(final Scene pScene) { 
    final float centerY = CAMERA_HEIGHT/2; 

    final float spriteWidth = this.mBoxFaceTextureRegion.getWidth(); 
    final float spriteHeight = this.mBoxFaceTextureRegion.getHeight(); 

    final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(30, 0.2f, 0.2f); 

    for(int i = 0; i < 10; i++) { 
     final float anchorFaceX = 100 + i * spriteWidth ; 
     final float anchorFaceY = centerY; 

     final AnimatedSprite anchorFace = new AnimatedSprite(anchorFaceX, anchorFaceY, 
       this.mBoxFaceTextureRegion, this.getVertexBufferObjectManager()); 
     final Body anchorBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, 
       anchorFace, BodyType.StaticBody, 
       objectFixtureDef); 

     final AnimatedSprite movingFace = new AnimatedSprite(anchorFaceX, anchorFaceY + 150, 
       this.mCircleFaceTextureRegion, this.getVertexBufferObjectManager()) ; 
//  movingFace.setScale(1.2f); 
     final Body movingBody = PhysicsFactory.createCircleBody(this.mPhysicsWorld, 
         movingFace, BodyType.DynamicBody, objectFixtureDef); 
     movingFace.setUserData(movingBody); 

//  anchorFace.setScale(1.2f); 
     anchorFace.animate(200); 
     anchorFace.animate(200); 
     final Line connectionLine = new Line(anchorFaceX + spriteWidth/2, 
            anchorFaceY + spriteHeight/2, 
            anchorFaceX + spriteWidth/2, 
            anchorFaceY + spriteHeight/2, 
            this.getVertexBufferObjectManager()); 

     pScene.registerTouchArea(movingFace); 
     pScene.attachChild(connectionLine); 
     pScene.attachChild(anchorFace); 
     pScene.attachChild(movingFace); 

     this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(anchorFace, 
       anchorBody, true, true){ 
      @Override 
      public void onUpdate(final float pSecondsElapsed) { 
       super.onUpdate(pSecondsElapsed); 
       final Vector2 movingBodyWorldCenter = movingBody.getWorldCenter(); 
       connectionLine.setPosition(connectionLine.getX1(), connectionLine.getY1(), 
         movingBodyWorldCenter.x * PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT, 
         movingBodyWorldCenter.y * PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT); 
      } 
     }); 

     this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(movingFace, movingBody, true, true)); 
     final RevoluteJointDef revoluteJointDef = new RevoluteJointDef(); 
     revoluteJointDef.initialize(anchorBody, movingBody, anchorBody.getWorldCenter()); 
     this.mPhysicsWorld.createJoint(revoluteJointDef); 
    } 
} 
@Override 
public void onAccelerationAccuracyChanged(final AccelerationData pAccelerationData) { 
} 
@Override 
public void onAccelerationChanged(final AccelerationData pAccelerationData) { 
    final Vector2 gravity = Vector2Pool.obtain(pAccelerationData.getX(), pAccelerationData.getY()); 
    this.mPhysicsWorld.setGravity(gravity); 
    Vector2Pool.recycle(gravity); 
} 


public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, 
     final ITouchArea pTouchArea,final float pTouchAreaLocalX, 
     final float pTouchAreaLocalY) { 

    if(pSceneTouchEvent.isActionMove()) 
    { 
     float touchX = pSceneTouchEvent.getX(); 
     float touchY = pSceneTouchEvent.getY(); 
     Log.d(TAG, "move to in X" +touchX + "n Y " +touchY); 
     final AnimatedSprite anchorFace = (AnimatedSprite) pTouchArea; 
     final Body tochedBody = (Body)anchorFace.getUserData(); 
     //move sprite to xy 
     final float x = pSceneTouchEvent.getX(); 
     final float y = pSceneTouchEvent.getY(); 
     final float widthD2 = anchorFace.getWidth()/2; 
     final float heightD2 = anchorFace.getHeight()/2; 
     final float angle = tochedBody.getAngle(); // keeps the body angle 
     final Vector2 v2 = Vector2Pool.obtain((x + widthD2)/32, (y + heightD2)/32);   
     tochedBody.setTransform(v2, angle); 
     Vector2Pool.recycle(v2); 
     return true;   
    } 
    return false; 
} 

}

回答

1

不幸的是Box2D的是不是真的適合這個。

根據我的經驗,只要球不接觸對方就可以獲得一個或兩個揮杆動作。也就是說,每個球從它與每邊鄰居之間的一個非常小的間隙開始。這意味着,當它們碰撞時,每次僅使用兩個球來解決每次碰撞,對於碰撞到另一側(對於5個球)來說總共有4次碰撞,而不是將所有5個球作爲單個「島'。

問題是,定位需要非常精確,並且在幾次擺動之後,球偏離該位置,這樣最終會碰到一次涉及兩個以上球的碰撞。我只看到最多2-3次揮杆工作...