Pull to refresh

Android: Вращаем на все четыре стороны AndEngine

Reading time 3 min
Views 7.6K
Однажды мне пришлось решать задачу — запускать четыре разные игры написанные на andengine в зависимости от ориентации экрана. Обычные положения — landscape и portrait вопросов не вызывали. Вопросы возникли для остальных положений — противоположных для указанных. Четыре варианта переворота устройства. Пришлось обратиться к работе с сенсорами. Указанный ниже подход применим не только к AndEngine, но и к обычным Activity.Для начала создал класс работы с сенсорами в котором вычислялось положение устройства в пространстве:
public class SensorRotation {

private SensorManager  sensorManager;
private long lastUpdateTime;
private int orientation = 1;
private SensorEventListener sensorListener;
private Activity activity;
private boolean rightPosition = false;
public SensorRotation instance;
   /**
    * Инициализация сенсора
    * 
    * @param context контекст
    */
   public SensorRotation(Context context) {
      sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
      lastUpdateTime = 0;
   }

   /**
    * Регистрация активити как слушателя сенсора
    * 
    * @param activity
    * @param listener
    */
   public void register(Activity activity, SensorEventListener listener) {
      try {
         if (sensorListener != null) {
            sensorManager.unregisterListener(sensorListener);
         }
         this.sensorListener = listener;
         this.activity = activity;
         sensorManager.registerListener(sensorListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME);
         Log.v("Activity = " + activity.getLocalClassName());
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   /**
    * Удаляет слушатель
    */
   public void unregister() {
      sensorManager.unregisterListener(sensorListener);
      Log.v("unregister");
   }

   private boolean in(float value, int min, int max) {
      return (value > min && value < max);
   }

   
   private int getCurrentOrientation(SensorEvent event) {
      float y = event.values[1];
      float z = event.values[2];

      // Ниже приведенные числа координат ограничивающие наклон рассчитаны эмпирически. Вы можете их варьировать под себя.

      if (in(z, 60, 100)) return 1;
      if (in(z, -20, 20) && y > 50)  return 2;
      if (in(z, -20, 20) && y < -50) return 0;
      if (in(z, -100, -60)) return 3;
      return -1;
   }

   /**
    * Реакция на поворот
    * 
    * @param event
    */
   public boolean onSensorChanged(SensorEvent event) {
      if (System.currentTimeMillis() - lastUpdateTime < 500) return false;

      lastUpdateTime = System.currentTimeMillis();
      orientation = getCurrentOrientation(event);

      if (activity.getClass() == Guitar.class) if (orientation == 0) rightPosition = true;
      if (activity.getClass() == Sing.class) if (orientation == 1) rightPosition = true;
      if (activity.getClass() == Drums.class) if (orientation == 2) rightPosition = true;
      if (activity.getClass() == Piano.class) if (orientation == 3) rightPosition = true;

      if (!rightPosition) return false;

      Intent intent = null;
      switch (orientation) {
         case 0: {
            Log.v("Orientation = " + orientation + ", launching Guitar");
            intent = new Intent(activity, Guitar.class);
            break;
         }
         case 1: {
            Log.v("Orientation = " + orientation + ", launching Sing");
            intent = new Intent(activity, Sing.class);
            break;
         }
         case 2: {
            Log.v("Orientation = " + orientation + ", launching Drums");
            intent = new Intent(activity, Drums.class);
            break;
         }
         case 3: {
            Log.v("Orientation = " + orientation + ", launching Piano");
            intent = new Intent(activity, Piano.class);
            break;
         }
      }
      if (intent != null) {
         activity.startActivity(intent);
         activity.finish();
         return true;
      }
      return false;
   }

}
Затем создаем Activity от которой наследуется остальные игровые Activity.
public abstract class TalentGameActivity extends BaseGameActivity implements SensorEventListener {

   @Override
   public void onAccuracyChanged(Sensor sensor, int accuracy) {
   }

   @Override
   public void onSensorChanged(SensorEvent event) {
      if (GameModel.getInstance().sensorRotation.onSensorChanged(event)) {
         // Ваши действия при повороте
      }
   }

   @Override
   public void onLoadComplete() {
      ....
                // не забудьте проинициализировть instance перед использованием
      SensorRotation.instance.sensorRotation.register(this, this);
      .....
   }
   
}
Теперь мы создаем все игровые активити. Активити которые должны быть перевернуты на 180 градусов должны в процессе создания перевернуть камеру на 180 градусов как указано ниже.
public class Drums extends TalentGameActivity {

   @Override
   public Engine onLoadEngine() {
      super.onLoadEngine();
      mCamera = new Camera(0, 0, Const.ENGINE_PORTRAIT_WIDTH, Const.ENGINE_PORTRAIT_HEIGHT);
      mCamera.setRotation(180); // Здесь мы задаем поворот на 180 градусов для перевернутых активити и не используем для обычных положений.
      mEngine = new Engine(new EngineOptions(true, ScreenOrientation.PORTRAIT, new FillResolutionPolicy(), mCamera));
      // ScreenOrientation - выставляйте нужную ориентацию
      //mEngine = new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new FillResolutionPolicy(), mCamera));
      super.onLoadEngine();
      return mEngine;
   }
}
Вот и все.
Tags:
Hubs:
+13
Comments 15
Comments Comments 15

Articles