2013-06-04 47 views
4

我從過去幾天開始閱讀「開始安卓遊戲」一書。但我堅持瞭解代碼。我需要一個「開始安卓遊戲」代碼的解釋

您可以查看或下載代碼: http://code.google.com/p/beginnginandroidgames2/downloads/list

我的意思是該項目是ch06-mr-mom。該活動被稱爲MrNomGame

public abstract class AndroidGame extends Activity implements Game { 

    AndroidFastRenderView renderView; 
    Graphics graphics; 
    Audio audio; 
    Input input; 
    FileIO fileIO; 
    Screen screen; 
    WakeLock wakeLock; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     boolean isLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; 
     int frameBufferWidth = isLandscape ? 480 : 320; 
     int frameBufferHeight = isLandscape ? 320 : 480; 
     Bitmap frameBuffer = Bitmap.createBitmap(frameBufferWidth, 
       frameBufferHeight, Config.RGB_565); 

     float scaleX = (float) frameBufferWidth 
       /getWindowManager().getDefaultDisplay().getWidth(); 
     float scaleY = (float) frameBufferHeight 
       /getWindowManager().getDefaultDisplay().getHeight(); 

     renderView = new AndroidFastRenderView(this, frameBuffer); 
     graphics = new AndroidGraphics(getAssets(), frameBuffer); 
     fileIO = new AndroidFileIO(this); 
     audio = new AndroidAudio(this); 
     input = new AndroidInput(this, renderView, scaleX, scaleY); 
     screen = getStartScreen(); 
     setContentView(renderView); 

     PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 
     wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame"); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     wakeLock.acquire(); 
     screen.resume(); 
     renderView.resume(); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     wakeLock.release(); 
     renderView.pause(); 
     screen.pause(); 

     if (isFinishing()) 
      screen.dispose(); 
    } 

    public Input getInput() { 
     return input; 
    } 

    public FileIO getFileIO() { 
     return fileIO; 
    } 

    public Graphics getGraphics() { 
     return graphics; 
    } 

    public Audio getAudio() { 
     return audio; 
    } 

    public void setScreen(Screen screen) { 
     if (screen == null) 
      throw new IllegalArgumentException("Screen must not be null"); 

     this.screen.pause(); 
     this.screen.dispose(); 
     screen.resume(); 
     screen.update(0); 
     this.screen = screen; 
    } 

    public Screen getCurrentScreen() { 
     return screen; 
    } 
} 

類實現接口Game

package com.badlogic.androidgames.framework; 

public interface Game { 
    public Input getInput(); 
    public FileIO getFileIO(); 
    public Graphics getGraphics(); 
    public Audio getAudio(); 
    public void setScreen(Screen screen); 
    public Screen getCurrentScreen(); 
    public Screen getStartScreen(); 
} 

我的第一個問題是:我錯過了方法的接口GamegetStartScreen()的實施。通常我必須實現一個接口的所有方法。

無論如何,現在onCreate正在運行。在這條線:

screen = getStartScreen(); 

該程序返回到原點類MrNomGame,其中該方法getStartScreen()給出LoadingScreen一個目的是可變screenLoadingScreen類:

public class LoadingScreen extends Screen { 

    public LoadingScreen(Game game) { 
     super(game); 
    } 

    public void update(float deltaTime) { 
     Graphics g = game.getGraphics(); 
     Assets.background = g.newPixmap("background.png", PixmapFormat.RGB565); 
     Assets.logo = g.newPixmap("logo.png", PixmapFormat.ARGB4444); 
     Assets.mainMenu = g.newPixmap("mainmenu.png", PixmapFormat.ARGB4444); 
     Assets.buttons = g.newPixmap("buttons.png", PixmapFormat.ARGB4444); 
     Assets.help1 = g.newPixmap("help1.png", PixmapFormat.ARGB4444); 
     Assets.help2 = g.newPixmap("help2.png", PixmapFormat.ARGB4444); 
     Assets.help3 = g.newPixmap("help3.png", PixmapFormat.ARGB4444); 
     Assets.numbers = g.newPixmap("numbers.png", PixmapFormat.ARGB4444); 
     Assets.ready = g.newPixmap("ready.png", PixmapFormat.ARGB4444); 
     Assets.pause = g.newPixmap("pausemenu.png", PixmapFormat.ARGB4444); 
     Assets.gameOver = g.newPixmap("gameover.png", PixmapFormat.ARGB4444); 
     Assets.headUp = g.newPixmap("headup.png", PixmapFormat.ARGB4444); 
     Assets.headLeft = g.newPixmap("headleft.png", PixmapFormat.ARGB4444); 
     Assets.headDown = g.newPixmap("headdown.png", PixmapFormat.ARGB4444); 
     Assets.headRight = g.newPixmap("headright.png", PixmapFormat.ARGB4444); 
     Assets.tail = g.newPixmap("tail.png", PixmapFormat.ARGB4444); 
     Assets.stain1 = g.newPixmap("stain1.png", PixmapFormat.ARGB4444); 
     Assets.stain2 = g.newPixmap("stain2.png", PixmapFormat.ARGB4444); 
     Assets.stain3 = g.newPixmap("stain3.png", PixmapFormat.ARGB4444); 
     Assets.click = game.getAudio().newSound("click.ogg"); 
     Assets.eat = game.getAudio().newSound("eat.ogg"); 
     Assets.bitten = game.getAudio().newSound("bitten.ogg"); 
     Settings.load(game.getFileIO()); 
     game.setScreen(new MainMenuScreen(game)); 
    } 

