페인트로 만든 순서도 이미지를 첨부했습니다.
이미지는 게임 개발 방법을 보여줍니다. 업데이트가 쉬운 스마트 코딩과 시간이 지남에 따라 광고 기능이 뛰어난 게임을 원합니다. 내 목표 플랫폼은 안드로이드 스마트 폰이며 모든 코드는 XML 팽창 리소스를 사용하여 Java로 작성됩니다. 의사 코드가 도움이 될지라도 하드 코드를 찾고 있지는 않지만 제안을 더 선호하고 전문가의 조언을 구합니다.
내 질문은 :
이것이 게임을 프로그래밍하는 좋은 방법입니까, 아니면 더 좋은 방법이 있습니까? 수정이 필요합니까? 게임 프로그래밍에 경험이 없기 때문에 어떤 제안이라도 유용 할 수 있으므로 여러 게임을 작성한 사람의 조언을 선호하고 경험을 통해 효율적으로 코드를 설정하는 방법에 대해 알고 싶습니다.
답변
많은 안드로이드 게임은 저장 /로드 또는 옵션 / 환경 설정을 정당화 할 수있을 정도로 범위가 크지 않습니다. 맞춤형 캐릭터 등은 기차 집에서 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 만 호출됩니다.
다음 은 단일 활동 / 프레임 레이아웃 아이디어에 대한 이전 질문 에 대한 다이어그램입니다 .
답변
다이어그램에서 볼 수있는 많은 것은 UI와 관련이 있으며 상당히 합리적입니다. 실제 게임 로직을 위해 예약 된 다이어그램의 일부만 있으며 매우 모호합니다.
나는 당신이 너무 열심히 노력하고 있다고 생각합니다. 코드 작성을 시작하는 것이 좋습니다. 특정 문제를 선택하고 해결을 시작하십시오. 당신은 문제 공간이 무엇인지에 대해 더 잘 이해할 때까지 완전히 다른 (더 유용한) 관점을 갖게 될 것입니다.