2012-02-21 22 views
0

我設置的對象上的線性衝動,它的動作罰款,但是當我按下電源按鈕,然後再來比賽,我發現我的對象旋轉速度減少。setAngularVelocity在onGameResume降低,在onPause

package com.algo; 

import org.anddev.andengine.engine.Engine; 
import org.anddev.andengine.engine.camera.Camera; 
import org.anddev.andengine.engine.options.EngineOptions; 
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation; 
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy; 
import org.anddev.andengine.entity.primitive.Rectangle; 
import org.anddev.andengine.entity.scene.Scene; 
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener; 
import org.anddev.andengine.entity.scene.background.ColorBackground; 
import org.anddev.andengine.entity.shape.Shape; 
import org.anddev.andengine.entity.sprite.AnimatedSprite; 
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector; 
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory; 
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld; 
import org.anddev.andengine.extension.physics.box2d.util.constants.PhysicsConstants; 
import org.anddev.andengine.input.touch.TouchEvent; 
import org.anddev.andengine.opengl.texture.TextureOptions; 
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas; 
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory; 
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion; 
import org.anddev.andengine.sensor.accelerometer.AccelerometerData; 
import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener; 
import org.anddev.andengine.ui.activity.BaseGameActivity; 
import org.anddev.andengine.util.Debug; 
import org.anddev.andengine.util.MathUtils; 
import org.anddev.andengine.util.constants.TimeConstants; 

import android.hardware.SensorManager; 

import com.badlogic.gdx.math.Vector2; 
import com.badlogic.gdx.physics.box2d.Body; 
import com.badlogic.gdx.physics.box2d.FixtureDef; 
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType; 

public class PhysicsTest1 extends BaseGameActivity implements IAccelerometerListener, IOnSceneTouchListener{ 

    private final float CAMERA_WIDTH = 800; 
    private final float CAMERA_HEIGHT = 480; 

    private final float MAX_DISTANCE_FLING = 80f; 
    private final float MAX_VELOCITY_CONST = 250f; 
    private final float DEFAULT_VELOCITY = 50f; 

    private BitmapTextureAtlas mBitmapTextureAtlas; 

    private Scene mScene; 

    protected TiledTextureRegion mBoxFaceTextureRegion; 
    protected TiledTextureRegion mCircleFaceTextureRegion; 

    protected PhysicsWorld mPhysicsWorld; 

    private int mFaceCount = 0; 


    private float X = 0; 
    private float Y = 0; 

    private Body body = null; 

    @Override 
    public void onLoadComplete() { 


    } 

