2012-10-22 200 views
0

我一直在對遊戲沒有位圖或任何東西,我使用矩形作爲對象,並改變它們的顏色,他們的目的就像一個紅色矩形的播放機和牆壁灰色矩形。我的問題是用位圖/圖像替換矩形的正確方法是什麼?如何爲Android遊戲加載位圖?

我知道加載位圖,你可以只是這樣做:

Bitmap randomBitmap = BitmapFactory.decodeResource(getResources(), 
com.example.android4gametest.R.drawable.ic_launcher); 

我應該載入我所有的位圖,並把它們傳遞給他們班或者我應該加載其類中的位圖,而不是通過它的?我怎麼做,因爲我不能使用BitmapFactory,因爲我沒有訪問getResources()!或者我應該加載我的資產文件夾我的位圖/圖像,我知道我不會有相同的「工具」,你可以說混亂的位圖。

MainActivity

public class MainActivity extends Activity { 
Game theGame; 
@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 Game(this)); 
} 
} 

遊戲盤 公共類遊戲延伸SurfaceView實現SurfaceHolder.Callback {

GameThread _thread; 

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

    getHolder().addCallback(this); 

    setFocusable(true); 

    _thread = new GameThread(getHolder(), this); 


} 

public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) { 
    // TODO Auto-generated method stub 

} 

public void surfaceCreated(SurfaceHolder holder) { 
    _thread.setRunning(true); 
    _thread.start(); 

} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    // TODO Auto-generated method stub 

} 

@Override 
protected void onDraw(Canvas canvas) { 
    Log.d("OnDraw", "it is Drawing"); 
    canvas.drawColor(Color.BLUE); 
} 

public void update() { 
    // TODO Auto-generated method stub 
} 
} 

GameLoop這裏沒有什麼

public class GameThread extends Thread{ 
/*FPS Code*/ 
private final static int MAX_FPS = 30; 
private static final int FRAME_PERIOD = 1000/MAX_FPS; 




protected SurfaceHolder holder; 
protected Game game; 
private boolean isRunning = false; 

public GameThread(SurfaceHolder _holder, Game _game) { 
    this.holder = _holder; 
    this.game = _game; 
} 



/** 
* Returns True if the game is still running and False if the game is over 
* @return 
*/ 
public boolean isRunning() { 
    return isRunning; 
} 
/** 
* Set to true for the game loop to start 
* @param isRunning 
*/ 
public void setRunning(boolean isRunning) { 
    this.isRunning = isRunning; 
} 


@Override 
public void run() { 
    Canvas c; 
    Log.d("Pallyways", "Starting game Loop"); 

    long beingTime; 
    long timeDiff; 
    int sleepTime; 
    int framesSkipped; 

    sleepTime = 0; 

    while(isRunning){ 
     c = null; 
     try{ 

      c = holder.lockCanvas(); 
      synchronized(holder){ 
       beingTime = System.currentTimeMillis(); 
       framesSkipped = 0; 
       game.update();//Update 
       game.onDraw(c);//Redraw 

       timeDiff = System.currentTimeMillis() - beingTime ; 
       sleepTime = (int) (FRAME_PERIOD - timeDiff); 

       if(sleepTime>0){ 
        try{ 
         Thread.sleep(sleepTime);} 
        catch (InterruptedException e) { 
         e.printStackTrace();} 
        finally{} 
       } 

       while(sleepTime<0 && framesSkipped < 5){ 
        game.update(); 

        sleepTime+= FRAME_PERIOD; 
        framesSkipped++; 
       } 

      } 
     }finally{if(c!=null){ 
      holder.unlockCanvasAndPost(c); 
     } 
     } 
    } 
} 

} 

英雄級我還沒有開始,但我想知道如何加載位圖在一個不同的包上

package com.example.android4gametest.Actors; 

import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 

import com.example.android4gametest.R; 

public class Hero { 
//getContext() gives me an error and that is because it does not have a reference 

private Bitmap hero = BitmapFactory.decodeResource(getContext().getResources(), 
R.drawable.ic_launcher); 
public Hero(){ 

}} 

回答

0

你在哪裏加載並不重要。我認爲你的主要問題是訪問資源。在視圖中,您可以撥打:

getContext().getResources() 

編輯:

所以在英雄的構造函數的方法簽名添加上下文作爲參數:

public Hero(Context context){ 
    private Bitmap hero = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher); 
} 
+0

我將不得不使用位圖傳遞到上下文我的課,以加載它?所以我們可以說我的類英雄構造函數會像'英雄(上下文)' –

+0

啊哈我不好,認爲你的類擴展視圖。是的,那也行得通。只是不要保留對Context的全局引用或將它保留在WeakReference中 – Ljdawson

+0

我將用我的4個類更新我的問題 –

1

根據尺寸/數量的位圖,將它們加載到Game類的構造函數中可能沒問題。但請注意,如果您一次加載太多/太大的位圖到內存中,您可能會遇到一些OOM錯誤或第一次繪製調用時出現延遲。你必須確定你是無效的,當你不再需要它們時有效地回收你的位圖。掙扎着這個問題,我的第一場比賽

+0

啊我會做一些關於回收位圖的研究!現在我的在線遊戲需要4個位圖英雄,牆壁,目標和玩家可以移動的對象 –

1

不要加載在你的遊戲對象的構造函數的Bitmap。如果其中任何Bitmaps會由多個對象(即敵人類)一起使用,那麼如果在你的對象的構造函數加載它們,你將不得不在內存中Bitmap的多個副本。這可能會導致OutOfMemoryException。相反,加載Bitmap你的構造以外(在你的遊戲主題或遊戲面板),然後通過Bitmap對象的構造函數或setter和設置您的私人Bitmaps的方式。你只需要在內存中保留有限數量的Bitmaps

您也可以考慮當你加載這些Bitmaps,顯示進度條或微調加載「屏幕」。

+0

我更新的英雄類將'Context'作爲參數,然後在Hero構造函數中將位圖英雄類'公共英雄(上下文){位圖= BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_launcher}'是不是這樣做的正確方法?你能提供我和例子以更好地理解 –

+0

這就是對於像你的Hero類這樣的對象來說沒關係,但是如果你有可能重複的敵人或者通電,那麼你會想在管理類或者線程類的資源上調用decodeResource方法一次,然後像下面這樣在構造函數中傳遞它: Powerup(位圖健康)。很抱歉,如果這沒有幫助。 – Flynn81

0

不要!使用動態對象..我的意思是根本不要在遊戲中創建動態對象,這會觸發GC,並在任何需要的時候都會造成一切結果。你必須自己控制一切,並在障礙物和敵人身上使用靜態/最終「物體」和陣列。這些對象將在啓動時加載到堆上,這意味着您將在加載應用程序之前加載它們。因此,您必須在這些靜態對象中找到平衡點,但在找到它時很容易。

位圖應該加載到這些靜態非動態對象之外,對象只應該進行計算。

並且不要在你的 之間使用任何不一致的計算,循環或Thread.sleep c = holder.lockCanvas();和holder.unlockCanvasAndPost(c);就像你在代碼中做的那樣。 這可能並最終會使遊戲閃爍。

問候, 我