Java 如何将画布引用传递给类

Java 如何将画布引用传递给类,java,android,Java,Android,我正在做一个简单的游戏,我有一个叫做GameLoop的类,在run()方法中,代码将画布的引用传递给一个画圆的方法。这段代码只是一些测试代码 我的问题是,如果我想创建几个带圆圈的精灵对象(类),并在游戏开始时将它们放入列表中,如何传递画布的引用?我以前做过,但是我在每个精灵对象中使用了位图,只是传递了一个图像的引用,但是在这种情况下,我不确定该怎么做,因为画布在run()方法中,我想在一开始就用initializeGameObjects()这样的方法创建精灵对象。我希望我的问题不是不清楚!?谢谢

我正在做一个简单的游戏,我有一个叫做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);    
}

我将实现Runnable并构造一个线程。这样,您就可以有一个“setup”方法,它最终调用一个“start”方法。“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
        }
    }
}
定义一个接口:

public interface Renderable{
    public void renderToCanvas(Canvas c);
} 
定义可渲染的
列表

private List<Renderable> sprites = new ArrayList<Renderable>();
这是一种绘制方法,也是同步的,所以您不会同时绘制和修改精灵列表。这可以由其他线程在循环中调用,也可以由视图的
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
,但是有更好的替代方法,比如原子标志。只有当你想在游戏循环运行时添加/删除精灵时才需要这些。如果你在启动游戏循环之前设置所有精灵,这不是问题。

如果你还没有,你应该考虑双缓冲。谢谢你的回复,但是什么是双缓冲?对不起,我对这种编程还不熟悉!在您的代码中,如何处理和获取画布引用?由您决定如何获取画布引用,您可以将其与游戏构造函数一起传递,并将其存储为实例字段,或者在某个对象中的某个位置对其进行静态引用。双缓冲基本上是在屏幕上显示图像之前从屏幕上画出图像。实际上,您有一个当前显示在屏幕上的图像和一个正在从屏幕上绘制的图像。绘制后,屏幕外图像将与屏幕上的图像交换。看看BuffereImage和createGraphics方法。谢谢你提供的信息。双缓冲,这不是run()方法内部发生的事情吗!?不管怎样,它现在起作用了。我设法以另一种方式通过画布,几乎和以前一样。最后我可以继续我的项目了。谢谢你的代码!这看起来很有趣,但有点难以立即理解。
addSprite(new Circle(new Paint(),20f));