Wednesday, January 28, 2009

MonolithAndroid renamed to Robotic Space Rock

Today, I received an email from google asking me to rename the game I published for free in the android market. The game is called MonolithAndroid. Was called, actually, because from now on, it shall be called Robotic Space Rock! Yes, they informed me that I cannot use the word android, becase users may think that it is officialy endorsed from google, so I decided to drop the MonolithAndroid name alltogether and use the new improved and b-moviey name Robotic Space Rock.

Thursday, January 22, 2009

How to display a license agreement on your android application.

It is usually good practice to present the user with a license agreement the first time it uses an app. You can show the user a preferably short text with the license agreement. A license agreement gives you some legal protection if your application causes a problem to someone. You can use a checkbox to indicate that the user accepted the license agreement and proceed to the application.

We can use the shared preference mechanism to check if the user has agreed to the license agreement during the activity. If the user has previously agreed to the license then we proceed as normal. Otherwise, we show him the EULA. If the user checks the "I accept the license agreement" checkbox and presses OK, then we write to the preferences that the user accepted the license. If the user presses Cancel, we exit the app. You can see this in the following code excerpt

private android.widget.CheckBox checkboxAcceptLicense;
private android.widget.Button buttonOK;
private android.widget.Button buttonCancel;
private android.widget.TextView textviewLicense;
public SharedPreferences.Editor prefsEditor;
public SharedPreferences prefs;
public android.view.View licenseView;
private boolean soundInitialized;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
soundInitialized = false;
prefs = this.getPreferences(android.content.Context.MODE_PRIVATE);
prefsEditor = prefs.edit();
if(!prefs.getBoolean("LicenseAccepted", false))
{

//this.licenseView = this.findViewById(R.layout.licenseagreement);
this.licenseView = View.inflate(this, R.layout.licenseagreement, null);
this.setContentView(licenseView);
this.checkboxAcceptLicense = (android.widget.CheckBox)this.findViewById(R.id.checkLicenseAgreement);
this.textviewLicense = (android.widget.TextView)this.findViewById(R.id.textviewLicenseAgreement);
this.buttonOK= (android.widget.Button)this.findViewById(R.id.buttonOK);
this.buttonCancel = (android.widget.Button)this.findViewById(R.id.buttonCancel);
this.buttonCancel.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
exitNotAcceptedApplication();
}
}
);
this.buttonOK.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
if(checkboxAcceptLicense.isChecked())
{
prefsEditor.putBoolean("LicenseAccepted", true);
prefsEditor.commit();
licenseView.setVisibility(View.INVISIBLE);

initActivity();
}

}
}
);
}
else
{
initActivity();
}



}

the initActivity() method contains the actual code that you would normally execute on the onCreate() method of your Activity. The layout file for the license agreement is the following (licenseagreement.xml):

xml version="1.0" encoding="utf-8"?>

<LinearLayout

android:id="@+id/widget24"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#ffffffff"

android:padding="0px"

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

>


<TextView

android:id="@+id/textviewLicenseAgreement"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:padding="0px"

android:text="Monolith Android Licence Agreement. This software package is provided to you, the end user, by the sofware package creator, Tasos Kleisas, as is. The software package is provided free of charge by the developer. However, the means of delivering the software to your device, (mobile phone, computer or other) may induce a service fee. The developer cannot be held responsible for any damage or loss that you may suffer by the use or installation of this application package to your device. Use at your own risk. The code, sound effects, and music are copyrighted by Tasos Kleisas (C) 2007-2009."

android:textSize="14sp"

android:textColor="#000000"

android:typeface="normal"

android:textStyle="normal"

android:layout_weight="0"

android:layout_gravity="left"

>

TextView>


<CheckBox

android:id="@+id/checkLicenseAgreement"

android:layout_width="fill_parent"

android:layout_height="wrap_content"


android:text="I accept the license agreement"

android:textColor="#000000"

android:textSize="12sp"

android:typeface="normal"

android:textStyle="normal"

android:checked="false"



android:orientation="horizontal"

>

CheckBox>

<TableRow

android:id="@+id/widget32"

android:layout_width="fill_parent"


android:layout_height="wrap_content"

android:orientation="horizontal"

>

<Button

android:id="@+id/buttonOK"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:padding="10px"

android:text="OK"

android:textSize="14sp"

android:typeface="normal"

android:textStyle="normal"

android:layout_weight="0"

android:layout_gravity="left"

>

Button>

<Button

android:id="@+id/buttonCancel"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:padding="10px"

android:text="Cancel"

android:textSize="14sp"

android:typeface="normal"

android:textStyle="normal"

android:layout_weight="0"

android:layout_gravity="left"

>


Button>

TableRow>

LinearLayout>