    @Override 
    public Engine onLoadEngine() {  
     final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT); 
     final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera); 
     engineOptions.getTouchOptions().setRunOnUpdateThread(true); 
     return new Engine(engineOptions); 
    } 

    @Override 
    public void onLoadResources() { 

     this.mBitmapTextureAtlas = new BitmapTextureAtlas(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA); 
     BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/"); 
     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.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas); 
    } 

    @Override 
    public Scene onLoadScene() { 


     this.mScene = new Scene(); 
     this.mScene.setBackground(new ColorBackground(0, 0, 0)); 
     this.mScene.setOnSceneTouchListener(this); 
     this.mScene.setOnSceneTouchListenerBindingEnabled(true); 

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

     final Shape ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2); 
     final Shape roof = new Rectangle(0, 0, CAMERA_WIDTH, 2); 
     final Shape left = new Rectangle(0, 0, 2, CAMERA_HEIGHT); 
     final Shape right = new Rectangle(CAMERA_WIDTH - 2, 0, 2, CAMERA_HEIGHT); 

     final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.3f); 
     PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef); 
     PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef); 
     PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef); 
     PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef); 

     this.mScene.attachChild(ground); 
     this.mScene.attachChild(roof); 
     this.mScene.attachChild(left); 
     this.mScene.attachChild(right); 

     this.mScene.registerUpdateHandler(this.mPhysicsWorld); 

     addFace(0,0); 

     return this.mScene; 
    } 

    @Override 
    public void onResumeGame() { 
     super.onResumeGame(); 

     this.enableAccelerometerSensor(this); 
    } 

    @Override 
    public void onPauseGame() { 
     super.onPauseGame(); 

     this.disableAccelerometerSensor(); 
    } 

    @Override 
    public void onAccelerometerChanged(AccelerometerData pAccelerometerData) { 
//  final Vector2 gravity = Vector2Pool.obtain(pAccelerometerData.getX(), pAccelerometerData.getY()); 
//  this.mPhysicsWorld.setGravity(gravity); 
//  Vector2Pool.recycle(gravity); 

    } 

    private float Xlocal = 0.0f; 
    private float Ylocal = 0.0f; 
    private long timeDown = 0; 

    @Override 
    public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) { 
//  if(this.mPhysicsWorld != null) { 
//   if(pSceneTouchEvent.isActionDown()) { 
//    this.addFace(pSceneTouchEvent.getX(), pSceneTouchEvent.getY()); 
//    return true; 
//   }  

     if (pSceneTouchEvent.isActionDown()) { 
      timeDown = System.currentTimeMillis(); 

      System.out.println("Time down is "+timeDown); 

      Xlocal = pSceneTouchEvent.getX(); 
      Ylocal = pSceneTouchEvent.getY();   
     } else if (pSceneTouchEvent.isActionUp()) { 

      X = (pSceneTouchEvent.getX() - Xlocal); 
      Y = (pSceneTouchEvent.getY() - Ylocal); 

      float distance = getDistance(Xlocal, Ylocal, pSceneTouchEvent.getX(), pSceneTouchEvent.getY()); 
      if(distance >= MAX_DISTANCE_FLING){ 
       long timeUp = System.currentTimeMillis(); 

       System.out.println("Time up is "+timeUp); 

       shootBall(X, Y, distance, (float) (timeUp - timeDown)/TimeConstants.MILLISECONDSPERSECOND); 
      }   
     } 


//  } 
     return true;   
    } 


    private void addFace(final float pX, final float pY) { 
     this.mFaceCount++; 
     Debug.d("Faces: " + this.mFaceCount); 

     final AnimatedSprite face; 


     final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(0.3f, 0.2f, 0.3f); 
     final FixtureDef objectFixtureDefKinetic = PhysicsFactory.createFixtureDef(0.5f, 0.4f, 0f); 

//  if(this.mFaceCount % 2 == 0) { 

      face = new AnimatedSprite(pX, pY, this.mCircleFaceTextureRegion){ 
       @Override 
       public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) { 

//     if(pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN){ 
//      Xlocal = pSceneTouchEvent.getX(); 
//      Ylocal = pSceneTouchEvent.getY(); 
//      
//     }else if(pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP){ 
//      float x = pSceneTouchEvent.getX(); 
//      float y = pSceneTouchEvent.getY(); 
//      
//      x = Math.abs(x - Xlocal); 
//      y = Math.abs(y - Ylocal); 
//      
//      shootBall(x, y); 
//     } 
//      
//     return mVisible; 
        return false; 
       }   
      }; 
      face.setScale(2); 


      AnimatedSprite face2 = new AnimatedSprite((CAMERA_WIDTH * 0.5f) - mBoxFaceTextureRegion.getWidth(), (CAMERA_HEIGHT * 0.5f) - mBoxFaceTextureRegion.getHeight(), this.mBoxFaceTextureRegion.clone()); 
      Body bodyKinetic = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face2, BodyType.KinematicBody, objectFixtureDefKinetic);    
      bodyKinetic.setAngularVelocity(15f); 

      AnimatedSprite face3 = new AnimatedSprite(400f, 100f, this.mBoxFaceTextureRegion.clone()); 
      Body body2 = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face3, BodyType.DynamicBody, objectFixtureDef);   
      body2.setLinearDamping(2f); 
      body2.setAngularDamping(10f);   


