There’s music in the air

March 5th, 2011 2 comments

After i recently bought a new version of Sony Vegas Movie Studio and ACID Music Studio, i accidentally created 2 Songs that at not that bad from my optinion.

Let me know what you think =)

Tags: , ,

Performance in 2D Canvas App / Game on Android

December 4th, 2010 3 comments

While I was reviewing a lot of game-code and examples, I learned a lot by mistake. Before you are running in similar problems i have summed up some information that might be interesting.

Common Advices:

  • Strings are bad. Because as you might know Strings are immutable. So if you have Methods like setText(“foo”) in combination with a frame-drawing Method you might ask yourself why the Garbage Collector is Running all the Time and Cleaning up thousands of Objects.
  • String-Objects are not the only Objects that accidentally allocated at run-time. You should aim for a Zero-Garbage-Collection Approach. I know that you might have to break some rules that may be strange, but if you are aiming for a animated Game on a Canvas Surface, you won’t be happy with the GC running while animations taking place.
  • Stop Allocating stuff. ArrayLists, Hashmaps, are Bad. Enumerations are bad, Collections in general are bad. Mostly because they are implicitly allocation memory by making shadow copies of themselves, or other strange stuff you don’t want happening at run-time.
  • You will read a lot about multi-threading Games. This might be true for OpenGL Games, because while the GPU is flushing the graphics to the surface you can calculate your Game Objects in parallel. For a 2D Canvas Game this is not mandatory because Canvas is a CPU based drawing and you won’t see any significant benefit by Multi-threading.
  • Furthermore you can tune the Bitmaps you are Loading. In general you have to preload all your Bitmaps up in front. By default this is done in the ARGB-8888 Color Mode (32 bit). If you need a Alpha Channel you might be faster if you load the Bitmaps in 16 bit with Alpha (ARGB-4444), or the fastest way in RGB 565 (without Alpha). Your can do that with Options like this.
    private static BitmapFactory.Options sBitmapOptions    = new BitmapFactory.Options();
    sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
  • Sounds: Preload everything and use the OGG Format with lowest possible settings. If you are having Files > 100kb you will run into OutOfHeadMemory Exceptions.
  • Math: If you are using Math.random() or Math.sqrt() frequently you should consider some other ways to calculate those equations. There are some other Implementations that are much faster than the standard Math tools provided by Java. (e.g google for “Fast Square Root Java”)
  • Because of the Garbage Collector you should re-implement your own Fixed-Sized-Array to avoid Collection Lists.
  • Generic Iterating is bad. Like the fancy for(int Moo: mooList) looks sexy, it creates a Iterator at Runtime that leads to : *tusch* Garbage Collection.
  • You should 100% be sure that you never ever create a Object at Runtime. This can be tricky . In my Case i want to serialize some of my Game Data and realized that Matrix() is not Serializable. Solution : Pass a static Matrix to the Method.
  • Method calls are more expensive than simply referencing the public value.
  • Method calls that Return Values should be avoided. Better provide the Method with a Reference that you want to work on. So Instead of
    public ReturnObject solveThis(123, 32);
    // better
    public void solveThis(123, 32, myObjectRef);
  • Ask yourself honestly how often you need to “update” something. Like a Score. You don’t have to update the Score 40 times / Second.
  • Filter Touch Events. If you have a Application that has to react to a push , maybe consider only to catch the UP Event. Flooding a Surface View Thread with hundreds of touch Events is not a good Idea. If you have to trace every move, you can Thread.sleep(xy) the Touch Method to prevent Flooding of Values.
  • It’s always hard to cover all possible Devices / Display Resolutions. In a Game you have to preload stuff, so you should initialize a Display Strategy first. Then load the appropriate images.

If you need more informations on certain points, or you have some good other ideads let me know.

Greets

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

Path finding / Routing in Games

September 8th, 2010 No comments

On of the more complex Topics in Game-Development is the Path finding Problem. The task is simple : “Go from Point A to Point B on the shortest Distance”. Mostly seen in some Tower Defense games. The easiest way to solve this is to give your moving objects a pre-defined path. You’ll see that in a lot of Tower Defense Games because it’s plain simple.

Some of the other Tower Defense Games are keeping the Path finding simple by only moving in 4 Directions, so always move in a right angle. This makes the math behind the calculations a Lot easier. But this looks a little bit stupid to me when NPCs running against a wall, and then moving left or right. So by searching for some algorithm that performs well an consider at least 8 directions, if found nothing handy in the web.


The Solution was to make my own Route-Algorithm which looks pretty clean at the Moment and performs pretty good. I wrote some tests that print a result route in a HTML File:

The image shows the route path in green, the blocked Parts in red. The start point is on the top , the end point at the bottom. How dows the algorithm work ? In short words: I pre calculate the complete Gamefield, every Field has a “weight”. So if your Objects starts moving it always knows the next step from the current field by looking at all neighbor fields. So the routing is fixed as long as no more “blocks” are occurring, so you only have to calculate one time and work with that result till something changes.

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 )

Let the music play…

September 3rd, 2010 1 comment

While a game consists usually of more pieces than simple code, from my point of view music and sound effects are a big part of the fun.  By testing a lot of “successful” games, i noticed that the have mostly pretty poor sound effects or music.

The reason for this could be the more or less poor implementation of MediaPlayer Capabilities in Games. As Developer you will struggle in playing multiple sounds at once, or loops that run smooth. There are several things that currently look more like a “workaround” implementation-wise, like the SoundPool.

Whatever…here are some samples of background loops it created recently, enjoy:

Loop Choir
Loop Piano
Loop E-Bass

Tags: , , ,

Hello world!

September 2nd, 2010 No comments

Every Developer knows those words “Hello World”. For me it’s kind of a nostalgic memory of my first JAVA App back in the University. So, for default reasons, i leave the first Topic of WordPress untouched. !

😉