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