Android的加速度运动中的球 [英] Android Accelerometer moving ball

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

问题描述

我已经做开发的教程贴在网络的帮助下一个示例应用程序。我的目标是访问加速度计和移动球按电话取向。我成功了,以certail程度。但我有两个isses

  1. 球会出界屏幕
  2. 球运动不顺畅(看起来消失,重新出现在屏幕上)

这是我的code。是否有任何改变,我需要做的就是球的平稳,精确的运动,因为我们在很多场比赛看到的。

 公共类加速度传感器扩展了活动实施SensorEventListener {
    / **第一次创建活动时调用。 * /
    CustomDrawableView mCustomDrawableView = NULL;
    ShapeDrawable mDrawable =新ShapeDrawable();
    公共静态INT X;
    公共静态INTÿ;
       私人位图mBitmap;
       私人位图mWood;
    私人的SensorManager的SensorManager = NULL;

    / **第一次创建活动时调用。 * /
    @覆盖
    公共无效的onCreate(包savedInstanceState)
    {

        super.onCreate(savedInstanceState);
        //获取一个引用的SensorManager
        的SensorManager =(的SensorManager)getSystemService(SENSOR_SERVICE);
        mCustomDrawableView =新CustomDrawableView(本);
        的setContentView(mCustomDrawableView);
        //的setContentView(R.layout.main);

    }

    //该方法将更新新传感器事件的用户界面
    公共无效onSensorChanged(SensorEvent sensorEvent)
    {
        {
           / *如果(sensorEvent.sensor.getType()== Sensor.TYPE_ACCELEROMETER){
                //你计算最初这里值均超过10000!
                X =(int)的Math.pow(sensorEvent.values​​ [0],2);
                Y =(int)的Math.pow(sensorEvent.values​​ [1],2);

            } * /

            如果(sensorEvent.sensor.getType()== Sensor.TYPE_ORIENTATION){
                  显示显示= 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);
                  如果(X> XMAX){
                      X = XMAX;
                  }否则如果(X< -xmax){
                      X = -xmax;
                  }
                  如果(Y> YMAX){
                      Y = YMAX;
                  }否则如果(Y< -ymax){
                      Y = -ymax;
                  }

            }
        }
    }

    //我选择不实现此方法
    公共无效onAccuracyChanged(传感器为arg0,INT ARG1)
    {
        // TODO自动生成方法存根

    }

    @覆盖
    保护无效onResume()
    {
        super.onResume();
        //注册这个类作为侦听器的加速度传感器
        sensorManager.registerListener(这一点,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
                SensorManager.SENSOR_DELAY_GAME);
        // ...和方向传感器
        sensorManager.registerListener(这一点,sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION)
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    @覆盖
    保护无效的onStop()
    {
        //注销监听器
        sensorManager.unregisterListener(本);
        super.onStop();
    }

    公共类CustomDrawableView扩展视图
    {


        公共CustomDrawableView(上下文的背景下)
        {
            超(上下文);

          位图球= BitmapFactory.de codeResource(getResources(),R.drawable.ball);
          最终诠释dstWidth = 50;
          最终诠释dstHeight = 50;
          mBitmap = Bitmap.createScaledBitmap(球,dstWidth,dstHeight,真正的);
          mWood = BitmapFactory.de codeResource(getResources(),R.drawable.wood);

        }

        保护无效的OnDraw(帆布油画)
        {

            最后的位图位= mBitmap;

            canvas.drawBitmap(mWood,0,0,NULL);
            canvas.drawBitmap(位图,X,Y,空);

            无效();
        }
    }
}
 

解决方案

这是不一样的问题,因为你的最后一个问题<一href="http://stackoverflow.com/questions/6457768/moving-an-image-using-accelerometer-of-anroid">here?!你应该只需编辑/扩展,而这在开始一个新的你原来的问题!

但基本上要通过使用X / Y的速度,而不是仅仅改变位置,移动球,使之切合实际。所以,你想有一个回路,平球,你想知道的电流回路和previous之间的时间差,那么你可以使用简单的运动学方程来计算出位置变化。

例如:

  newspeed = oldSpeed​​ +(加*时间)
距离=(原速*时间)+(0.5 *加速时间* ^ 2)。
 

如果您使用传感器输入设置的加速度,然后计算出的距离只需添加到球的位置。


