0

I've been working on a simple tile-based terrain generation system for a game I'm trying to build, and have run into a bit of a snag. I'm trying to develop a new way to pick and store the bitmap I'll need for the individual tiles. I had a very simple method where the bitmaps were all loaded before I ran through the world drawing, and the bitmap was selected based on which type of tile it was.

Unfortunately, the selection process is probably going to get pretty complicated as I add variations on the tiles and world types. As such it seemed like a good idea to store that data within the tile object, as well as all the rules required to determine which tile it will be.

The problem that I'm running into is that this method is causing me to load a copy of the bitmap for each tile rather than just loading a pointer to the bitmap. This, in turn, is eating up my memory and causing my GC to go a little haywire.

What I'm looking for is a simple way to create static pointers to the different bitmaps that will be used, and then to reference those pointers in the Tile Object rather than load a new copy of the bitmap. The problem I've run into with that is that I can't load the bitmap without a reference to context, and I can't figure out how to reference the context in a static method.

Does anyone have any ideas on how to work around this?

Here's my tile class, and an example of a tile type class (they are all pretty much the same)

Tile: package com.psstudio.hub.gen;

import java.io.Serializable;

import android.graphics.Bitmap;

public class Tile implements Serializable
{
/****
 * Create a BitmaHolder class that uses a case for which field type it isn, and then 
 * loads all applicable bitmaps into objects.  The individuak tile types then reference
 * those objects and return bitmaps, which are ultimately stored in this super class.
 */
double elevation = 0.0;     //tile's elevation

int type = 0;       //tile's type
int health = 0;     //tile's health - used for harvestable tiles (trees, stone, mountain, etc.)
Bitmap bitmap;          //pointer to the bitmap

public void setTile(Bitmap _bitmap, double _elev, int _type){
    bitmap = _bitmap;
    elevation = _elev;
    type = _type;
}
public void setBreakableTile(Bitmap _bitmap, double _elev, int _type, int _health){
    bitmap = _bitmap;
    elevation = _elev;
    type = _type;
    health = _health;
}

}

Tile Type (Grass):

package com.psstudio.hub.gen.tiles;

import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.psstudio.hub.R;
import com.psstudio.hub.gen.Tile;

public class Grass extends Tile {
Bitmap holder;
BitmapFactory.Options bFOptions = new BitmapFactory.Options();  //used to prevent bitmap scaling

Random r = new Random();

public Grass(Context context, int mapType, Double elevation){
    super.setTile(pickBitmap(context, mapType), elevation, 4);
    pickBitmap(context, mapType);

}

public Bitmap pickBitmap(Context context, int mapType){
    bFOptions.inScaled = false;

    switch(mapType){        
    case 1:                 //Forest Type 1
        holder = BitmapFactory.decodeResource(context.getResources(), R.drawable.grass, bFOptions);
        break;
    }

    return holder;
}
}

The "holder = BitmapFactory" is what I think is causing my issue, since it's loading a new bitmap for every grass tile, rather than just pointing to a pre-loaded one.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Patrick Reynolds
  • 243
  • 1
  • 5
  • 18

1 Answers1

0

Alright, I managed to figure out a way to do what I needed. I don't know if it's the most proper way, but it works for what I need.

I create a BitmapLoader class that loads the images based on the world type, and then stores them to static bitmaps which are then referenced by the tiles.

Not the most elegant solution, but it gets the job done. ^^

Patrick Reynolds
  • 243
  • 1
  • 5
  • 18
  • Can I ask how exactly you reference these bitmaps from the loader class? I've already made a game without such a loader, but it tends to consume memory. I'm also working on another using a bitmap holder class, but I'm curious as to what you found to work best; a public static bitmap which you call every time (drawBitmap(loader.firstStaticBmp)) or do you create a bmp in your surfaceview (Bitmap bmp = loader.firstBmp) or do you use weak references? – MacD Aug 06 '14 at 21:08
  • @MacD The method I used probably isn't a good one, but what I did was create a class: BitmapLoader(), and added 'static BitmapLoader loader' to it. When I create a new instance of the BitmapLoader, I load the tiles for the given field, and then set 'loader=this', then from wherever I am in game I can do: 'bitmap = BitmapLoader.loader.loadedBitmap' where loadedBitmap is the public variable storing the bitmap I'm looking for. Like I said, not sure how good of an idea this is, but it worked for what I was trying. Hope it helps, sorry for taking so long, I just saw the notice about your post. – Patrick Reynolds Sep 05 '14 at 13:35