使用加速度计移动的简单循环

发布于 2025-01-07 12:20:17 字数 3290 浏览 1 评论 0原文

我根据目前所掌握的内容再次重新编辑了整个主题,因为我对上一个主题有很多看法并且没有回复。与此同时,我有点弄清楚加速度计是如何工作的。

现在我有一个圆形(画布),如果你不介意的话,我想将其称为“Zoga”。该循环应根据手机的角度移动。因此,基本上,如果手机向左侧移动,则圆圈向左侧移动,如果手机向右下侧移动,则圆圈向该方向移动。

该循环是通过 Zoga.java 类创建的,整个过程都在 GravitacijaActivity.java 中进行。

这是我有两个问题:
1.) 圆仅向左移动。
2.) 圆圈移出屏幕(当然在左侧)

关于如何解决此问题有什么想法吗?

注意:我已经附上了我的整个代码,甚至是布局 main.xml,以防万一其他人以后需要该代码,用于教育和学习目的:)

GravitaijaActivity.java

package gravity.pack;
import android.app.Activity;
import android.os.Bundle;
import android.widget.FrameLayout;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class GravitacijaActivity extends Activity implements SensorEventListener{
    public float xPos = 50.0f, yPos = 50.0f;
    public float xAcc = 0.0f, yAcc = 0.0f;
    public int radius = 30;
    private SensorManager sensorManager;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                    SensorManager.SENSOR_DELAY_GAME);

        FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
        main.addView(new Zoga(this, xPos, yPos, radius));
}

public void onAccuracyChanged(Sensor arg0, int arg1) {
    // TODO Auto-generated method stub

}

public void onSensorChanged(SensorEvent sensorArg) {
    if (sensorArg.sensor.getType() == Sensor.TYPE_ORIENTATION)
    {
            xAcc = sensorArg.values[1];
            yAcc = sensorArg.values[2];
        updateZoga();

    }

}

public void updateZoga()
{
    xPos += xAcc;
    yPos += yAcc;
    FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
    main.removeAllViews();
    main.addView(new Zoga(this, xPos, yPos, radius));
    try {
        Thread.sleep(1);
    } catch (InterruptedException e) {}

  }         
}


Zoga .java

package gravity.pack;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;

public class Zoga extends View{
    private final float x;
    private final float y;
    private final float r;
    private final Paint mPaint = new Paint (Paint.ANTI_ALIAS_FLAG);

    public Zoga(Context context, float x, float y, float r) {
        super(context);
        mPaint.setColor(0xFFFF0000);
        this.x = x;
        this.y = y;
        this.r = r;
    }

    @Override
    protected void onDraw(Canvas canvas){
        super.onDraw(canvas);
        canvas.drawCircle(x, y, r, mPaint);
    } 
}


布局 main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/main_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FF66FF33" />

I have re-edited the whole topic again, based on what i have so far, since i had so many views on the previous topic and no replys. In the meanwhile i kinda figured out how accelerometer works.

Now I have a cyrcle (canvas) which i would like to call "Zoga", if you don't mind. This cyrcle should move based on the angle of the phone. So basicly if the phone is moved on the left side, the cyrcle travels on the left side, if the phone is moved on down-right side, the cyrcle moves in that direction.

The cyrcle is created trough the class Zoga.java, and the whole magic heppens in GravitacijaActivity.java.

Here are 2 issues i have:

1.) The cyrcle only moves in left dirrection.

2.) The cyrcle travels outside of the screen (on the left side ofcourse).

Any ideas on how to fix this issues?

NOTE: I've attached my whole code, even the layout main.xml, just in case someone else will later need the code, for the education and learning purpose :)

GravitaijaActivity.java

package gravity.pack;
import android.app.Activity;
import android.os.Bundle;
import android.widget.FrameLayout;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class GravitacijaActivity extends Activity implements SensorEventListener{
    public float xPos = 50.0f, yPos = 50.0f;
    public float xAcc = 0.0f, yAcc = 0.0f;
    public int radius = 30;
    private SensorManager sensorManager;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                    SensorManager.SENSOR_DELAY_GAME);

        FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
        main.addView(new Zoga(this, xPos, yPos, radius));
}

public void onAccuracyChanged(Sensor arg0, int arg1) {
    // TODO Auto-generated method stub

}

public void onSensorChanged(SensorEvent sensorArg) {
    if (sensorArg.sensor.getType() == Sensor.TYPE_ORIENTATION)
    {
            xAcc = sensorArg.values[1];
            yAcc = sensorArg.values[2];
        updateZoga();

    }

}

public void updateZoga()
{
    xPos += xAcc;
    yPos += yAcc;
    FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
    main.removeAllViews();
    main.addView(new Zoga(this, xPos, yPos, radius));
    try {
        Thread.sleep(1);
    } catch (InterruptedException e) {}

  }         
}

Zoga.java

package gravity.pack;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;

public class Zoga extends View{
    private final float x;
    private final float y;
    private final float r;
    private final Paint mPaint = new Paint (Paint.ANTI_ALIAS_FLAG);

