Простой круговорот с акселерометром - PullRequest
0 голосов
/ 21 февраля 2012

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

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

Цикл создается через класс 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) {}

  }         
}


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" />

Ответы [ 2 ]

0 голосов
/ 13 апреля 2013

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

}

Это все, я надеюсь помочь нам.

0 голосов
/ 11 марта 2012

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

...