2011-06-25 11 views
5

私は、Web上に公開されたチュートリアルの助けを借りてサンプルアプリケーションを開発しました。私の目的は、加速度計にアクセスし、携帯電話の向きに応じてボールを移動することです。私は範囲を証明するのに成功しました。しかし、私は2 issesAndroid Accelerometer moving ball

  1. を持っているボールは
  2. 画面の境界の外に起こっているボールの動きが滑らかでない(それが消え、再画面に表示されます見えます)

ここに私ですコード。多くのゲームで見られるように、ボールの滑らかで正確な動きを得るために必要な変更がありますか?

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

..あなたが探しているものと完全に一致するものがこちらです(http://www.appsrox.com/android/tutorials/accelerometer-golf/) – user2230793

答えて

10

これはあなたの最後の質問と同じ質問ではありませんhere?!新しい質問を開始するのではなく、元の質問を編集/展開するだけです。

しかし、基本的には、位置を変更するのではなく、x/yの速度を使ってボールを移動したいと考えています。だからあなたはボールを描くループを持ち、現在のループと前のループとの間の時間差を知りたければ、単純な運動方程式を使って位置の変化を計算することができます。例えば

:あなたがちょうどボール位置に算出された距離を追加し、加速を設定するには、センサ入力を使用

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


EDIT - コードを要求しました。

あなたの幸運なことに、退屈なゲームプログラマーが見つかりました!それはあなたにとって完璧なことではありません。あなたはゲーム開発の本を買って、オープンGLを使ってこれをもっとよくするようにしてください! SENSOR_DELAY_FASTESTにそれを変えることはなかった

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

ちょっと、私はこのサイトに非常に新しいです。私は以前の質問をクローズしたかったが、オプションをどこにも見ることができなかった。私は正しい場所を見ていないかもしれません。どのように答えを受け入れるのですか? –

+0

こんにちは私は答えを受け入れる方法を得た。私はあなたの前のanswer.thanksを受け入れている –

+0

こんにちはケニー、良い音。しかし、私はjavaにも新しいです。あなたは私のコードを変更し、あなたが説明したロジックを入れてもいいですか? –

2

私はそれを修正するかどうかを確認し

SENSOR_DELAY_FASTEST 

に一定のSENSOR_DELAYを設定します。 これは、吃音問題に役立ちます。 また、xmaxとymaxの値が与えられているので境界チェックが間違っていると思います。display.getWidth/getHeight ビットマップの幅と高さの境界をxmaxとymaxの値にしてください。

+0

こんにちはボブ、問題を解決する、それはあまりにも速い動きを私は境界問題が解決されていませんでした –

関連する問題