많은 안드로이드 게임은 저장 /로드 또는 옵션 / 환경 설정을 정당화 할 수있을 정도로 범위가 크지 않습니다. 맞춤형 캐릭터 등은 기차 집에서 10 분 동안 손으로 연주되기 때문에 결코 신경 쓰지 마십시오.
내가 첫 번째 안드로이드 게임을 위해 넓은 범위를 가진 무언가에 착수 한 실수를하지 마십시오. 더 작은 게임들을 만들고 더 큰 것을 찾으십시오
현명한 안드로이드 사양 :
구조:
하나의 액티비티 클래스에서 거의 모든 게임을하는 것이 좋습니다. Android는 각 액티비티가 앱의 다른 액티비티와 반독립적인 미니 앱과 같다는 생각으로 작동합니다. 응용 프로그램은 본질적으로 활동 스택이며 사용자가 가장 위에있는 것을 볼 수 있습니다.
상단에서 팝하면 일반적으로 소멸되고 다음에 사용자가 새 활동을 시작할 때 다시 시작됩니다 (startActivity 의도). 이것은 활동 사이의 상태를 유지하기 어렵게하고 단일 활동 아키텍처로 이어집니다.
"새 게임 /로드 게임 / 옵션"메뉴가있는 홈 화면 유형 활동을 갖고 시작 활동을 할 수 있습니다. 그러나 게임 활동뿐만 아니라 게임 내 메뉴가 있어야합니다.이 메뉴에는 대부분 동일한 기능이 있습니다.
내 자신의 응용 프로그램, 나는 새로운 게임을 시작, 저장,로드, 옵션을 변경하는 기능을 가진 "MenuActivity"를 만들었습니다. 그런 다음 내 GameActivity와 마찬가지로 HomeActivity도 확장됩니다.
모든 것이 하나의 Activity 클래스에 있으므로 활동 클래스 계층 구조를 만들고 개인, 보호 및 기본 범위 로트를 사용하는 것이 좋습니다. 이 방법을 사용하면 관리 할 수없는 하나의 활동 파일이없는 것을 최소한 다른 파일로 분할 할 수 있습니다. 예를 들어 내 자신의 앱 :
GraphicsEngine extends MenuActivity
.
PhysicsEngine extends GraphicsEngine
.
GameLogicActivity extends PhysicsEngine
.
UIActivity extends GameLogicActivity
.
내 앱은 3D opengl-es이므로 교차 활동을하지 않는 많은 것들이 있으므로 모든 것이 동일한 활동에 있으므로 하나의 활동 아키텍처를 사용하는 편견이 있습니다.
-
스레딩
게임 활동의 경우 두 개의 스레드가 있습니다 (또는 3D opengl 작업을 수행하는 경우 3 개). 하나의 스레드는 UI / 메인 스레드입니다. 이것은 활동이 시작되고 실행되는 스레드이며 안드로이드에 의해 제공됩니다.
이 UI 스레드는 UI 요소 (보기, 레이아웃 등)를 업데이트 할 수있는 유일한 스레드입니다. 또한 사용자 입력에 대한 리스너가 실행되는 스레드이기도합니다. UI 스레드의 메커니즘은 보이지 않지만 백그라운드에서 루프로 실행됩니다.
두 번째 스레드는 스스로 만드는 것입니다 ( 모든 단점에도 불구하고 AsyncTask 사용하는 것이 좋습니다 ). 이것은 움직임 업데이트, 충돌 계산, 전투 계산 등과 같은 일반적인 게임 루프에서 UI가 아닌 모든 작업을 수행합니다.
이 AsyncTask 스레드 / 클래스를 활동의 내부 클래스로 만듭니다. 그렇게하면 Vector<Spaceship>
UI 스레드와 게임 루프 스레드에서 모두 액세스 할 수있는 활동 범위 개체 ( )를 가질 수 있습니다.
게임 로직이 게임 루프 스레드에서 진행되고 있기 때문에 실제로 변수 값 (탱크 속도 업데이트, 플레이어 HP 감소)을 변경해야하는 유일한 스레드입니다. UI 스레드는 값을 읽으므로 동시성 문제가 최소화되어야합니다.
까다로운 비트는 UI 스레드가 게임 루프 스레드의 요청에 따라 업데이트를 수행하도록하는 것입니다. 이를 수행하는 몇 가지 방법이 있습니다. AsyncTask 설명서를 읽으면 publishProgress () / onProgressUpdate () 메서드가 있습니다. 이것은 실제로 다음 루프를 수행하기 위해 UI 스레드의 대기열에 물건을 추가합니다.
Handler는 handleMessage () 메소드를 구현하는 동일한 작업을 수행하며 해당 메소드는 실제로 UI 스레드 다음 루프에 의해 실행됩니다.
마지막으로 UI 스레드에있는 모든 사용자 입력은 UI 요소를 즉시 업데이트 할 수 있습니다 (따라서 onClick / onTouch 리스너 구현 내부). 게임 객체를 업데이트해야 할 경우 동기화와 같은 것을 사용하거나 UI 스레드와 같은 AsyncTask에 자체 업데이트 대기열을 구현할 수 있습니다. 다음에 게임 루프를 실행할 때까지 진행됩니다.
안드로이드 스레딩 안내서 .
-
UI
단일 액티비티 내의 실제 UI 구조에 대해서는 기본 레이아웃으로 프레임 레이아웃을 사용하는 것이 좋습니다. 프레임 레이아웃의 자식 요소는 대기열처럼 작동합니다. 첫 번째 요소는 먼저 그려지고, 두 번째 요소는 첫 번째 위에, 세 번째는 두 번째 위에 그려집니다.
이런 방식으로 여러 XML 레이아웃 파일을 가질 수 있으며 프레임 레이아웃의 자식을 관리하여 뷰 세트를 쉽게주고받을 수 있습니다.
항상 SurfaceView가 맨 아래 (프레임 레이아웃의 첫 번째 자식) 인 경우 Surface View의 맨 위에 모든 일반적인 Android보기 / 위젯 (단추, 텍스트보기, 스크롤보기) 등을 사용할 수 있습니다. 게임의 그래픽 부분.
예를 들어, 무언가가로드되면 게임 루프를 일시 중지하고 모든 것을 건너 뛰고 프레임 레이아웃의 마지막 자식으로 불투명 한 '로드 중'화면을 추가하면 화면에 '로드 중'이 표시됩니다 다른 견해가 뒤에 있다는 것을 잘 알지 못합니다. 이 방법을 사용하면 추가 / 제거 할 때마다 설정하거나 합병증을 유발하는 데 오랜 시간이 걸리는보기를 제거 할 필요가 없습니다.
View.setVisibility 로트를 사용하는 것이 좋습니다. 예를 들어 기본 프레임 레이아웃에 전체 '인벤토리'레이아웃을 추가 한 다음 사용자가 클릭하여 인벤토리를 볼 때 setVisibility (View.Visible)를 설정하고 다시 닫을 때 setVisibility (View.Gone)을 설정할 수 있습니다. 그렇게하면 사용자가 다른 일을 할 때뿐만 아니라 모든 것을 추가하고 볼 수 / 보이지 않는 것을 만드는 것만 큼 프레임 레이아웃의 자식을 관리하지 않아도됩니다.
이것은 다시 스레딩하는 데 도움이됩니다. 사용자가 클릭하여 인벤토리를 열면 onCLickListener가 UI 스레드에서 처리되고 해당 인벤토리가 표시되며 UI 스레드에서 updateInventory 메소드가 다시 호출되며 모든 게임 오브젝트에 대한 getter 만 호출됩니다.
다음 은 단일 활동 / 프레임 레이아웃 아이디어에 대한 이전 질문 에 대한 다이어그램입니다 .