Unfortunately, as you can see the server messed up the xml layout a bit. But you can find the full code at http://code.google.com/p/monolithandroid/source/browse/

Android 3D graphics and SurfaceView

If you want to use OpenGL/ES, you have to use a SurfaceView class. The problem is that there are various parameters for the SurfaceView class. This, for example may work fine in the emulator:

getHolder().setType(android.view.SurfaceHolder.SURFACE_TYPE_NORMAL);

on a real device, however, you may get a blank screen, or very slow redraws, so you should use this:

getHolder().setType(android.view.SurfaceHolder.
SURFACE_TYPE_GPU);

or even this:

getHolder().setType(android.view.SurfaceHolder.
SURFACE_TYPE_HARDWARE);

So i came up with this solution for the SurfaceView initialization:

public GameSurfaceView(Context context,GameOverlay overlay,Sound soundManager)
{
super(context);
this.soundManager = soundManager;
this.context = context;
this.overlay = overlay;
this.viewType = GLThread.VIEW_INTRO;
this.gameType = Game.GAME_MONOLITH;
getHolder().addCallback(this);
try
{
getHolder().setType(android.view.SurfaceHolder.
SURFACE_TYPE_GPU);
}
catch(Exception e)
{
try
{
getHolder().setType(android.view.SurfaceHolder.
SURFACE_TYPE_HARDWARE);
}
catch(Exception e2)
{
try
{
getHolder().setType(android.view.SurfaceHolder.SURFACE_TYPE_NORMAL);
}
catch(Exception e3)
{
}
}
}
}

So in the code above, we first try to get a hardware accelerated surface (fastest), if that fails a gpu memory surface(still fast) and if that fails a normal software surface.

Tuesday, January 20, 2009

MonolithAndroid 1.0.4 beta is out

It' s been almost two weeks since I released an updated version of MonolithAndroid. But now version 1.0.4 beta is out! I've corrected a few bugs and added some features but there are still some critters in there. So to sum up, here's a small changelog.

1. Switched from using media player for sound effects and music to a hybrid SoundPool / MediaPlayer implementation. Now the sounds are played using SoundPool and the music is played with MediaPlayer. Of course some problems remain. The most important problem is that the music cannot reliably be stopped.
2. Added a highscore table. Now you can find out who is the best player. The highscore table persists, so if you restart the game, your highscore is still there.
3. Added an options menu. Now you can select the type of game you want to play, the level and the difficulty. Two types of game are provided: Classic, which resembles a well known 6 letter game, and Monolith. Monolith introduces special white blocks. If you complete a line with a white block in it, the game grid evolves according to Conway's game of life. The difficulty setting enables you to choose between two settings. Normal is your meat and potatoes game. You can drag the touch screen to rotate the playfield. That may be useful practice for the expert difficulty mode. In Expert, the playfield rotates in various axes (depending on the level you currently play) so if you suffer from motion sickness do not play this mode! Ahhh, you have been warned! The level (1-10) determines the speed of the falling blocks as well as the rotation of the screen in expert mode. In the options screen you can enable/disable the music (not currently working) and the sound effects of the game. When you are happy with the game options go to OK, press right and then choose Play to start your game.
4. Changed the music format from mp3 to ogg because it reportedly causes less crashes on the MediaPlayer.
5. The program now exits if you press the back or the home button.

A bit of a warning... I do not currently own an android hardware device, because they are not available yet in Greece where I live. So if you happen to install the game on a real device I would like to hear your comments and bug reports. You can download a signed apk from http://code.google.com/p/monolithandroid/downloads/list. Choose the monolithandroid 1.0.4 beta apk. You can post your comments here, or you can use the issue tracker found on http://code.google.com/p/monolithandroid/issues/list
Here's a grainy video made from the emulator. You can almost hear me talking in the background...

Wednesday, January 7, 2009

Monolithandroid 1.0.3 beta release

The release frenzy continues with the release of monolithandroid 1.0.3 beta apk. This release corrects the texture loading problem of the previous 1.0.2 beta release. The problem manifested itself as holes in the textures used. Instead of using custom loading code, we use a function from the GLUtils class. So try it out!

Tuesday, January 6, 2009

monolithandroid 1.0.2 beta version update


A new apk is up for grabs. I am referring to the monolithandroid 1.0.2 beta which can be found at http://code.google.com/p/monolithandroid/downloads/list The new apk uses the
setType(SurfaceHolder.SURFACE_TYPE_GPU) parameter during the initialization of the display surface. Maybe the omission of this parameters caused the black screens on the G1 devices in the previous releases. However this change has caused the textures to appear incorrectly in the emulator.Note the picture on the left. The texture is full of black holes. I do not know if this occurs in an actual hardware device however... Can a guy with a real phone try it out and tell us the result?

Search the web