2013-11-25 53 views
6

一些背景:的Android - 帆布的onDraw與縮放卡馬拉以下人物動作

我創建一個Android遊戲繪製一個迷宮到對背景圖像的畫布,這裏採用方形塊,因此迷宮總是automtically放大到5 x 5平方米的迷宮,可能是20 x 20.通過簡單地運行一組for循環繪製迷宮,然後在相關位置繪製線條。這一切都工作完美,但我有一個問題,讓我的onDraw工作順利。這是因爲每當我無效時,我必須重新運行for外觀並運行各種if語句來檢查位置(不幸的是,這個過程無法改進)。

問題:

我期待重新寫我的迷宮繪製在畫布上的方式,下面是我需要實現3個主要特點:

1 - 畫整個迷宮到畫布(這很容易) 2 - 放大迷宮,僅顯示5 x 5 3 - 移動角色(始終居中在屏幕上)並繪製迷宮的下一個部分

現在如上所述繪製整個迷宮很容易,並會使onDraw顯着更快因爲它們不需要在invaldate上運行for循環,所以在第一次加載關卡時可以執行一次。

關於第2點& 3,我看到這個工作的方式是在畫布的中間畫一個角色,然後用一個2d birdseye視角攝像頭連接/連接角色動作。這臺相機還需要放大到只顯示整個迷宮網格的5 x 5的程度。然後當charcater移動時,相機隨着角色移動並顯示已經繪製的迷宮的下一部分。我已經嘗試了一些事情,並做了一些研究,但是我從來沒有使用過畫布,也不知道從哪裏開始,甚至有可能。

所以總結一下,問題的主要部分是他們是否將birdseye視角相機連接到放大並隨角色圖像移動的角色。

下面是目前如何繪製迷宮的代碼片段,它使用2組for循環檢查2組布爾數組[] [],它們只存儲要繪製的垂直線和horixaonl線。

@Override 
protected void onDraw(Canvas canvas) 
{ 
    canvas.drawRect(0, 0, width, 100, background); 
    RectBackground.set(0,0, FullScreenWidth, FullScreenWidth); 
    canvas.drawBitmap(gameBackground, null, RectBackground, null); 

    for(int i = 0; i < 5; i++) 
    { 
     for(int j = 0; j < 5; j++) 
     { 
      float x = j * totalCellWidth; 
      float y = i * totalCellHeight; 

      indexY = i + currentY; 
      indexX = j + currentX; 

      // Draw Verticle line (y axis) 
      if (indexY < vLength && indexX < vLines[indexY].length && vLines[indexY][indexX]) 
      { 
       RectOuterBackground.set((int)x + (int)cellWidth, (int)y, (int)x + (int)cellWidth + 15, (int)y + (int)cellHeight + 15); 
       canvas.drawBitmap(walls, null, RectOuterBackground, null); 
      } 
      // Draws Horizontal lines (x axis) 
      if (indexY < hLength && indexX < hLines[indexY].length && hLines[indexY][indexX]) 
      { 
       RectOuterBackground.set((int)x, (int)y + (int)cellHeight,(int)x + (int)cellWidth + 15,(int)y + (int)cellHeight + 15); 
       canvas.drawBitmap(walls, null, RectOuterBackground, null); 
      } 
     } 
    } 
} 

回答

1

爲了更快地繪製圖形,您可以通過直接繪製到位圖並將位圖像閃爍到畫布中來雙重緩衝畫布。速度非常快。

private void init() 
{ 
     //variables below are class-wide variables 
     b = Bitmap.createBitmap(cwidth, cheight, Bitmap.Config.ARGB_8888); 
     bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     bitmapPaint.setStyle(Paint.Style.STROKE); 

     bitmapPaint.setStrokeWidth(3); 
     myPaint.setColor(0xff000000); 
     myCanvas = new Canvas(b); 
} 

protected void onDraw(Canvas c) 
{ 
    super.onDraw(c); 
    c.drawBitmap(b, 0, 0, myPaint); 

    for(int i = 0; i < number lines; i++) 
    { 
     //draw here using myPath 
    } 

    if(b != null) 
     c.drawBitmap(b, 0, 0, myPaint); 

    myCanvas.drawPath(myPath, bitmapPaint); 

} 

然後,「移動」我會建議使用裁剪框。這意味着1:1比例,圖像大於屏幕上顯示的視口。當某人「移動」時,真正發生的情況是位圖在剪裁框下面移動。

你可以使用BitmapRegionDecoder並只顯示該區域中的字符是(這可能是slowish)或使用

public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint) 

這裏的src參數允許您指定顯示的位圖的一個小區域。它實際上是一個裁剪盒。

+0

我還要補充一點,該方法的onDraw可悲的是不完整的。如果你需要看到整個事情的工作,我可以給你一些代碼。我寫了一個應用程序,它和你在迷宮中做的事情類似。它繪製筆記本線條並從手寫筆捕獲手寫。 – mttdbrd

+0

明天我會看看這個,請給我發電子郵件給我你的完整代碼,這樣我就可以看到一個工作版本。謝謝。 –

+0

我不知道如何通過SO發送電子郵件。如何做到這一點? – mttdbrd

1

要放大和縮小,你需要通過一個數字(縮放係數)乘以座標

int x1 = (int)x + (int)cellWidth; 
int y1 = (int)y; 
int x2 = (int)x + (int)cellWidth + 15; 
int y2 = (int)y + (int)cellHeight + 15; 

RectOuterBackground.set(x1*zoom, y1*zoom, x2*zoom, y2*zoom); 

注意,縮放必須是一個浮點數,使用變焦= 2,使得一切的兩倍大。

如果你想要把相機放在池的頂部(XC,YC)你需要這樣做:

RectOuterBackground.set((x1-xc)*zoom, (y1-yc)*zoom, (x2-xc)*zoom, (y2-yc)*zoom); 

嘗試先繪製整個迷宮,很快你就會找出如何只畫這僅僅是屏幕

我希望這有助於內部迷宮的一下,讓我知道,如果您有任何疑問:)

+0

我會在今晚的某個階段看看這個,並讓你知道我如何繼續。 –

+0

有沒有可能爲我提供更完整的代碼片段,因爲不能100%確定如何實現它。例如,這個int不是有意的;最後。到目前爲止,我已經畫出了完整的迷宮10 x 10,現在我需要用相機實現變焦,使其平穩移動(逐漸顯示迷宮的下一部分)。謝謝 –

+0

你可以寄給我你到目前爲止?我會爲你實現這一點 – aguaviva