且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我需要的&QUOT code进行解释;在开始的Andr​​oid游戏"

更新时间:2022-12-08 22:42:19

有关你的第一个问题: AndroidGame 摘要的类。这意味着它没有实现的所有方法游戏,只要延长类之一 AndroidGame 做这个。正如你可以从code看到,这是在做 MrNomGame

 公共类MrNomGame扩展AndroidGame {
    公共屏幕getStartScreen(){
        返回新LoadingScreen(本);
    }
}

现在你的大问题:

的onCreate ,创建一个渲染器:

 的RenderView =新AndroidFastRenderView(这一点,FRAMEBUFFER);

如果你看一下这个类,你会看到 onResume 创建运行下列code一个新的线程:

 公共无效的run(){
    矩形dstRect =新的矩形();
    长STARTTIME = System.nanoTime();
    而(运行){
        如果(!holder.getSurface()。isValid()的)
            继续;        浮动deltaTime =(System.nanoTime() - startTime时)/ 1000000000.0f;
        STARTTIME = System.nanoTime();        。game.getCurrentScreen()更新(deltaTime);
        game.getCurrentScreen()present(deltaTime)。        帆布帆布= holder.lockCanvas();
        canvas.getClipBounds(dstRect);
        canvas.drawBitmap(帧缓冲,空,dstRect,NULL);
        holder.unlockCanvasAndPost(画布);
    }
}

因此​​,重复调用更新在当前屏幕上,这是 LoadingScreen 的实例。

I am reading the book "Beginning Android Games" since last couple of days. But I am stuck to understand the code.

You can check or download the code here: http://code.google.com/p/beginnginandroidgames2/downloads/list

The project I mean is ch06-mr-mom. The Activity is called 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;
    }
}

The class implements the interface 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();
}

My first question is: I missed the implementation of the method getStartScreen() of the interface Game. Usually I have to implement all methods of an interface.

Anyway, now the onCreate is running. At this line:

screen = getStartScreen();

The program goes back to the origin class MrNomGame, where the method getStartScreen() gives an object of LoadingScreen to the variable screen. Class LoadingScreen:

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() {

    }
}

Class 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();
}

After a certain time, the onCreate() method is finished. But in the Debug-Mode the screen of my mobile phone is already black and dark. It seems to be the program is in a loop. I can press F6 as often as I want. But when I resume the Main-Menu will shown. If you look in the code you will see that the Main-Menu will call in the update() method of loadingScreen.

My big question is: What happens after the onCreate() method is finished and how the program get into the update() method of loadingScreen?

I know that is a lot of code. But it would be very useful for me to understand it.

For your first question: AndroidGame is an abstract class. This means it doesn't have to implement all methods of Game, as long as one of the classes extending AndroidGame does this. As you can see from the code, this is done in MrNomGame:

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

Now for your big question:

In onCreate, a renderer is created:

renderView = new AndroidFastRenderView(this, frameBuffer);

If you have a look at that class, you see that onResume creates a new thread that runs the following code:

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);
    }
}

So, it repetitively calls update on the current screen, which is the instance of LoadingScreen.