    public void present(float deltaTime) { 

    } 

    public void pause() { 

    } 

    public void resume() { 

    } 

    public void dispose() { 

    } 
} 

Screen類:

public abstract class Screen { 
    protected final Game game; 

    public Screen(Game game) { 
     this.game = game; 
    } 

    public abstract void update(float deltaTime); 
    public abstract void present(float deltaTime); 
    public abstract void pause(); 
    public abstract void resume(); 
    public abstract void dispose(); 
} 

經過一定時間後,該方法onCreate()完成。但在調試模式下,我的手機屏幕已經黑而黑。這似乎是程序在循環中。我可以按我想要的頻率按F6。但是,當我恢復主菜單將顯示。如果您查看代碼,您將看到主菜單將使用方法loadingScreen進行調用。

我的大問題是:onCreate()方法後會發生什麼結束,並且程序是如何進入的loadingScreenupdate()方法?

我知道這是很多代碼。但對我來說理解它會非常有用。

+13

上帝保佑勇敢的Stackoverflowers誰讀到最後。 – xyz

+1

您的更新方法有問題。它會調用Game.setScreen,並且您的Game實現在setScreen結束時調用update。它看起來像一個無限的遞歸給我。 – njzk2

+0

@ njzk2起初,'screen'是'LoadingScreen'的一個實例。該類的'update'將'screen'設置爲'MainMenuScreen'的一個實例。因此,新的'update'在不同的類上被調用。 –

回答

4

對於你的第一個問題:AndroidGame是一個摘要類。這意味着它不必執行Game的所有方法,只要其中一個類擴展爲AndroidGame即可。正如你可以從代碼中看到,這是在MrNomGame完成:

public class MrNomGame extends AndroidGame { 
    public Screen getStartScreen() { 
     return new LoadingScreen(this); 
    } 
} 

現在你的大問題:

onCreate,創建渲染:

renderView = new AndroidFastRenderView(this, frameBuffer); 

如果你有一個看看那個課程,你會看到onResume創建了一個運行以下代碼的新線程:

public void run() { 
    Rect dstRect = new Rect(); 
    long startTime = System.nanoTime(); 
    while(running) { 
     if(!holder.getSurface().isValid()) 
      continue;   

     float deltaTime = (System.nanoTime()-startTime)/1000000000.0f; 
     startTime = System.nanoTime(); 

     game.getCurrentScreen().update(deltaTime); 
     game.getCurrentScreen().present(deltaTime); 

     Canvas canvas = holder.lockCanvas(); 
     canvas.getClipBounds(dstRect); 
     canvas.drawBitmap(framebuffer, null, dstRect, null); 
     holder.unlockCanvasAndPost(canvas); 
    } 
} 

因此,在當前屏幕上重複調用update,這是LoadingScreen的實例。

+0

謝謝你的幫助。另一個問題:什麼叫「AndroidFastRenderView」中的「onResume」和「run」方法?爲什麼我需要這個界面「可運行」?也許我不明白接口的目的。我認爲它處理由「AndroidFastRenderView」擴展的「SurfaceView」類。 –

+0

@PeterPanne正如您在發佈的代碼中看到的那樣,'AndroidGame.onResume'在'AndroidFastRenderView'中調用'resume'方法(如果您想知道爲什麼要調用'onResume',請查看[Activity Lifecycle ](http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle))。 'run'方法由'renderThread.start()'調用。這是因爲'AndroidFastRenderView'實現了'Runnable',這意味着它可以在單獨的線程中運行,以便不凍結GUI。 –

+0

非常感謝。我想現在我明白了。 「運行」中的while循環是一個無限循環。所以它需要自己的線程,否則意志應用程序會凍結。我對界面「runnable」不夠了解,但我知道它是必需的,因爲這個類只能擴展一個類。因此你需要這個界面。目前我不瞭解接口的整個主題。我會很快開一個新的線索來詢問一些事情。非常感謝您解答我的問題。 –