    public Zoga(Context context, float x, float y, float r) {
        super(context);
        mPaint.setColor(0xFFFF0000);
        this.x = x;
        this.y = y;
        this.r = r;
    }

    @Override
    protected void onDraw(Canvas canvas){
        super.onDraw(canvas);
        canvas.drawCircle(x, y, r, mPaint);
    } 
}

Layout main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/main_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FF66FF33" />

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏日落 2025-01-14 12:20:17

你做错了。您正在将加速度值添加到位置值中。相反,您应该不断添加加速度值,通过此您将获得速度值。现在,如果您继续添加速度值,您将获得位置值。现在您应该将此位置值添加到函数 updateZoga 中

You are doing a mistake. You are adding value of acceleration into value of position. Instead of this you should keep adding the value of acceleration, through this you will get te value of velocity. Now if you keep adding the value of velocity you will get value of position. Now you should add this value of position into function updateZoga

多情癖 2025-01-14 12:20:17

我对 onSensorChange 代码做了一些更改以在屏幕中移动球。在我的例子中,球没有正确移动,为此我做了一些改变。这个例子对我来说效果很好。

public void onSensorChanged(SensorEvent sensorEvent)
{
    //Try synchronize the events
    synchronized(this){
    //For each sensor
    switch (sensorEvent.sensor.getType()) {
    case Sensor.TYPE_MAGNETIC_FIELD: //Magnetic sensor to know when the screen is landscape or portrait
        //Save values to calculate the orientation
        mMagneticValues = sensorEvent.values.clone();
        break;
    case Sensor.TYPE_ACCELEROMETER://Accelerometer to move the ball
        if (bOrientacion==true){//Landscape
            //Positive values to move on x
            if (sensorEvent.values[1]>0){
                //In margenMax I save the margin of the screen this value depends of the screen where we run the application. With this the ball not disapears of the screen
                if (x<=margenMaxX){
                    //We plus in x to move the ball
                    x = x + (int) Math.pow(sensorEvent.values[1], 2);
                }
            }
            else{
                //Move the ball to the other side
                if (x>=margenMinX){
                    x = x - (int) Math.pow(sensorEvent.values[1], 2);
                }
            }
            //Same in y
            if (sensorEvent.values[0]>0){
                if (y<=margenMaxY){
                    y = y + (int) Math.pow(sensorEvent.values[0], 2);
                }
            }
            else{
                if (y>=margenMinY){
                    y = y - (int) Math.pow(sensorEvent.values[0], 2);
                }
            }
        }
        else{//Portrait
            //Eje X
            if (sensorEvent.values[0]<0){
                if (x<=margenMaxX){
                    x = x + (int) Math.pow(sensorEvent.values[0], 2);
                }
            }
            else{
                if (x>=margenMinX){
                    x = x - (int) Math.pow(sensorEvent.values[0], 2);
                }
            }
            //Eje Y
            if (sensorEvent.values[1]>0){
                if (y<=margenMaxY){
                    y = y + (int) Math.pow(sensorEvent.values[1], 2);
                }
            }
            else{
                if (y>=margenMinY){
                    y = y - (int) Math.pow(sensorEvent.values[1], 2);
                }
            }

        }
        //Save the values to calculate the orientation
        mAccelerometerValues = sensorEvent.values.clone();
        break;  
    case Sensor.TYPE_ROTATION_VECTOR:  //Rotation sensor
        //With this value I do the ball bigger or smaller
        if (sensorEvent.values[1]>0){
            z=z+ (int) Math.pow(sensorEvent.values[1]+1, 2);
        }
        else{
            z=z- (int) Math.pow(sensorEvent.values[1]+1, 2);                    
        }

    default:
        break;
    }
    //Screen Orientation
    if (mMagneticValues != null && mAccelerometerValues != null) {
        float[] R = new float[16];
        SensorManager.getRotationMatrix(R, null, mAccelerometerValues, mMagneticValues);
        float[] orientation = new float[3];
        SensorManager.getOrientation(R, orientation);
        //if x have positives values the screen orientation is landscape in other case is portrait
        if (orientation[0]>0){//LandScape
            //Here I change the margins of the screen for the ball not disapear
            bOrientacion=true;
            margenMaxX=1200;
            margenMinX=0;
            margenMaxY=500;
            margenMinY=0;
        }
        else{//Portrait
            bOrientacion=false;
            margenMaxX=600;
            margenMinX=0;
            margenMaxY=1000;
            margenMinY=0;
        }

    }
    }
}

我画球的视图类

