2013-05-21 3 views
0

SurfaceView를 사용하여 LunarLander와 유사한 프레임 워크로 비트 맵을 그리는 Android 게임 엔진을 개발 중입니다. 아래 그림과 같이 내 주요 게임 엔진 활동은 하는 서피스 뷰 SurfaceView 확장 클래스를 표시해야한다는 등의 레이아웃을 설정합니다 :(SurfaceHolder.Callback) surfaceCreated는 결코 호출되지 않았습니다

super.onCreate(savedInstanceState); 

    setContentView(R.layout.ss_layout); 

    SSSurfaceView ssSurfaceView = (SSSurfaceView)findViewById(R.id.surface_view); 
    SSSurfaceView.SSViewThread renderThread = 
     (SSSurfaceView.SSViewThread) ssSurfaceView.getThread();  

findViewById를 방법이 성공적으로 내 서피스 뷰 SurfaceView 확장 클래스의 인스턴스를 반환하고, 나는 수 있어요 I는이 방법에서 생성 된 클래스의 클래스 생성자 내에 정의 스레드를 실행

public SSSurfaceView(Context context, AttributeSet attributes) 
{ 
    super(context, attributes); 

    SurfaceHolder holder = getHolder(); 
    holder.addCallback(this); 

    thread = new SSViewThread(holder, context); 
} 

그 다음 스레드 CONSTRUC에 전달 연관된 SurfaceHolder에 대한 참조를 획득한다 생성자 토르. holder.lockCanvas (null)가 null을 반환하는 스레드 실행 메서드에서 문제가 발생하기 시작했습니다. 어딘가에 서피스가 생성되지 않았다는 것을 읽을 수 있으므로, ifCreated 콜백에서 true로 설정 한 boolean을 사용하여 if 문을 추가했습니다. 여기

public void run() 
    { 
     Canvas canvas = null; 
     try 
     { 
      canvas = holder.lockCanvas(null); 
      //I added the condition below 
      if(surfaceCreated) 
      { 
       drawAll(canvas); 
      } 
     } 
     catch(Exception e) 
     { 
      Log.wtf("SurfaceView", "exception"); 
     } 
     finally 
     { 
      if(canvas != null) 
      { 
       holder.unlockCanvasAndPost(canvas); 
      } 
     } 
    } 

그리고

콜백입니다 :

public void surfaceCreated(SurfaceHolder holder) 
{ 
    surfaceCreated = true; 
} 

그리고 그것은 밝혀, surfaceCreated가 호출되지 않습니다. drawAll 메서드는 결코 반복되지 않으므로 내 응용 프로그램은 회색 화면을 표시하고 다른 작업은 수행하지 않습니다.

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <com.bostonwalker.sseng.SSSurfaceView 
     android:id="@+id/surface_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

</FrameLayout> 

편집 : 이것은 내가 관련 섹션 내 예를 제한하려고 내 전체 코드가 아닙니다 다음 부팅에 layout.xml 파일입니다. 스레드는 주 루프에서 호출되지만 시간이 주어지면 콜백이 실행되지 않습니다.

편집 : 여기에 UI 스레드에서 반복 루프입니다 :

while(!halt) 
    { 
     //EDIT: Changed from .run() to .start() 
     renderThread.start(); 
     gameThread.start(); 
     //Wait for both threads to proceed before continuing 
     try 
     { 
      renderThread.join(); 
      gameThread.join(); 
     } 
     catch (InterruptedException e) 
     { 
      //Do nothing 
     } 

     Thread.currentThread(); 
     try 
     { 
      Thread.sleep(2); 
     } 
     catch (Exception e) 
     { 
      //Do nothing 
     } 
    } 
+0

미안하지만 'while (! halt)'루프와 컨텐츠는 정말 악마처럼 보입니다. 그렇게 할 필요가 있을까요? – WarrenFaith

+0

그게 문제는 아니지만 걱정됩니다. 이 시점에서 필자는 최적화 또는 유연성에 관심을 갖지 않고 표시 할 SurfaceView와 호출 할 콜백을 가져옵니다. –

답변

1

그리기 스레드가없는 루프를 않습니다 - 그냥 한 번 출구 실행됩니다. 그리고 첫 번째 실행에서 표면이 아직 생성되지 않은 것 같습니다.

당신은 (의사 코드) 등 현재 루프의 일종에있는 코드를 넣어해야합니다 :

while(!done) { 
    lockTheCanvas(); 
    drawAFrame(); 
    unlockTheCanvas(); 
    sleep(FRAME_INTERVAL); 
} 
그런 다음 적절한 시간에 의해에서 스레드를 종료 할 필요가

을 "done"을 true로 설정하십시오. sleep()이 필요함을 주목하십시오. 그렇지 않으면 스레드가 CPU를 hog하고 절대로 종료하지 않습니다.

+0

스레드는 1 차 루프에 의해 초당 10 회 활성화되며 최소한 그 부분을 완벽하게 처리합니다. 내 문제는 표면이 결코 생성되지 않는다는 것입니다. 적어도 콜백은 결코 발생하지 않습니다. –

+0

나는 어떻게 10 번에 1 번 스레드를 활성화 시킬지 의심 스럽다. 당신이 사용하고있는 루프가 콜백을 호출 할 수 있도록 적절하게 (수면에 의해) 굴복하고 있는가? 또한 스레드가 한 번 실행 된 다음 종료되고 여러 번 호출되는 이유는 무엇입니까? 내 의사 코드 예제 에서처럼 스레드가 중단 될 때까지 계속 실행되도록하는 것이 더 나을 것입니다. – GreyBeardedGeek

+0

조금 단순화되었지만 루프를 UI 스레드 (기본 활동 .java)에 반복 게시했습니다. –

관련 문제