Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何为android游戏加载位图?_Java_Android - Fatal编程技术网

Java 如何为android游戏加载位图?

Java 如何为android游戏加载位图?,java,android,Java,Android,我一直在做一个没有位图或任何东西的游戏,我使用矩形作为对象,并改变它们的颜色,就像玩家使用红色矩形,墙壁使用灰色矩形。我的问题是,用位图/图像替换矩形的正确方法是什么 我知道要加载位图,您可以执行以下操作: Bitmap randomBitmap = BitmapFactory.decodeResource(getResources(), com.example.android4gametest.R.drawable.ic_launcher); 我应该加载所有位图并将其传递给他们的类,还是应该

我一直在做一个没有位图或任何东西的游戏,我使用矩形作为对象,并改变它们的颜色,就像玩家使用红色矩形,墙壁使用灰色矩形。我的问题是,用位图/图像替换矩形的正确方法是什么

我知道要加载位图,您可以执行以下操作:

Bitmap randomBitmap = BitmapFactory.decodeResource(getResources(),
com.example.android4gametest.R.drawable.ic_launcher);
我应该加载所有位图并将其传递给他们的类,还是应该在他们的类中加载位图而不是传递位图?由于无法访问getResources(),因此无法使用BitmapFactory,我将如何做到这一点!或者我应该从我的资产文件夹中加载位图/图像,因为我知道我不会使用与位图相同的“工具”

主要活动

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  
}
}
这里什么都没有

    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);
        }
        }
    }
}

}

加载位置并不重要。我认为您的主要问题是访问资源。在视图中,您可以调用:

getContext().getResources()
编辑:

因此,在Hero构造函数的方法签名中,添加上下文作为参数:

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

根据位图的大小/数量,可以将它们加载到游戏类的构造函数中。不过,请注意,如果一次将太多/太大的位图加载到内存中,则在第一次调用绘图时可能会遇到一些OOM错误或延迟。您必须确保将其置零,并在n您不再需要它们。在我的第一个游戏中遇到了这个问题,请不要在游戏对象的构造函数中加载
位图。如果这些
位图中的任何一个
将被多个对象使用(即一个敌方类),则如果将它们加载到对象的构造函数中,则内存中会有多个
位图
副本。这可能会导致
OutOfMemoryException
。相反,将
位图
加载到构造函数之外(在游戏线程或游戏面板中)然后将
位图
对象传递给构造函数或setter,并以这种方式设置私有
位图
。您只需在内存中保留有限数量的
位图


您可能还想考虑加载“屏幕”。当你加载那些

位图时,它会显示一个进度条或微调器。不要使用动态对象。我的意思是根本不要在游戏中创建动态对象,它们会触发GC,并在它想运行的时候使一切都停顿。你必须自己控制一切,使用静态/最终的“对象”以及障碍物和敌人上的阵列。对象将在启动时加载到堆中,这意味着您将在应用程序关闭之前加载它们。因此,您必须在这些静态对象中包含的内容和不包含的内容之间找到平衡,但找到它们后很容易

位图应加载在这些静态非动态对象之外,对象应仅执行计算

不要使用任何不必要的计算、循环或线程 c=holder.lockCanvas();和holder.unlockCanvasAndPost(c);就像您在代码中所做的那样。 这可以并且最终会使游戏闪烁

问候,,
Me

我是否必须将上下文传递给我的类,以便使用位图加载它?因此,让我们假设我的类hero构造函数类似于
hero(上下文)
Aha我不好,我想你的类扩展视图。是的,那也行。只是不要保留对上下文的全局引用或将其保存在weakreference中。我知道这样可以工作,但这是正确的方法吗?作为一种有效的方法吗?我看不出为什么不这样做的原因。只要记住在使用位图时循环使用它们/旋转等等h我将做一些关于回收位图的研究!目前我的在线游戏不需要4个位图英雄、墙、目标和可以被玩家移动的对象。我更新的英雄类将
Context
作为一个参数,然后在英雄构造函数中将位图作为英雄类
public hero(Context){bitmap=BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_launcher}
这不是正确的方法吗?请提供我和示例,以便更好地理解这对于像Hero类这样的对象来说是可以的,但是如果您有可能重复的敌人或通电,那么您希望在管理类或线程类中的资源上调用decodeResource方法一次,并以这样的方式传递它构造函数:通电(位图运行状况)。如果这没有帮助,请道歉。
public Hero(Context context){
  private Bitmap hero = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
}