0

对于我目前正在为 Android 设备编写的游戏,我有一个名为 RenderView 的类,它是一个线程,可以更新和渲染所有内容。有时,该类会记录消息“游戏线程仅更新更新方法并且不呈现任何内容”。游戏在我的 nexus 上以 30 fps 的速度运行。在整个会议期间,我多次收到该消息。有人可以告诉我如何优化课程,或者我忘记了什么或者这完全正常吗?

这是我的代码:

public class RenderView extends SurfaceView implements Runnable {

    public final String classTAG = this.getClass().getSimpleName();
    Game game;
    Bitmap framebuffer;
    Thread gameloop;
    SurfaceHolder holder;
    boolean running;

    int sleepTime;
    int numberOfFramesSkipped;
    long beginTime;
    long endTime;
    long lastTime;
    int differenceTime;
    int framePeriod;
    Canvas canvas;
    int frameCount;
    WSLog gameEngineLog;

    public RenderView(Game game, Bitmap framebuffer) {
        super(game);
        this.game = game;
        this.framebuffer = framebuffer;
        this.holder = getHolder();
        framePeriod = 1000/game.getFramesPerSecond();
        lastTime = System.currentTimeMillis();
        gameEngineLog = game.getGameEngineLog();
    }

    @Override
    public void run() {
        while(running == true) {
            if(holder.getSurface().isValid()) {

                beginTime = System.currentTimeMillis();
                numberOfFramesSkipped = 0;

                game.getCurrentScreen().update();
                game.getCurrentScreen().render(); // Draw out everything to the current virtual screen (the bitmap)
                game.getGraphics().renderFrameBuffer(); // Actually draw everything to the real screen (combine both bitmaps)

                canvas = holder.lockCanvas();
                if(canvas != null) { // Fix for mysterious bug ( FATAL EXCEPTION: Thread)
                    // The viewing area of our virtual screen on our real screen
                    canvas.drawBitmap(framebuffer, null, game.getWSScreen().getGameScreenextendeddst(), null);
                    holder.unlockCanvasAndPost(canvas);
                }
                else {
                    gameEngineLog.e(classTAG, "Surface has not been created or otherwise cannot be edited");
                }

                endTime = System.currentTimeMillis();;
                differenceTime = (int) (endTime - beginTime);
                sleepTime = (int) (framePeriod - differenceTime);

                if(sleepTime > 0) {
                    try {
                        Thread.sleep(sleepTime);
                    } catch (InterruptedException exception) {
                        exception.printStackTrace();
                    }
                }
                else {
                    while(sleepTime < 0 && numberOfFramesSkipped < game.getMaxFrameSkippes()) {
                        gameEngineLog.d(classTAG, "Game thread is only updating the update method and is not rendering anything");
                        try {
                            Thread.sleep(5);
                        } 
                        catch (InterruptedException exception) {
                            exception.printStackTrace();
                        }
                        game.getCurrentScreen().update();
                        sleepTime += framePeriod;
                        numberOfFramesSkipped++;
                    }
                }

             // Frame Per Second Count
                frameCount++;

                if(lastTime + 1000 < System.currentTimeMillis()) {
                    game.getGameEngineLog().d(classTAG, "REAL FPS: " + frameCount);
                    lastTime = System.currentTimeMillis();
                    frameCount = 0;
                }

            }
        }

    }

    public void resume() { 
        running = true;
        gameloop = new Thread(this);
        gameloop.start();         
    }   

    public void pause() { 
        running = false;                        
        while(running == true) {
            try {
                gameloop.join();
                running = false;
            } 
            catch (InterruptedException e) {
            }
        }
        gameloop = null;
    }

}

这是 Graphics 类的代码(getGraphics() 只返回一个图形对象):

public class Graphics {

    public final String classTAG = this.getClass().getSimpleName();
    Game game;
    Canvas frameBuffer;
    Canvas canvasGameScreenextended;
    Canvas canvasGameScreen; // Used for customeScreen
    Bitmap gameScreenextended;
    Bitmap gameScreen;
    Rect gameScreendst;
    Rect gameScreenextendeddst;
    WSLog gameEngineLog;

    Graphics(Game game, Bitmap framebuffer, Bitmap gameScreen) {
        this.game = game;
        // Initialize canvases to render to
        frameBuffer = new Canvas(framebuffer);
        canvasGameScreen = new Canvas(gameScreen);
        // Initialize images to be rendered to our composition
        this.gameScreen = gameScreen;
        // Set up the Log
        gameEngineLog = game.getGameEngineLog();
    }

    public void resetCanvasGameScreenextended() {
        // This method has to be called each time the screen scaling type changes
        canvasGameScreenextended = new Canvas(game.getWSScreen().getGameScreenextended());
        gameScreenextended = game.getWSScreen().getGameScreenextended();
    }

    public Canvas getCanvasGameScreenextended() {
        return canvasGameScreenextended;
    }

    public Canvas getCanvasGameScreen() {
        return canvasGameScreen;
    }

    public void renderFrameBuffer() {
        // Composition
        // First layer (bottom)
        frameBuffer.drawBitmap(gameScreen, null, game.getWSScreen().getGameScreendst(), null);
        // Second layer (top)
        frameBuffer.drawBitmap(gameScreenextended, null, game.getWSScreen().getGameScreenextendeddst(), null);
    }

    public void clearFrameBuffer() {
        canvasGameScreen.drawColor(Color.BLACK);
        //canvasGameScreenextended.drawColor(Color.BLACK);
        gameScreenextended.eraseColor(Color.TRANSPARENT); // Make top layer transparent
    }

}

这是屏幕类的代码(getCurrentScreen() 方法返回一个屏幕对象):

public class Screen {

    public final String classTAG = this.getClass().getSimpleName();
    protected final Game game;
    protected final Graphics graphics;

    protected Screen(Game game) {
        this.game = game;
        this.graphics = game.getGraphics();
        //game.getInput().reset();
    }

    public void update() {

    }

    public void render() {

    }

    /** Initialize all the sensory that should be used within this screen.*/

    public void resume() {

    }

    public void pause() {
        game.getInput().useAccelerometer(false);
        game.getInput().useKeyboard(false);
        game.getInput().useTouchscreen(false);
    }

    public void onDispose() {
        game.getGraphics().clearFrameBuffer();
    }

    public void setScreenResizeType(int screenResizeType) {

    }

Screen 类被扩展,render() 方法被以下方法遮蔽:

graphics.getCanvasGameScreen().drawRect(play, red);

有趣的是,当我覆盖 render() 方法并且没有在其中放置任何代码时,记录器会不断触发以下消息:“游戏线程仅更新更新方法并且不渲染任何内容”。这是什么魔法?!

非常感谢您的帮助!

4

1 回答 1

0

据我从您更新的帖子中了解到,实际上没有渲染问题。相反,您的代码错误地打印了该消息。

这是因为您检查 if(sleepTime > 0)了 ,因此如果渲染速度非常快并且 sleepTime 为零,您会收到该消息。只需将其更改为 if(sleepTime >= 0).

于 2012-05-18T15:55:44.633 回答