//  } else { 
//   face = new AnimatedSprite(pX, pY, this.mBoxFaceTextureRegion); 
//   face.setScale(MathUtils.random(0.5f, 1.25f)); 
//   body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef); 
//  } 

     body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);  
     body.setBullet(true); 
     this.mScene.attachChild(face); 
     this.mScene.registerTouchArea(face); 
     this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true)); 

     this.mScene.attachChild(face2); 
     this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face2, bodyKinetic)); 

     this.mScene.attachChild(face3); 
     this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face3, body2)); 
    } 


    private void shootBall(final float pX, final float pY, final float pDistance, final float pTime) { 

     System.out.println("Time Final seconds "+pTime); 

     float angleRad =(float)Math.atan2(pY, pX); 
     float velocity = this.getVelocity(pTime);//(pDistance * 12.5f)/100f;  
     if(body != null){   
      float Vx = velocity * (float)Math.cos(angleRad); 
      float Vy = velocity * (float)Math.sin(angleRad); 
      body.applyLinearImpulse(new Vector2(Vx,Vy), body.getWorldCenter()); 
      body.setAngularDamping(0.8f); //to decrease velocity slowly. no linear no floaty :) 
      body.setLinearDamping(0.5f); 
      body.applyTorque(100f); 
     } 
    } 

    private float getDistance(float x1, float y1, float x2, float y2){ 
     float X2_ = (float)Math.pow(x2 - x1, 2); 
     float Y2_ = (float)Math.pow(y2 - y1, 2);  

     float distance = (float)Math.sqrt(X2_ + Y2_);  
     return distance; 
    } 

    private float getVelocity(float pTime) { 
     float velocity = MAX_VELOCITY_CONST - (pTime * 100f); 
     if (velocity < DEFAULT_VELOCITY) { 
      velocity = DEFAULT_VELOCITY; 
     } 
     System.out.println("velocity "+velocity); 
     return velocity; 
    } 

} 

請參閱bodyKinetic.setAngularVelocity(15F);

更新

@Override 公共無效onResumeGame(){ super.onResumeGame();

if(bodyKinetic != null){ 
     System.out.println("set angular veclocity resume "); 
     bodyKinetic.setAngularVelocity(25f); 
    }  
    this.enableAccelerometerSensor(this); 
} 

其奇怪的是,當我在dubug模式下運行它,它運行正常,並沒有調試它沒有任何效果

更新 我也有UNREG並重新REG身體,但還是沒有用的: (

@Override 
    public void onResumeGame() { 
     super.onResumeGame();  

     if(bodyKinetic != null){ 
      System.out.println("OnResumeGame Angular Velocity "+bodyKinetic.getAngularVelocity()); 

      this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector((IShape) bodyKinetic.getUserData(), bodyKinetic)); 
      bodyKinetic.setAngularVelocity(25f);  
     } 

     this.enableAccelerometerSensor(this); 
    } 

    @Override 
    public void onPauseGame() { 
     super.onPauseGame(); 
     if(bodyKinetic != null){ 
      System.out.println("OnPauseGame Angular Velocity "+bodyKinetic.getAngularVelocity()); 
     bodyKinetic.setAngularVelocity(0f); 
      this.mPhysicsWorld.unregisterPhysicsConnector(this.mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape((IShape) bodyKinetic.getUserData())); 
     }  

     this.disableAccelerometerSensor(); 
    } 
+1

bodyKinetic.applyAngularImpulse(25F)有超過身體,爲什麼沒有效果呢? – 2012-02-23 08:09:44

+0

有什麼理由不使用DynamicBody?運動機構用於特殊目的,在大多數情況下不相關。 – JohnEye 2012-02-23 12:22:46

+1

是的,因爲我正在使用我的身體作爲旋轉面板。這不應該移動,但只能旋轉。這是我的遊戲邏輯。 – 2012-02-23 12:37:14

回答

2

您可以嘗試保存機構的速度在onPauseGame()和的onResume()設置他們回來。你也可以嘗試設置線性和角暫停遊戲,當resum正在重置值時,阻尼0 ING。在我工作的項目中,阻尼有時表現得很奇怪。

,你遇到了heisenbug的事實表明,這可能是在發動機的錯誤。

+1

我使用UpdateHandler來修復它 – 2012-02-24 04:42:32

+1

我也已經做了你所說的甚至我unreg和重新註冊在onResume但沒有用:( – 2012-02-24 04:56:35

+1

我有一個更復雜的想法 - 如果動態的身體行爲正確,你可以身型改變爲動態的暫停和恢復設置回正確的位置,速度和改變身體類型的運動。你問的AndEngine論壇?也許這只是我們的一部分了一些愚蠢的監督。 – JohnEye 2012-02-24 10:07:54