编辑 - code的要求

你的幸运,你找到了一个无聊的游戏程序员!它并不完美,任何手段,但它为你工作。你应该给自己买一个游戏开发的书,看看使用开放GL基于这一点,那将是一个好多了!

 公共类test2的延伸活动实现SensorEventListener {

CustomDrawableView mCustomDrawableView = NULL;
ShapeDrawable mDrawable =新ShapeDrawable();
公众持股量xPosition位置,xAcceleration,xVelocity = 0.0;
公众持股量yPosition,yAcceleration,yVelocity = 0.0;
公众持股量XMAX,YMAX;
私人位图mBitmap;
私人位图mWood;
私人的SensorManager的SensorManager = NULL;
公众持股量frameTime的= 0.666f;

/ **第一次创建活动时调用。 * /
@覆盖
公共无效的onCreate(包savedInstanceState)
{

    super.onCreate(savedInstanceState);

    //设置全屏和放大器;肖像
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow()setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN)。
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    //获取一个引用的SensorManager
    的SensorManager =(的SensorManager)getSystemService(SENSOR_SERVICE);
    sensorManager.registerListener(这一点,sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION)
            SensorManager.SENSOR_DELAY_GAME);

    mCustomDrawableView =新CustomDrawableView(本);
    的setContentView(mCustomDrawableView);
    //的setContentView(R.layout.main);

    //计算疆
    显示显示= getWindowManager()getDefaultDisplay()。
    XMAX =(浮点)display.getWidth() -  50;
    YMAX =(浮点)display.getHeight() -  50;
}

//该方法将更新新传感器事件的用户界面
公共无效onSensorChanged(SensorEvent sensorEvent)
{
    {
        如果(sensorEvent.sensor.getType()== Sensor.TYPE_ORIENTATION){
            //设置传感器值加速度
            yAcceleration = sensorEvent.values​​ [1];
            xAcceleration = sensorEvent.values​​ [2];
            updateBall();
        }
    }
}

私人无效updateBall(){


    //计算新速度
    xVelocity + =(xAcceleration * frameTime的);
    yVelocity + =(yAcceleration * frameTime的);

    在那段时间// Calc的行驶距离
    浮动XS =(xVelocity / 2)* frameTime的;
    浮动YS =(yVelocity / 2)* frameTime的;

    //添加到位置,由于传感器的负
    //读数是相反我们想要的!
    xPosition位置 -  = XS;
    yPosition  -  = YS;

    如果(xPosition位置&GT; XMAX){
        xPosition位置= XMAX;
    }否则如果(xPosition位置℃,){
        xPosition位置= 0;
    }
    如果(yPosition&GT; YMAX){
        yPosition = YMAX;
    }否则如果(yPosition℃,){
        yPosition = 0;
    }
}

//我选择不实现此方法
公共无效onAccuracyChanged(传感器为arg0,INT ARG1)
{
    // TODO自动生成方法存根
}

@覆盖
保护无效onResume()
{
    super.onResume();
    sensorManager.registerListener(这一点,sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION)
            SensorManager.SENSOR_DELAY_GAME);
}

@覆盖
保护无效的onStop()
{
    //注销监听器
    sensorManager.unregisterListener(本);
    super.onStop();
}

公共类CustomDrawableView扩展视图
{
    公共CustomDrawableView(上下文的背景下)
    {
        超(上下文);
        位图球= BitmapFactory.de codeResource(getResources(),R.drawable.ball);
        最终诠释dstWidth = 50;
        最终诠释dstHeight = 50;
        mBitmap = Bitmap.createScaledBitmap(球,dstWidth,dstHeight,真正的);
        mWood = BitmapFactory.de codeResource(getResources(),R.drawable.wood);

    }

    保护无效的OnDraw(帆布油画)
    {
        最后的位图位= mBitmap;
        canvas.drawBitmap(mWood,0,0,NULL);
        canvas.drawBitmap(位图,xPosition位置,yPosition,NULL);
        无效();
    }
}

@覆盖
公共无效onConfigurationChanged(配置NEWCONFIG){
    // TODO自动生成方法存根
    super.onConfigurationChanged(NEWCONFIG);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
 

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. the ball is going out of bound of the screen
  2. the ball movement is not smooth ( looks it disappears and re appears on the screen)

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!

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.

For example:

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.

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天全站免登陆