setAngularVelocity уменьшается в onGameResume, onPause - PullRequest
0 голосов
/ 21 февраля 2012

Я устанавливаю линейный импульс на объект, он движется нормально, но когда я нажимаю кнопку питания и затем снова захожу в игру, я заметил, что скорость вращения моего объекта уменьшена.

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 public void onResumeGame () { super.onResumeGame ();

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

Странно, что когда я запускаю его в режиме дублирования, он работает нормально и без отладки не действует

Обновление У меня также есть незарегистрированный и повторный регистр тела, но он по-прежнему бесполезен: (

@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 Ответ

2 голосов
/ 23 февраля 2012

Вы можете попытаться сохранить скорости тел в onPauseGame () и установить их обратно в onResume ().Вы также можете попробовать установить линейное и угловое демпфирование на 0 при приостановке игры и сбросить значения при возобновлении.Демпфирование иногда ведет себя странно в проекте, над которым я работаю.

Тот факт, что вы испытываете heisenbug, предполагает, что это может быть ошибка в двигателе.

...