如何使用游戏循环每五秒在屏幕上出现和消失一个对象
Posted
技术标签:
【中文标题】如何使用游戏循环每五秒在屏幕上出现和消失一个对象【英文标题】:How to appear and disappear an object on screen using game loop for every five second 【发布时间】:2012-09-05 12:53:03 【问题描述】:我正在尝试学习 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);
【问题讨论】:
乍一看,它似乎过度设计了。 您有一些日志消息:Log.i("Image ...
它们显示了什么?
【参考方案1】:
在这部分
if (image.isAppeared())
image.draw(canvas);
你永远不会清理你的画布。你所做的实际上是在同一个地方一遍又一遍地绘制你的图像。
您可能需要在 cas isAppeared()
is false
中重绘背景
编辑
您也可以在绘制图像之前使用 canvas.save(),当您不再需要该图像时使用 canvas.restore()。
【讨论】:
我刚刚使用了 canvas.drawColor(Color.CYAN);在 if 条件之外。 if (image.isAppeared()) image.draw(canvas); 谢谢 njzk2 :)【参考方案2】:不要尝试过早优化,游戏渲染通常效率低下,因为几乎所有屏幕的大部分都预计会发生变化。
循环应该是:
-
始终在画布上绘制背景
始终将所有游戏对象绘制到画布上,让它们决定它们是否可见,这将简化 MainGamePanel 类
最后总是显示画布(通过复制到图像)
扩展第 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);
【讨论】:
【参考方案3】:将MainGamePanel.java中的方法render改为
if (image.isAppeared() && canvas != null)
image.draw(canvas);
【讨论】:
以上是关于如何使用游戏循环每五秒在屏幕上出现和消失一个对象的主要内容,如果未能解决你的问题,请参考以下文章