[안드로이드 게임 개발] 기초다지기 SurfaceView
안드로이드에서 기본 뷰(view)는 게임을 만들때에는 적합하지 않습니다. 안드로이드에서는 5초이상 동작이 멈추면 ANR(Application Not Responding)에러가 발생하게 되는데요. 게임과 같이 연산처리가 많은 어플을 UI스레드에서 처리하다 보면 GUI업데이트가 늦어지게 되고 ANR에러가 발생하게 됩니다. 이런 에러 발생을 막기 위해서 SurfaceView를 사용하는 것입니다. 다른View는 화면 업데이트를 UI스레드에서 처리하지만 SurfaceView는 백그라운드로 처리하므로 어플의 자원을 차지하지 않고 원할하게 업데이트를 할 수 있습니다.
그리고 OpenGL을 통한 가속도 지원하기 때문에 3D 그래픽도 표현 할 수 있습니다.
위 그림에서 보듯이 SurfaceView는 하나의 틀의 역할을 합니다. 실질적으로 화면을 처리해주는 것은 SurfaceHolder의 객체가 Surface에 접근해서 처리합니다.
■ 먼저 기본 프레임을 하나만들고 View를 상속받은 클래스를하나 만들어서 일반 View로 아이콘 이미지를 화면에 띄우는 과정까지 만들어 보겠습니다.
■ 실행을 해서 AVD에 아이콘이 제대로 출력되는 걸 확인하고 넘어가겠습니다.
■ 이제 SurfaceView를 프레임워크에 적용해 보겠습니다. GameView가 상속받은 클래스를 SurfaceView로 바꿔주겠습니다.
■ 상속받는 클래스를 변경하고 실행을 해보자 화면에 보이던 아이콘이 사라져버렸습니다.
■ 이것은 SurfaceView를 실제로 관리하는 객체가 SurfaceHolder이기 때문입니다. 화면을 그리는 canvas에 접근하려면 SurfaceHolder객체가 필요합니다. 이를 위해 SurfaceHolder.Callback의 순수가상 메서드를 구현해야 합니다.
■ 위와 같이 소스 코드를 추가하고 GameView의 생성자에서 Callback을 등록해 줘야 합니다.
■ 여기까지 하고 나서 다음으로 해야할 것은 그림을 관리하는 클래스를 만들어야 합니다. 그림 처리는 스레드를 이용합니다. 일단 Thread 클래스를 상속받는 GameViewThread클래스를 하나 만들겠습니다. GameView와 SurfaceHolder를 생성자 매개변수로 가지며, 스레드 실행을 위해 run()메서드를 재정의 합니다.
■ 방금 제작한 스레드 클래스를 GameView클래스의 멤버로 추가하고 생성자에서 인스턴스를 생성하는 코드를 추가하겠습니다.
■ 이제 SurfaceHolder.Callback을 implements해서 추가된 메서드에서 스레드를 시작하고 종료하는 코드를작성하겠습니다.
■ 지금까지의 코딩은 GameViewThread를 멤버 변수로 추가하고 생성자에서 인스턴스화 하고 GameView의 Surface가 생성될 때 스레드를 실행하고, Surface가 파괴될때 스레드를 종료시키는 과정입니다.
■ 다음으로 GameViewThread 클래스의 run()메서드를 구현해야 합니다.
■ 이렇게 하면 화면과 관련된 이벤트가 발생하지 않아도 게임 루프가 계속 돌아가는 기반을 만든 것입니다.