2013-08-24 92 views
4

我在拼貼Bitmap時遇到問題。我想要Bitmap繪製到2D Array中定義的座標。在SurfaceView Canvas上拼貼位圖

我想能夠讓我們說「草」到某些座標,「水等等」到其他座標。

我花了好幾天的時間試圖弄清楚這一點,並非常感謝任何見解。我只能得到Canvas繪製1「草」Bitmap,所以我覺得我的循環中有一個錯誤。我看過herehere,其中包括許多其他,並不希望每瓦都是相同的。這裏是我的代碼:

MapLoader.java

public class MapLoader extends SurfaceView implements SurfaceHolder.Callback, 
    Runnable { 

SurfaceHolder holder; 
Thread thread; 

Bitmap grass = BitmapFactory.decodeResource(getResources(), 
     R.drawable.grass); 
boolean running = false; 

int[][] grassCoords = new int[][] { { 0, 16, 32, 48, 64 }, 
     { 0, 16, 32, 48, 64 }, { 0, 16, 32, 48, 64 }, 
     { 0, 16, 32, 48, 64 }, { 0, 16, 32, 48, 64 } }; 

public MapLoader(Context context) { 
    super(context); 

    holder = getHolder(); 
    holder.addCallback(this); 
} 

public MapLoader(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    holder = getHolder(); 
    holder.addCallback(this); 
} 

public MapLoader(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 

    holder = getHolder(); 
    holder.addCallback(this); 
} 

public void pause() { 
    running = false; 

    while (running) { 
     try { 
      thread.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     break; 
    } 
    thread = null; 
} 

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

} 

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

    running = true; 
    thread = new Thread(this); 
    thread.start(); 

} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    Canvas c = holder.lockCanvas(); 
    draw(c); 
    holder.unlockCanvasAndPost(c); 

} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 

} 

@Override 
public void run() { 

    while (running == true) { 

     // performs drawing to the canvas 
     if (!holder.getSurface().isValid()) { 

      continue; 
     } 

     Canvas c = holder.lockCanvas(); 

     int x = 0; 
     int y = 0; 

     for (x = 0; x < grassCoords.length; x += grass.getWidth()) { 

      for (y = 0; y < grassCoords.length; y += grass.getHeight()) { 

       c.drawBitmap(grass, x, y, null); 
      } 

     } 

     holder.unlockCanvasAndPost(c); 

    } 

} 

} 

ActivityClass.java

public class Test extends Activity { 

MapLoader mapLoader; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    mapLoader = new MapLoader(this); 
    setContentView(mapLoader); 

} 
} 

任何幫助或建議(甚至一個鏈接到一個有效的方法),將不勝感激!

感謝,

馬特

回答

3

這是不容易明白你正在嘗試做的...

你怎麼座標編碼成grassCoords陣列?由於其目前的形式,它有5x5元素。

int[][] grassCoords = new int[][] { { 0, 16, 32, 48, 64 }, 
     { 0, 16, 32, 48, 64 }, { 0, 16, 32, 48, 64 }, 
     { 0, 16, 32, 48, 64 }, { 0, 16, 32, 48, 64 } }; 

因爲它有它的名字grass我假設你只想繪製草,那麼你可以把它定義這樣

int[][] grassCoords = new int[][] { {0, 0}, {16, 16}, {32, 32} }; 

像上面這樣{0, 0}每個元素將是一個單一的座標草瓦。

第二個問題是你的循環,除了數組長度以外,你不會讀取任何來自grassCoords的數據,當你增加索引時,你會用grass.getWidth()增加索引,這並不合理。

int x = 0; 
    int y = 0; 

    for (x = 0; x < grassCoords.length; x += grass.getWidth()) { 

     for (y = 0; y < grassCoords.length; y += grass.getHeight()) { 

      c.drawBitmap(grass, x, y, null); 
     } 

    } 

您應該正確地迭代數組並從中獲取數據。

int x = 0; 
    for (x = 0; x < grassCoords.length; x++) { 
     c.drawBitmap(grass, grassCoords[x][0], grassCoords[x][1], null); 
    } 

如果我是你,我會至少研究Java tutorial的相關部分。

+0

謝謝你的鏈接和解釋。起初我無法理解一個二維數組。兩個答案都非常有幫助,並教會了我很多。謝謝你和@Geobits! – MattMatt

1
for (x = 0; x < grassCoords.length; x += grass.getWidth()) { 
    for (y = 0; y < grassCoords.length; y += grass.getHeight()) { 
     c.drawBitmap(grass, x, y, null); 
    } 
} 

它只能畫一次的原因就在這裏。 grassCoords.length5。在第一次繪製之後將草的寬度添加到x時,它將超過5,循環結束。你需要爲這兩者分別使用一個變量。相同的y。正如auselen指出的那樣,還有其他一些問題,但這是它一開始就只畫一次的原因。

但是,如果要用一個位圖無縫地平鋪矩形,則可以完全消除座標數組。你甚至不需要知道它有多少瓦寬/高。

for(int x = startX; x < endX; x += grass.getWidth()){ 
    for(int y = startY; y < endY; y += grass.getHeight()){ 
     c.drawBitmap(grass, x, y, null); 
    } 
} 

記住,如果你:如果你使用下面的其他瓷磚草基層,如果你是平鋪的圖案爲背景圖像等。你可以是這樣做的,這是特別有用只是想要定期填寫拼貼,不需要定義座標。它們都是倍數,所以定義一個座標數組沒有多大意義。只要將每個瓦片點視爲網格點並乘以瓦片的高度/寬度即可。