如何使用游戏循环每隔五秒在屏幕上显示和消失一个对象

时间:2012-09-05 12:53:04

标签: android game-loop

我正在尝试学习Android中的游戏开发。首先,我试图使用游戏循环每五秒钟在屏幕上出现并消失一个对象。但我没有成功。我已经阅读了不同的教程和论坛。我在教程中应用了所有内容,但仍然是对象不断绘制。它并没有消失。我没有得到我所缺少的东西?请指导我。

完整的代码在这里:

MainGameActivity.java

package com.example.showandhideobject;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class MainGameActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(new MainGamePanel(this));
    }  
}

MainGamePanel .java

package com.example.showandhideobject;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainGamePanel extends SurfaceView implements
        SurfaceHolder.Callback {

    private MainGameThread thread;
    private ImageObject image;

    // private long gameStartTime;

    public MainGamePanel(Context context) {
        super(context);
        // adding the callback (this) to the surface holder to intercept events
        getHolder().addCallback(this);
        // create the game loop thread
        thread = new MainGameThread(getHolder(), this);

        Bitmap imageBitMap = BitmapFactory.decodeResource(getResources(),
                R.drawable.rose);
        image = new ImageObject(imageBitMap, 100, 150);
        image.setAppeared(false);
        image.setDisappearTime(System.currentTimeMillis());

        // make the GamePanel focusable so it can handle events
        setFocusable(true);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // at this point the surface is created and
        // we can safely start the game loop

        thread.setRunning(true);
        thread.start();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    }

    public void update() {

        Log.i("Image Status:::::::::::::    ",
                Boolean.valueOf(image.isAppeared()).toString());

        if (!image.isAppeared()
                && System.currentTimeMillis() - image.getDisappearTime() >= 5000) {

            Log.i("Image Object:::::::  ", "Showing");
            image.setAppeared(true);
            image.setAppearTime(System.currentTimeMillis());

        }
        if (image.isAppeared()
                && (System.currentTimeMillis() - image.getAppearTime() >= 5000)) {

            Log.i("Image Object:::::::  ", "Not Showing");
            image.setAppeared(false);
            image.setDisappearTime(System.currentTimeMillis());
        }
    }

    public void render(Canvas canvas) {

        if (image.isAppeared()) {
            image.draw(canvas);
        }
    }

}

MainGameThread.java

package com.example.showandhideobject;

import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;

public class MainGameThread extends Thread {

    // Surface holder that can access the physical surface
    private SurfaceHolder surfaceHolder;

    // The actual view that handles inputs
    // and draws to the surface
    private MainGamePanel gamePanel;

    // flag to hold game state
    private boolean running;

    public boolean isRunning() {
        return running;
    }

    public void setRunning(boolean running) {
        this.running = running;
    }

    public MainGameThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
        super();
        this.surfaceHolder = surfaceHolder;
        this.gamePanel = gamePanel;
    }

    @Override
    public void run() {
        Canvas canvas;

        while (isRunning()) {
            canvas = null;
            // try locking the canvas for exclusive pixel editing
            // in the surface
            try {
                canvas = this.surfaceHolder.lockCanvas();
                synchronized (surfaceHolder) {
                    Log.i("With in :::::::::", "Game Loop");
                    // update game state
                    gamePanel.update();
                    // render state to the screen and draw the canvas on the
                    // panel

                    gamePanel.render(canvas);
                    // gamePanel.onDraw(canvas);
                }
            } finally {
                // in case of an exception the surface is not left in an
                // inconsistent state
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            } // end finally
        }
    }
}

ImageObject.java

package com.example.showandhideobject;

import android.graphics.Bitmap;
import android.graphics.Canvas;

public class ImageObject {

    private Bitmap bitmap; // the actual bitmap
    private int x; // the X coordinate
    private int y; // the Y coordinate
    private boolean isAppeared;
    private long appearTime;
    private long disappearTime;

    // Constructor for this class
    public ImageObject(Bitmap bitmap, int x, int y) {
        this.bitmap = bitmap;
        this.x = x;
        this.y = y;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public boolean isAppeared() {
        return isAppeared;
    }

    public void setAppeared(boolean isAppeared) {
        this.isAppeared = isAppeared;
    }

    public long getAppearTime() {
        return appearTime;
    }

    public void setAppearTime(long appearTime) {
        this.appearTime = appearTime;
    }

    public long getDisappearTime() {
        return disappearTime;
    }

    public void setDisappearTime(long disappearTime) {
        this.disappearTime = disappearTime;
    }

    /* Method to draw images on Canvas */
    public void draw(Canvas canvas) {
        canvas.drawBitmap(bitmap, x - (bitmap.getWidth() / 2),
                y - (bitmap.getHeight() / 2), null);
    }
}

3 个答案:

答案 0 :(得分:2)

在这部分

if (image.isAppeared()) {
    image.draw(canvas);
}

你永远不会清理你的画布。你在做什么实际上是在同一个地方反复绘制你的图像。

您可能需要重新绘制cas isAppeared() false

中的背景

修改

你也可以在绘制图像之前使用canvas.save(),在不再需要图像时使用canvas.restore()。

答案 1 :(得分:1)

不要试图过早优化,游戏渲染通常效率低下,因为几乎总是大部分屏幕都会发生变化。

循环应该是:

  1. 始终将背景绘制到画布
  2. 总是将所有游戏对象绘制到画布上,让他们决定是否可见,这将简化MainGamePanel类
  3. 最后总是显示画布(通过复制到你正在做的图像)
  4. 扩展第2点:

    /* Method to draw images on Canvas */  
    public void draw(Canvas canvas) { 
        if(!isAppeared) return; //let the object decide when it should be drawn
        canvas.drawBitmap(bitmap, x - (bitmap.getWidth() / 2),  
                y - (bitmap.getHeight() / 2), null);  
    }  
    

答案 2 :(得分:0)

将MainGamePanel.java中的方法渲染更改为

if (image.isAppeared() && canvas != null) {
        image.draw(canvas);
}