Простой круг, движущийся с акселерометром

Я снова отредактировал всю тему, основываясь на том, что у меня есть до сих пор, так как у меня было так много просмотров предыдущей темы и ни одного ответа. Тем временем я вроде как понял, как работает акселерометр.

Теперь у меня есть круг (холст), который я хочу назвать "Зога", если не возражаете. Этот круг должен двигаться в зависимости от угла наклона телефона. Таким образом, если телефон перемещается влево, круг перемещается по левой стороне, если телефон перемещается вниз-вправо, круг движется в этом направлении.

Цикл создается с помощью класса Zoga.java, а вся магия происходит в GravitacijaActivity.java.

У меня есть 2 проблемы:
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) {}

  }         
}


Зога.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" />

person user1223725    schedule 21.02.2012    source источник


Ответы (2)


Вы делаете ошибку. Вы добавляете значение ускорения к значению положения. Вместо этого вы должны продолжать добавлять значение ускорения, через это вы получите значение скорости. Теперь, если вы продолжите добавлять значение скорости, вы получите значение положения. Теперь вы должны добавить это значение позиции в функцию updateZoga.

person aps109    schedule 11.03.2012

Я внес некоторые изменения в код 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();
    }
}

}

Вот и все, надеюсь нам поможет.

person Pedro    schedule 13.04.2013