2011-06-25 15 views
5

Opracowałem przykładową aplikację za pomocą samouczków zamieszczonych w Internecie. moim celem jest uzyskanie dostępu do akcelerometru i przesunięcie piłki zgodnie z orientacją telefonu. Udało mi się zdobyć certyfikat. Ale mam dwie issesPrzyspieszanie przyśpieszeniomierza Androidu

  1. piłka wychodzi związanego z ekranu
  2. ruch piłka nie jest gładka (wygląda to znika i pojawia się na ekranie re)

tutaj jest mój kod. Czy jest jakaś zmiana, którą muszę zrobić, aby uzyskać płynny i dokładny ruch piłki, jak widzimy w wielu grach.

public class Accelerometer extends Activity implements SensorEventListener{ 
    /** Called when the activity is first created. */ 
    CustomDrawableView mCustomDrawableView = null; 
    ShapeDrawable mDrawable = new ShapeDrawable(); 
    public static int x; 
    public static int y; 
     private Bitmap mBitmap; 
     private Bitmap mWood; 
    private SensorManager sensorManager = null; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 

     super.onCreate(savedInstanceState); 
     // Get a reference to a SensorManager 
     sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 
     mCustomDrawableView = new CustomDrawableView(this); 
     setContentView(mCustomDrawableView); 
     // setContentView(R.layout.main); 

    } 

    // This method will update the UI on new sensor events 
    public void onSensorChanged(SensorEvent sensorEvent) 
    { 
     { 
      /* if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 
       // the values you were calculating originally here were over 10000! 
       x = (int) Math.pow(sensorEvent.values[0], 2); 
       y = (int) Math.pow(sensorEvent.values[1], 2); 

      }*/ 

      if (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) { 
        Display display = getWindowManager().getDefaultDisplay(); 
        int xmax = display.getWidth(); 
        int ymax = display.getHeight(); 
        x = (int) Math.pow(sensorEvent.values[1], 2); 
        y = (int) Math.pow(sensorEvent.values[2], 2); 
        if (x > xmax) { 
         x = xmax; 
        } else if (x < -xmax) { 
         x = -xmax; 
        } 
        if (y > ymax) { 
         y = ymax; 
        } else if (y < -ymax) { 
         y = -ymax; 
        } 

      } 
     } 
    } 

    // I've chosen to not implement this method 
    public void onAccuracyChanged(Sensor arg0, int arg1) 
    { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    protected void onResume() 
    { 
     super.onResume(); 
     // Register this class as a listener for the accelerometer sensor 
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
       SensorManager.SENSOR_DELAY_GAME); 
     // ...and the orientation sensor 
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 
       SensorManager.SENSOR_DELAY_NORMAL); 
    } 

    @Override 
    protected void onStop() 
    { 
     // Unregister the listener 
     sensorManager.unregisterListener(this); 
     super.onStop(); 
    } 

    public class CustomDrawableView extends View 
    { 


     public CustomDrawableView(Context context) 
     { 
      super(context); 

      Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball); 
      final int dstWidth = 50; 
      final int dstHeight = 50; 
      mBitmap = Bitmap.createScaledBitmap(ball, dstWidth, dstHeight, true); 
      mWood = BitmapFactory.decodeResource(getResources(), R.drawable.wood); 

     } 

     protected void onDraw(Canvas canvas) 
     { 

      final Bitmap bitmap = mBitmap; 

      canvas.drawBitmap(mWood, 0, 0, null); 
      canvas.drawBitmap(bitmap, x, y, null); 

      invalidate(); 
     } 
    } 
} 
+0

.. idealnie pasują do tego, czego szukasz, jest [tutaj] (http://www.appsrox.com/android/tutorials/accelerometer-golf/) – user2230793

Odpowiedz

10

Czy to nie to samo pytanie, co ostatnie pytanie? here?! Powinieneś po prostu edytować/rozwinąć oryginalne pytanie, zamiast zaczynać nowe!

Ale zasadniczo, aby uczynić go realistycznym, chcesz przesunąć piłkę za pomocą prędkości x/y, a nie tylko zmienić pozycję. Więc chcesz mieć pętlę, która rysuje piłkę i chcesz poznać różnicę czasu między bieżącą pętlą a poprzednią, wtedy możesz użyć prostych równań kinematycznych, aby obliczyć zmianę pozycji.

Na przykład:

newspeed = oldSpeed + (acceleration * time) 
distance = (original speed*time) + (0.5 * acceleration * time^2). 

Gdzie ustawić przyspieszenie używać wejścia czujników, a potem po prostu dodać obliczoną odległość do położenia kul.


EDYCJA - Kod zgodnie z żądaniem.

Twoje szczęście, że znalazłeś programującego znudzonego programistę! W żadnym razie nie jest doskonały, ale działa dla ciebie. Powinieneś kupić sobie książkę do tworzenia gier i spojrzeć na używanie otwartego GL, ponieważ byłoby o wiele lepiej!

public class test2 extends Activity implements SensorEventListener{ 

CustomDrawableView mCustomDrawableView = null; 
ShapeDrawable mDrawable = new ShapeDrawable(); 
public float xPosition, xAcceleration,xVelocity = 0.0f; 
public float yPosition, yAcceleration,yVelocity = 0.0f; 
public float xmax,ymax; 
private Bitmap mBitmap; 
private Bitmap mWood; 
private SensorManager sensorManager = null; 
public float frameTime = 0.666f; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) 
{ 

    super.onCreate(savedInstanceState); 

    //Set FullScreen & portrait 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

    // Get a reference to a SensorManager 
    sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 
      SensorManager.SENSOR_DELAY_GAME); 

    mCustomDrawableView = new CustomDrawableView(this); 
    setContentView(mCustomDrawableView); 
    // setContentView(R.layout.main); 

    //Calculate Boundry 
    Display display = getWindowManager().getDefaultDisplay(); 
    xmax = (float)display.getWidth() - 50; 
    ymax = (float)display.getHeight() - 50; 
} 