public class CustomDrawableView extends View
{
    static final int width = 50;
    static final int height = 50;
    //Constructor de la figura
    public CustomDrawableView(Context context)
    {
        super(context);

        mDrawable = new ShapeDrawable(new OvalShape());
        mDrawable.getPaint().setColor(0xff74AC23);
        mDrawable.setBounds(x, y, x + width, y + height);
    }
    //Dibujamos la figura
    protected void onDraw(Canvas canvas)
    {
        //Actividad_Principal x,y,z are variables from the main activity where I have the onSensorChange
        RectF oval = new RectF(Actividad_Principal.x+Actividad_Principal.z, Actividad_Principal.y+Actividad_Principal.z, Actividad_Principal.x + width, Actividad_Principal.y + height);             
        Paint p = new Paint(); 
        p.setColor(Color.BLUE);
        canvas.drawOval(oval, p);
        invalidate();
    }
}

}

就是这样,希望对我们有帮助。

I have done some changes in onSensorChange code to move the ball in the screen. With the example in my case the ball don´t move correctly and for that I did the changes. This example Works fine for my.

public void onSensorChanged(SensorEvent sensorEvent)
{
    //Try synchronize the events
    synchronized(this){
    //For each sensor
    switch (sensorEvent.sensor.getType()) {
    case Sensor.TYPE_MAGNETIC_FIELD: //Magnetic sensor to know when the screen is landscape or portrait
        //Save values to calculate the orientation
        mMagneticValues = sensorEvent.values.clone();
        break;
    case Sensor.TYPE_ACCELEROMETER://Accelerometer to move the ball
        if (bOrientacion==true){//Landscape
            //Positive values to move on x
            if (sensorEvent.values[1]>0){
                //In margenMax I save the margin of the screen this value depends of the screen where we run the application. With this the ball not disapears of the screen
                if (x<=margenMaxX){
                    //We plus in x to move the ball
                    x = x + (int) Math.pow(sensorEvent.values[1], 2);
                }
            }
            else{
                //Move the ball to the other side
                if (x>=margenMinX){
                    x = x - (int) Math.pow(sensorEvent.values[1], 2);
                }
            }
            //Same in y
            if (sensorEvent.values[0]>0){
                if (y<=margenMaxY){
                    y = y + (int) Math.pow(sensorEvent.values[0], 2);
                }
            }
            else{
                if (y>=margenMinY){
                    y = y - (int) Math.pow(sensorEvent.values[0], 2);
                }
            }
        }
        else{//Portrait
            //Eje X
            if (sensorEvent.values[0]<0){
                if (x<=margenMaxX){
                    x = x + (int) Math.pow(sensorEvent.values[0], 2);
                }
            }
            else{
                if (x>=margenMinX){
                    x = x - (int) Math.pow(sensorEvent.values[0], 2);
                }
            }
            //Eje Y
            if (sensorEvent.values[1]>0){
                if (y<=margenMaxY){
                    y = y + (int) Math.pow(sensorEvent.values[1], 2);
                }
            }
            else{
                if (y>=margenMinY){
                    y = y - (int) Math.pow(sensorEvent.values[1], 2);
                }
            }

        }
        //Save the values to calculate the orientation
        mAccelerometerValues = sensorEvent.values.clone();
        break;  
    case Sensor.TYPE_ROTATION_VECTOR:  //Rotation sensor
        //With this value I do the ball bigger or smaller
        if (sensorEvent.values[1]>0){
            z=z+ (int) Math.pow(sensorEvent.values[1]+1, 2);
        }
        else{
            z=z- (int) Math.pow(sensorEvent.values[1]+1, 2);                    
        }

    default:
        break;
    }
    //Screen Orientation
    if (mMagneticValues != null && mAccelerometerValues != null) {
        float[] R = new float[16];
        SensorManager.getRotationMatrix(R, null, mAccelerometerValues, mMagneticValues);
        float[] orientation = new float[3];
        SensorManager.getOrientation(R, orientation);
        //if x have positives values the screen orientation is landscape in other case is portrait
        if (orientation[0]>0){//LandScape
            //Here I change the margins of the screen for the ball not disapear
            bOrientacion=true;
            margenMaxX=1200;
            margenMinX=0;
            margenMaxY=500;
            margenMinY=0;
        }
        else{//Portrait
            bOrientacion=false;
            margenMaxX=600;
            margenMinX=0;
            margenMaxY=1000;
            margenMinY=0;
        }

    }
    }
}

The view class where I draw the ball

public class CustomDrawableView extends View
{
    static final int width = 50;
    static final int height = 50;
    //Constructor de la figura
    public CustomDrawableView(Context context)
    {
        super(context);

        mDrawable = new ShapeDrawable(new OvalShape());
        mDrawable.getPaint().setColor(0xff74AC23);
        mDrawable.setBounds(x, y, x + width, y + height);
    }
    //Dibujamos la figura
    protected void onDraw(Canvas canvas)
    {
        //Actividad_Principal x,y,z are variables from the main activity where I have the onSensorChange
        RectF oval = new RectF(Actividad_Principal.x+Actividad_Principal.z, Actividad_Principal.y+Actividad_Principal.z, Actividad_Principal.x + width, Actividad_Principal.y + height);             
        Paint p = new Paint(); 
        p.setColor(Color.BLUE);
        canvas.drawOval(oval, p);
        invalidate();
    }
}

}

That is all, I hope help us.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文