2012-10-22 4 views
0

Я работал над игрой без растровых изображений или чего-то еще, я использую прямоугольники в качестве объектов и меняю их цвет для своей цели, как красные прямоугольники для игрока и серые прямоугольники для стен. Мой вопрос в том, что это правильный способ заменить прямоугольники растровыми изображениями/изображениями?Как загрузить растровое изображение для Android-игры?

Я знаю, чтобы загрузить Bitmaps вы можете просто сделать это:

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

Должен ли я загрузить все мои Bitmaps и передать их в классы, или я должен загрузить растровое изображение внутри своего класса, а не передать его? и как бы я это сделал, потому что я не могу использовать 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)); 
} 
} 

Игра Панель общественного класса Game продляет 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); 
     } 
     } 
    } 
} 

} 

Hero Class я не начал, но я хотел бы знать, как загрузить растровое изображение на классе, который находится на другом пакете

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() 

Edit:

Таким образом, в методе подписи конструктора Героя добавить контекст в качестве параметра:

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

бы я должен перейти к контексту в мой класс, чтобы загрузить его с помощью растрового изображения? так что скажем, что мой конструктор героя класса будет чем-то вроде «Герой (Контекст)» –

+0

Ага, мой плохой, подумал, что ваш класс расширен. Да, это тоже сработает. Просто не держите глобальную ссылку на Контекст или не храните его в WeakReference. – Ljdawson

+0

. Я обновлю свой вопрос с помощью моих 4 классов. –

1

В зависимости от размеров/номер растровых изображений, может быть хорошо загрузить их в конструкторе вашего класса Game. Имейте в виду, что если вы загружаете слишком много/слишком больших растровых изображений в память сразу, вы можете столкнуться с некоторыми ошибками OOM или задержкой, когда ваш первый призыв к розыгрышу будет сделан. Вы должны быть уверены, что обнуляете, перерабатываете свои растровые изображения эффективно, когда они вам больше не нужны. Борясь с этим вопросом с моей первой игрой

+0

ahh, я буду делать некоторые исследования об утилизации растровых изображений! и нет, как сейчас, для моей онлайн-игры требуется 4 растровых изображения героев, стен, цели и объекта, которые могут быть перемещены игроком –

1

Не загружайте Bitmap в конструкторы игрового объекта. Если какой-либо из этих Bitmaps будет использоваться несколькими объектами (т. Е. Классом противника), то, если вы загрузили их в конструкторы объекта, у вас будет несколько копий Bitmap в памяти. Это может привести к OutOfMemoryException. Вместо этого загрузите Bitmap за пределы ваших конструкторов (в игровой нити или игровой панели), а затем передайте Bitmap объектам конструкторам или сеттерам и установите свой собственный Bitmaps таким образом. Вам нужно сохранить только ограниченное количество Bitmaps.

Возможно, вы также захотите рассмотреть «экран» загрузки, на котором отображается индикатор выполнения или счетчик, когда вы загружаете эти Bitmaps.

+0

. Мой обновленный класс Героев принимает «Контекст» в качестве параметра, а затем в конструкторе Гера, который передает растровое изображение класс героя 'public Hero (context) {bitmap = BitmapFactory.decodeResource (context.getResources(), R.drawable.ic_launcher}' это не правильный способ сделать это? можете ли вы предоставить мне и пример для лучшего понимания? –

+0

Это хорошо для объекта, такого как ваш класс Hero, но если у вас есть враги или бонусы, которые могут быть повторены, вы бы хотели вызвать метод decodeResource один раз на своем ресурсе в классе управления или потоке управления и передать его так же в конструкторе: Powerup (Bitmap health). Извините, если это не помогает. – Flynn81

0

НЕ ДЕЛАЙТЕ! использовать динамические объекты. Я имею в виду, что вообще не создавайте динамические объекты в игре, они вызовут GC и сделают все заикание, когда оно будет работать, когда захочет.Вы должны сами контролировать себя и использовать статические/конечные «объекты» и массивы на препятствиях и врагах. Объекты будут загружены в кучу при запуске, а это значит, что вы загрузите их до закрытия приложения. Поэтому вы должны найти баланс между тем, что иметь в этих статических объектах, а не, но это легко, когда вы его нашли.

Растровые изображения должны быть загружены за пределы этих статических нединамических объектов, объекты должны выполнять только вычисления.

И никогда не используйте какие-либо необдуманные вычисления, петли или Thread.sleep между вашим c = holder.lockCanvas(); и holder.unlockCanvasAndPost (c); как вы делаете в своем коде. Это может и, наконец, сделать мерцание игры.

С уважением, Me

Смежные вопросы