2012-10-22 178 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);就像你在代码中做的那样。 这可能并最终会使游戏闪烁。

问候, 我