1

我正在做一个简单的游戏,我有一个名为 GameLoop 的类,在 run() 方法中,代码将画布的引用传递给绘制圆的方法。这段代码只是一些测试代码。

我的问题是,如果我想创建几个带有圆圈的精灵对象(类)并在游戏开始时将它们放入列表中,我该如何传递画布的引用?我以前做过这个,但后来我在每个精灵对象中使用了位图,只是传递了图像的引用,但在这种情况下,我不确定我会怎么做,因为画布在 run() 方法中,我想在一开始就用 initializeGameObjects() 之类的方法创建我的精灵对象。我希望我的问题不清楚!?一些帮助!谢谢!

// Game loop ---------------------------------------
@Override
public void run() {
    // TODO Auto-generated method stub

    while (gameRunning) {
        if (!surfaceHolder.getSurface().isValid())
            continue;

    canvas = surfaceHolder.lockCanvas();

    // Call method to draw objects on screen
    drawObjects(canvas);

    surfaceHolder.unlockCanvasAndPost(canvas);
    }
}
// End game loop ---------------------------------------

// Method that draw everything on canvas
private void drawObjects(Canvas canvas) {

    // Test
    paint = new Paint();
    paint.setAntiAlias(true);
    paint.setColor(Color.WHITE);

    // Clear screen with black color
    canvas.drawRGB(0, 0, 0);

    // Draw a circle
    canvas.drawCircle(100, 100, 100, paint);    
}
4

2 回答 2

1

定义一个接口:

public interface Renderable{
    public void renderToCanvas(Canvas c);
} 

定义一个列表Renderables

private List<Renderable> sprites = new ArrayList<Renderable>();

创建添加/删除精灵的方法,确保它们是同步的:

public synchronized void addSprite(Renderable r){
  sprites.add(r);
}

public synchronized void removeSprite(Renderable r){
  sprites.remove(r);
}

这是绘制方法,也是同步的,所以你不会同时绘制和修改精灵列表。这要么由其他线程在循环中调用,要么由视图的onDraw()方法调用:

public synchronized void draw(Canvas c){
  // lock canvas if needed

  // common drawing code

  for(Renderable r :sprites){
    r.renderToCanvas(c);
  }

  // release canvas if locked
}

现在,您可以自由定义任何类型的精灵、圆形、方形或其他任何类型的精灵,

public class Circle implements Renderable{
  private Paint mPaint;
  private float mRadius;

  public Circle(Paint p, float r){
    mPaint = p;
    mRadius = r;
  }

  @Override
  public void renderToCanvas(Canvas c){
    c.drawCircle(100, 100, mRadius, mPaint);
  }
}

并将其添加到精灵列表:

addSprite(new Circle(new Paint(),20f));

注意:为了简单起见,我使用synchronized了更好的替代方法,例如原子标志。仅当您想在游戏循环运行时添加/删除精灵时才需要这些。如果您在开始游戏循环之前设置所有精灵,这不是问题。

于 2013-04-26T06:21:21.920 回答
1

我会实现 Runnable 并构造一个线程。这样你就可以有一个“setup”方法,它最终调用一个“start”方法。“开始”方法将在启动线程之前绘制到画布上。

对于这类东西,这实际上是更好的做法。您可能想在启动线程之前初始化一些东西。

public class Game implements Runnable {
    private Thread thisThread = new Thread(this);
    private boolean gameRunning = false;

    public void startGame() {
       gameRunning = true;
       //Draw to canvas
       thisThread.start();
    }

    @Override
    public void run() {
        while(gameRunning) {
        //Draw other objects
        }
    }
}
于 2013-04-26T06:09:54.957 回答