// This method will update the UI on new sensor events 
public void onSensorChanged(SensorEvent sensorEvent) 
{ 
    { 
     if (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) { 
      //Set sensor values as acceleration 
      yAcceleration = sensorEvent.values[1]; 
      xAcceleration = sensorEvent.values[2]; 
      updateBall(); 
     } 
    } 
} 

private void updateBall() { 


    //Calculate new speed 
    xVelocity += (xAcceleration * frameTime); 
    yVelocity += (yAcceleration * frameTime); 

    //Calc distance travelled in that time 
    float xS = (xVelocity/2)*frameTime; 
    float yS = (yVelocity/2)*frameTime; 

    //Add to position negative due to sensor 
    //readings being opposite to what we want! 
    xPosition -= xS; 
    yPosition -= yS; 

    if (xPosition > xmax) { 
     xPosition = xmax; 
    } else if (xPosition < 0) { 
     xPosition = 0; 
    } 
    if (yPosition > ymax) { 
     yPosition = ymax; 
    } else if (yPosition < 0) { 
     yPosition = 0; 
    } 
} 

// I've chosen to not implement this method 
public void onAccuracyChanged(Sensor arg0, int arg1) 
{ 
    // TODO Auto-generated method stub 
} 

@Override 
protected void onResume() 
{ 
    super.onResume(); 
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 
      SensorManager.SENSOR_DELAY_GAME); 
} 

@Override 
protected void onStop() 
{ 
    // Unregister the listener 
    sensorManager.unregisterListener(this); 
    super.onStop(); 
} 

public class CustomDrawableView extends View 
{ 
    public CustomDrawableView(Context context) 
    { 
     super(context); 
     Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball); 
     final int dstWidth = 50; 
     final int dstHeight = 50; 
     mBitmap = Bitmap.createScaledBitmap(ball, dstWidth, dstHeight, true); 
     mWood = BitmapFactory.decodeResource(getResources(), R.drawable.wood); 

    } 

    protected void onDraw(Canvas canvas) 
    { 
     final Bitmap bitmap = mBitmap; 
     canvas.drawBitmap(mWood, 0, 0, null); 
     canvas.drawBitmap(bitmap, xPosition, yPosition, null); 
     invalidate(); 
    } 
} 

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    // TODO Auto-generated method stub 
    super.onConfigurationChanged(newConfig); 
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
} 
} 
+0

hej, jestem bardzo nowy na tej stronie. chciałem zamknąć wcześniejsze pytanie, ale nigdzie nie widziałem tej opcji. być może nie patrzę w odpowiednie miejsce. jak mogę przyjąć odpowiedź? –

+0

cześć, mam sposób, aby zaakceptować odpowiedź. Zaakceptowałem twoją poprzednią odpowiedź. dzięki –

+0

cześć kenny, brzmi dobrze. ale ja również jestem nowy w java. czy możesz zmienić mój kod i objaśnić logikę? –

2

chciałbym ustawić SENSOR_DELAY stały się

SENSOR_DELAY_FASTEST 

sprawdzić, czy to rozwiązuje go. To powinno pomóc w rozwiązywaniu problemów z jąkaniem. Sądzę też, że kontrole graniczne są nieprawidłowe, ponieważ podane są wartości xmax i ymax display.getWidth/getHeight Może powinieneś podać swoje granice szerokości i wysokości BitMap do wartości xmax i ymax.

+0

hi bob, zmieniając go do SENSOR_DELAY_FASTEST nie rozwiązać problem, w rzeczywistości sprawił, że ruch był zbyt szybki, a problem z granicami nie został rozwiązany. –