понедельник, 24 сентября 2012 г.

Двигаем спрайт акселерометром.



Следующие полшага к созданию аркады.

Прикрутим к нашему SimpleBaseGameActivity вот такую штуку:+

public class HelloWorldActivity extends SimpleBaseGameActivity implements SensorEventListener{
Однако, как только мы этот Implement приписали - сразу возникает ошибка в этой же строчке:
Multiple markers at this line
- The type HelloWorldActivity must implement the inherited abstract method
SensorEventListener.onSensorChanged(SensorEvent)
- The type HelloWorldActivity must implement the inherited abstract method
SensorEventListener.onAccuracyChanged(Sensor, int)
Нам надо описать эти 2 метода. И вот как мы это сделаем:
private int accellerometerSpeedX;
private int accellerometerSpeedY;

public void onAccuracyChanged(Sensor sensor, int accuracy) {
     //
 }
 
public void onSensorChanged(SensorEvent event) {
    synchronized (this) {
            switch (event.sensor.getType()) {
            case Sensor.TYPE_ACCELEROMETER:
                    accellerometerSpeedX = (int) event.values[1];
                    accellerometerSpeedY = (int) event.values[0];
                    break;
        }}}
Ну а в OnCreateScene запихиваем вот такую конструкцию:
mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE); 
     mSensorManager.registerListener(this, 
     mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
     SensorManager.SENSOR_DELAY_GAME);
Конечно, в начало кода надо пихнуть переменную:
private SensorManager mSensorManager;
После этих манипуляций у нас есть ежекадровые данные с акселерометра.
Надо бы их куда-нибудь применить. Припишем функцию апдэйта позиции нашего спрайта:
private void updateSpritePosition(float pSecondsElapsed) {
     //Log.d("Sapfil_Log", "upd");
        if ((accellerometerSpeedX != 0) || (accellerometerSpeedY != 0)) {
                // Set the Boundary limits
                int tL = 0;
                int lL = 0;
                int rL = CAMERA_WIDTH - (int) mSprite.getWidth();
                int bL = CAMERA_HEIGHT - (int) mSprite.getHeight();
                //float dt = pSecondsElapsed * 20;
     
                // вычисление новых координат и проверка касания с краем экрана
                sX -= (accellerometerSpeedY * (pSecondsElapsed * speed));
                sY += (accellerometerSpeedX * (pSecondsElapsed * speed));
                if (sX < lL)
                        sX = lL;
                if (sX > rL)
                        sX = rL;
                if (sY < tL)
                        sY = tL;
                if (sY > bL)
                        sY = bL;
     
                mSprite.setPosition(sX, sY);
        };
    }
Функция есть. Теперь ее надо как-то где-то вызывать, конечно ежекадрово.
scene.registerUpdateHandler(new IUpdateHandler() {
            public void onUpdate(float pSecondsElapsed) { 
                        updateSpritePosition(pSecondsElapsed); 
                        }
                        public void reset() {
                          // TODO Auto-generated method stub
                        }
Вот собственно и все. Полный код давайте запихнем на Everfall.
http://www.everfall.com/paste/id.php?0mf6g2njgree

1 комментарий:

  1. если еще просматриваешь этот блог, то есть один маленький вопрос. А как задать некий "угол" для акселерометра? я имею ввиду, играть если телефон нужно держать параллельно земле не очень удобно, если например сидишь где то в автобусе , метро или просто за столом. Если можно задавать базовый угол, то будет намного удобнее, сточки зрения юзабилити )))
    P.S : я только начинаю знакомиться с Android и AndEnginer, поэтому возможно вопрос не совсем корректный, а может даже глуповат )))

    ОтветитьУдалить