Archive

Archive for the ‘HowTo’ Category

Fast Game Mathematics

April 2nd, 2011 7 comments

As for myself, I never had anything to do with game programming. I’m a normal J2EE Developer / Architect in my “real” life, working for a big IT-Company here in Germany. If you are entering game programming you have to learn to throw some common java habits overboard. Besides the “Aiming for Performance” Arcticle ” down below, there are some more technical issues that can speed up your game. A good starting point is a wiki article about fast square roots (Link). The thing with the square roots is especially interesting if you are going 3D.

Another aspect is the Math factor.

int result = inputInt / 2;
int result2 = inputInt >> 1;

If you have some division by the power of 2, then you can simple shift the bits. In my TestCase this is like 8x faster than the standard division. Another useful approach are Data Tables, when you don’t need exact values. If you are calculating angles with Math.tan() or something similar, you might want to consider to pre calculate the angles your need for your game. In my case the rotation of arrows in 10 degree steps. So the only thing you have to to is to divide the cathetus and search for a Number in the table. In my case 5x times faster that Java Math.

Persisting Game Data / A Game State

September 12th, 2010 No comments

I was thinking about some possibilities storing a more or less “big” GameState. As you may know the InstanceState is transient. If you google the topic you will find the Android Developer Documents about “Saving Persistent State“.

In my opinion the SharedPreferences are “ok” for simple data like Music on / off, or some yes / no / age / gender stuff. But when it comes to more complex data structures you will run into problems.

So let’s see what else we got. There is another solution called Parcelable This works with objects too, but it’s a pain in the *** to implement it for every Object you have in your Pocket.

Another possibility would be to store your data in a SQLite Database. But when you only want to store “one big” Object with lots of sub objects it’s a not to underestimate effort to implement everything you need to get tings stored at the right place.

I came to the conclusion to “keep it simple stupid”. I have a large “GameData” Object with a lot of Object Lists and primitive values and so on ….so i wrote a Singleton Save Service that read/write the Object to a File on the device. Nothing to be proud of, but sometimes in the Android World you loose the sense for the simple Java Stuff that just – works !

package com.androidfactory.service;

public class SaveService {

	private static final String SAVE_FILENAME = "TheSaveFile.ser";

	private GameData saveData;

	private static SaveService saveService;
	private Activity context;

	private FileOutputStream fOut = null;
	private ObjectOutputStream  osw = null;
	
	private FileInputStream fin = null;
	private ObjectInputStream sin = null;

	public SaveService(Context context){
		this.context = (Activity)context;
	}

	public static SaveService getInstance(Context context){
		if(saveService == null){
			saveService = new SaveService(context);

		}
		return saveService;
	}

	public  void save(GameData object){
		try {
			fOut = context.openFileOutput(SAVE_FILENAME, Activity.MODE_PRIVATE);
			osw = new ObjectOutputStream(fOut);
			osw.writeObject(object);
			osw.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public GameData readLastState(){
			try {
				fin = context.openFileInput(SAVE_FILENAME);
				sin = new ObjectInputStream(fin);
				saveData = (GameData) sin.readObject();
				sin.close();
			} catch (StreamCorruptedException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}

			return saveData;
	}
}

Bitmap processing in Android

September 8th, 2010 No comments

I recently got somehow curious about some Sample Code I found in the web. The Problem is Simple. Let’s say we have a GameThread that want’s to draw a background image that fits the complete Screen. Before you draw the Bitmap to the Canvas you normally want to import the picture like this (maybe):

Bitmap mBackgroundImage = BitmapFactory.decodeResource(res, R.drawable.hase);
// this is curious
Log.i("DEBUG", "Imported Image width = " +
mBackgroundImage.getWidth() + " Heigth ="+
mBackgroundImage.getHeight());
// maybe expensive
mBackgroundImage = Bitmap.createScaledBitmap(mBackgroundImage, 480, 800, true);

The open Question: Why scaling the picture if the source-image is already in 480×800 ? The picture will suffer from scaling besides the expensive scaling process. In this scenario the we have a fixed TargetDisplay-Size of 480×800. The Picture we are importing is already 480×800 Pixel. So far so good, but the LOG output says:

09-08 10:10:16.859: INFO/DEBUG(19137): Imported Image width = 720 Heigth =1200

Strange ? ! This comes from the default density settings which seem to be kind of unreliable. In my case it’s 240dpi but the BitmapFactory works with 160 dpi. If you want to skip the re-scaling part and want to import a Bitmap the “short” way you can do that with Options.

The first thing you should do is get the density of your Display:

final DisplayMetrics metrics = context.getResources().getDisplayMetrics();

Now we can wire some options for the decoding:

Options myOptions = new Options();
		myOptions .inScaled = false;
		myOptions .inScreenDensity = metrics.densityDpi;
		myOptions .inTargetDensity = metrics.densityDpi;

So now we are ready to load the Bitmap in the right scale & size:

Bitmap newPic =	BitmapFactory.decodeResource(_resources, R.drawable.hase, myOptions )