Android 加速度计移动球 [英] Android Accelerometer moving ball

查看:27
本文介绍了Android 加速度计移动球的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在网上发布的教程的帮助下开发了一个示例应用程序.我的目标是访问加速度计并根据手机方向移动球.我在一定程度上是成功的.但我有两个问题

i have done developed a sample application with the help of tutorials posted on web. my aim is to access the accelerometer and move a ball as per the phone orientation. i was successful to certail extent. But i have two isses

  1. 球出界了
  2. 小球运动不流畅(看起来它消失了又重新出现在屏幕上)

这是我的代码.有什么我需要做的改变才能让球像我们在很多比赛中看到的那样平稳准确地运动.

here is my code. is there any change i need to do to get the smooth and exact movement of the ball as we see in lot of games.

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();
        }
    }
}

推荐答案

这和你上一个问题不是同一个问题吗这里?!你应该编辑/扩展你原来的问题,而不是开始一个新的问题!

Is this not the same question as your last question here?! You should just edit/expand your original question rather that starting a new one!

但基本上是为了让你想通过使用 x/y 速度而不是仅仅改变位置来移动球.所以你想有一个循环来画球,你想知道当前循环和前一个循环之间的时间差,然后你可以使用简单的运动学方程来计算位置变化.

But basically to make it realistic you want to move the ball by using x/y speed rather than just changing the position. So you want to have a loop which draws the ball and you want to know the time difference between the current loop and the previous, then you can use simple kinematics equations to work out the position change.

例如:

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

在您使用传感器输入设置加速度的情况下,只需将计算出的距离与球位置相加即可.

Where you use sensor inputs to set the acceleration, then just add the calculated distance to the balls position.

编辑 - 按要求编写代码.

EDIT - Code as requested.

幸运的是你找到了一个无聊的游戏程序员!它无论如何都不是完美的,但它对你有用.你应该给自己买一本游戏开发书,看看为此使用 open GL,因为它会好得多!

Your lucky you found a bored games programmer! It's not perfect by any means but its working for you. You should buy yourself a game development book and have a look at using open GL for this as it would be a lot better!

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);
}
}

这篇关于Android 加速度计移动球的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