버그 잡이

android 기울기 센서로 공 움직이기(Accelometer sensor) #android sensor 본문

안드로이드

android 기울기 센서로 공 움직이기(Accelometer sensor) #android sensor

버그잡이 2020. 3. 17. 21:26

https://androidkennel.org/android-sensors-game-tutorial/

 

How to Use Android Sensors in Games

In this post, we're going to learn how to access just one of the multitude of sensors present on an Android device by building a very small game that uses the accelerometer on the device. This

androidkennel.org

해당 블로그 글을 보고 정리하는 글입니다.

 

 

 

 

1. 스크린 전체를 활용하기 위해서 setContentView(R.layout.activity_main) 이 아닌 setContentView(BallView)를 쓴다.

private class BallView extends View {
    public BallView(Context context) {
        super(context);
    }
}

위와 같이 Class를 만들어 사용합니다.

레이아웃으로 ui를 그리는 것이 아니라 canvas를 활용해서 그리는 것입니다.

이와 관련된 구체적인 사항은 뒤에서 자세히 알아보겠습니다.

 

 

 

 

2. 공의 위치를 나타내 줄 변수를 선언하자.

private float xPos, xAccel, xVel = 0.0f;
private float yPos, yAccel, yVel = 0.0f;
private float xMax, yMax;
private Bitmap ball;
private SensorManager sensorManager;

 

 

 

 

3. onCreate()에서 View를 그려주고 화면의 최대크기를 정의해준다.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);	//세로모드 고정
    BallView ballView = new BallView(this);
    setContentView(ballView);
 
 	//기본 화면 사이즈를 받아와서 x축, y축 maxSize 설정
    Point size = new Point();
    Display display = getWindowManager().getDefaultDisplay();
    display.getSize(size);
    xMax = (float) size.x - 100;
    yMax = (float) size.y - 100;
 
    sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}

  마지막으로 sensorManager도 선언해줍니다.

 

 

 

 

4. onStart(), onStop() 생명주기를 활용하여 sensorManagerListener를 등록하고 해제합니다.

@Override
protected void onStart() {
    super.onStart();
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
}
 
@Override
protected void onStop() {
    sensorManager.unregisterListener(this);
    super.onStop();
}

 

 

 

 

5. onSensorChanged()를 override 해줍니다.

   참고로 sensor를 쓰기 위해서는 SensorEventListener를 implement해줘야합니다.

   그러면 자동으로 onSensorChanged(), onFlushCompleted(), onAccuracyChanged()를 오버라이드 할 수 있습니다.

   하지만 여기서 우리가 사용할 것은 onSensorChanged()뿐입니다.

@Override
public void onSensorChanged(SensorEvent sensorEvent) {
    if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        //values[0] = x축 가속도, values[1] = y축 가속도, values[2] = z축 가속도
        xAccel = sensorEvent.values[0];		
        yAccel = -sensorEvent.values[1];
        updateBall();
    }
}

yAccel에 '-' 를 붙여주지 않으면 공이 x축으로만 이동합니다. (왜 그러지? 아시는 분은 댓글 부탁드립니다!) 

 

 

 

 

 

 

6. Ball의 위치 최신화

기본적으로 게임은 frameTime에 객체를 움직입니다. 하지만 우리의 ballgame은 그럴 경우 속도가 너무 빠르다. 조정해줄 필요가 있다.(그래서 0.666을 곱해준듯 합니다. 저는 실제로 해보니 이것도 빨라서 너 낮췄습니다.)

private void updateBall() {
    float frameTime = 0.666f;
    xVel += (xAccel * frameTime);
    yVel += (yAccel * frameTime);
 
    float xS = (xVel / 2) * frameTime;		//x축 이동 속도
    float yS = (yVel / 2) * frameTime;		//y축 이동 속도
 
    xPos -= xS;								//x축 위치
    yPos -= yS;								//y축 위치
 
    if (xPos > xMax) {
        xPos = xMax;
    } else if (xPos < 0) {
        xPos = 0;
    }
 
    if (yPos > yMax) {
        yPos = yMax;
    } else if (yPos < 0) {
        yPos = 0;
    }
}

결국 여기서는 속도를 조절할 수 있습니다.

 

 

 

 

 

7. 수치는 다 얻었으니 BallView를 그려보자

private class BallView extends View {
 
    public BallView(Context context) {
        super(context);
        Bitmap ballSrc = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
        final int dstWidth = 100;
        final int dstHeight = 100;
        ball = Bitmap.createScaledBitmap(ballSrc, dstWidth, dstHeight, true);
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(ball, xPos, yPos, null);
        invalidate();
    }
}

 

onDraw가 수치들을 읽으며 위치를 최신화 해줍니다.

 

 

 

 

[추가 TIP]

"Button 클릭과 같은 activity의 여러 가지 동작을 취하고 싶은 경우는 어떻게 하나?"

 

- 기본적으로 setContentView(activity_layout.xml) 하고

- FrameLayout으로 위에 BallView를 겹쳐줍니다.

 

https://m.blog.naver.com/PostView.nhn?blogId=i_ehdfyd&logNo=50134181710&proxyReferer=https%3A%2F%2Fwww.google.com%2F

 

반응형
Comments