As you can see the code is pretty simple. You can find the code in javascript in this github repository: https://github.com/tkleisas/microbit_examples
Thursday, January 18, 2018
A messenger program for the micro:bit
As you can see the code is pretty simple. You can find the code in javascript in this github repository: https://github.com/tkleisas/microbit_examples
Wednesday, November 29, 2017
Monday, May 4, 2015
A groovebox using Arduino uno (part 2 of N). Choosing the appropriate libraries.
1. Sound generation. This is maybe the most important component. Arduino uses a microcontroller as its processor. It is an ATMEL atmega 328p with 32Kb of flash memory, 2Kb of ram and 1Kb of EEPROM. It doesn't have a pcm codec like a PC or even raspberry pi have. So in order to produce sound we need either some additional component like an i2c dac, or we can use a PWM output and then filter it to produce a signal that can be fed to headphones, an amplifier or recording equipment. The approach I chose is to use PWM because I did not have a dac, and from the research I did, I found that PWM output does sound OK, if properly filtered. The first candidate for sound generation was Mozzi, a fantastic library with excellent documentation. You should definately check it out: http://sensorium.github.io/Mozzi/
2. Library for the 128x64 OLED display: I searched for a driver/library to drive my OLED display. The display uses an SSD1306 chip. The particular display in my case was wired as SPI. You can find i2c or SPI/i2c versions in various places and with various prices. I bought 5 of those displays for under 20 euros in order to use them in various projects. The good thing about this display is that you can show a lot of information, With an 8x8 character matrix you can show 8 lines of 16 characters. That is a lot of information. The display is pretty crisp too! The only problem is that it is smallish, so if you are a bit older you may have trouble reading it. You can see details for the wiring in this Adafruit tutorial: https://learn.adafruit.com/monochrome-oled-breakouts
The library I initially used is this one: https://github.com/adafruit/Adafruit_SSD1306. This library supports both SPI and i2c and it uses the Adafruit GFX library (a separate download) for text and graphics rendering. Using the wiring documentation above and the library, I managed to connect the OLED display to arduino uno without any problems.
3. Library/code for rotary encoder support. Anyone interested in reading rotary encoders with arduino should definately check out this post by Oleg Mazurov: https://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino
At first it was not working, but the problem was not in the code but rather on my poor soldering skills. You see I made 2 small breakout boards in order to make the encoders breadboard friendly and I created some sort circuits. When I found the problem Oleg's code worked like a charm.
4. Library code for reading the buttons. No worries about this one! The support is built in arduino. Just configure the input pins with the INPUT_PULLUP parameter like this
pinMode(BUTTON_1,INPUT_PULLUP);
Well, not so fast my friends. Why? Well these parts work OK on their own but when you try to make them work together problems DO occur.
For example some libraries use particular pins that cannot be shared. Some others use a lot of precious ram starving the other libraries from it. So what seems a good start at first, may need some iterations before it works adequately as a system with the required functionality.
So in our next blog post, we will go through some of the iterations required to make those libraries work together and even replace them with others in order to achieve the necessary interoperability and performance.
Saturday, May 2, 2015
A groovebox using Arduino uno (part 1 of N)
it's been a while since I last wrote on this blog. The previous blog entry dates back to 2009. Wow, that was six years ago... In the meantime a lot of things happened. As a citizen of a crisis plagued Greece I witness a whole nation holding its breath hoping for some kind of salvation fearing that an economic apocalypse might happen. As I find breath holding a waste of time, I started a new project that marries two of my favorite interests: Electronics and music. I am an amateur electronic musician and over the years I managed to gather a few sound producing gadgets and software. However, as every synth freak knows, I feel the urge to add new weapons to my sonic arsenal. I already have 2 Virtual Analog Synths (M-Audio Venom, Novation Mininova), and a cheap analog synth (Korg Volca keys). I recently brought back from the attic a yamaha 4 track cassette recorder and the idea of creating songs only with physical hardware, without a DAW and a computer for some reason started to resonate. What I don't have is a drum machine/groovebox hardware that could be used as the rhythm section and the backbone of the songs I write. Of course you can find a lot of grooveboxes and hardware in the market right now. But instead of buying a groovebox or a drum machine, the idea of creating my own groovebox started to grow on me for many reasons. Reason number one is to create something unique sounding with an expressive and creative workflow. As I had one or two arduino unos lying around I thought that I could base my groovebox on arduino. So I started researching and trying to shape the groovebox design in my head. I had to balance the features I wanted with the physical limitations of the parts I had in my disposal for prototyping. After quite some thought I decided on a simple design with the following specifications.
1. Arduino uno based. That means that you can use a lot of existing libraries and resources and integrate rather than write code from scratch and there are a lot of documented ways to create a product out of your prototype.
2. OLED LCD display. I also considered 7 segment type displays or even a color coded led scheme for visual feedback regarding the groove machine. But since I wanted to be able to edit a lot of parameters, some sort of LCD display became mandatory.
3. Rotary encoders. I really like rotary encoders. I think that by using them, instead of potentiometers, is easier and really expressive.
4. 4 sounds at once, in order to be able to create interesting grooves and mini songs. Also some other buttons with shift and/or mode functions.
5. Low fi sound.
6. Low part count and cheap to make.
Little by little I started connecting the various components. Here is the prototype spaghetti of wires that I made.
Wednesday, November 18, 2009
Can N900 and Maemo save nokia?
1. Abandon Symbian series 60 models in favor of Maemo.
2. Keep its series 40 line for dirt cheap mobile phones.
3. Develop a series 60 emulator that can run series 60 apps on Maemo phones.
4. Radically improve Maemo development tools. Let me elaborate on this. Compared to android and iPhone developer tools, Symbian series 60 tools have been really difficult to use. An entirely different sdk should be downloaded in order to support specific features found in specific models. And the SDK's were practically running only on Windows (and very specific versions of windows that is). Now, the new Maemo SDK is linux only, and it requires a lot of setup steps compared to android. So Nokia developers should make a move from windows to linux and from symbian to maemo. Whoa, that seems like a lot of work!
On the other hand the android SDK runs on windows, linux and MacosX, is simple to setup (at least compared to symbian and Maemo) and the emulator and the IDE are really simple to use and quite fast. In only one year android has 10,000+ apps and a lot of them are very good. Of course Nokia is starting to make some moves on the right direction. One of those moves is QT Creator, a very good cross - platform IDE, that can create QT apps that can be compiled for mobile platforms like Maemo, in good, old, speedy C++. But until Nokia bundles a simple to use QT Creator and Maemo SDK combo, I don't see developers fleeing their way.
However, N900, the first Maemo smartphone device, looks cool and packs a lot of power. But as we all know, the apps count, so Nokia should help developers write some cooool apps or it may be heading palm's way.
Friday, May 22, 2009
Robotic Space Rock 1.0.10 for android 1.5 (cupcake)
getHolder().setType(android.view.SurfaceHolder.SURFACE_TYPE_GPU);Friday, May 1, 2009
New! Improved! The 1.5 android SDK is here.
Saturday, April 4, 2009
Robotic Space Rock and other games fell victims of the DMCA
For more information, or to contact us, please reply to this email, or visit the Android Market Help Center.
Thanks,
The Android Market Team
Now my application looks like this in the developer console:

Additionaly they forwarded me a four page fax they received from Norris, McNaughlin &
Marcus P.A. who represent the Tetris Company.
Here's the fax:




As you can see there are six applications listed for infringement:
Blocks, Cubik, Net Tetris, Netblocks, Robotics Space Rock, Tetroid
Actually, my application is called "Robotic Space Rock", not Robotics Space Rock. However I do not use the tetris name anywhere in my application, and I do not copy or reuse tetris related art or sound. The game mechanics are also quite different. And the application is free.
Thursday, February 26, 2009
Some lessons learned from the android market
So what are my conclusions for now:
1. Never, ever release an app, unless you thoroughly test it on a real device. If you don't get it passably right the first time, your app will be buried.
2. The phone memory limit is a severe limitation. My application has some original music. I wanted to add a couple of songs or more but I do not want to, because that would make it bigger and big apps, especially games are not going to stay on the phone for long. So keep your app small (under 1 MB) in order to maximize the chance of your application staying on the phone. Google should permit program installation on the SD card, increase the APK size limit and maybe increase the amount of internal storage to 1 GB or more.
3. Games are not that popular on the G1. It seems that geeks don't like gaming so much, or the games currently available are not so hot. So focus on applications, especially if you want to make some $$$.
4. Sound support for android is not good yet. If you use SoundPool, you increase the chance of your application hanging, making the user unhappy. I think that sound problems should be corrected immediately, because that affects all kinds of applications and especially games.
In my next blog entry I will try to compare android to iphone and symbian developer tools and market publishing. Stay tuned!
Saturday, February 7, 2009
Robotic Space Rock 1.0.8 beta released!
1. Added easy mode. Now the screen spins in Normal and Expert Difficulty. The screen does not move in Easy Difficulty.
2. Changed texture size to 32x32 from 64x64 in order to improve performance.
3. Changed the way explosions are drawn.
4. Added a game over sound effect.
5. Changed the way that playfield rotation is calculated by introducing a new LinearInterpolator class.
As always your remarks, bug reports and suggestions are welcome!
Thursday, February 5, 2009
A class for playing music and sound effects revisited
This is the Sound interface used to abstract soundplaying functions.
package org.teacake.monolith.apk;
public interface Sound {
public void addSound(int resid, boolean isLooping);
public void startSound();
public void stopSound();
public void stopSound(int resid);
public void playSound(int resid);
public void startMusic(int resid);
public void stopMusic(int resid);
public void pauseMusic(int resid);
public void resumeMusic(int resid);
}
And now for the main dish, SoundPoolManager class
package org.teacake.monolith.apk;
import android.media.SoundPool;
import android.util.Log;
class SoundPoolEvent
{
public SoundPoolEvent(int eventType,int eventSound)
{
this.eventType = eventType;
this.eventSound = eventSound;
}
public int eventType;
public int eventSound;
public static final int SOUND_PLAY=0;
public static final int SOUND_STOP=1;
public static final int SOUND_MUSIC_PLAY=2;
public static final int SOUND_MUSIC_PAUSE=3;
public static final int SOUND_MUSIC_STOP=4;
public static final int SOUND_MUSIC_RESUME=5;
}
class SoundStatus
{
public SoundStatus()
{
}
public static final int STATUS_LOOPING_NOT_STARTED=0;
public static final int STATUS_LOOPING_PAUSED=1;
public static final int STATUS_LOOPING_PLAYING=2;
}
public class SoundPoolManager extends Thread implements Sound
{
SoundPoolManager(android.content.Context context)
{
this.context = context;
soundEvents = new java.util.LinkedList();
sounds = new java.util.HashMap();
handles = new java.util.HashMap();
mediaPlayers = new java.util.HashMap();
isRunning = false;
}
public void addSound(int resid, boolean isLooping)
{
sounds.put(resid, new Boolean(isLooping));
if(isLooping)
{
try
{
android.media.MediaPlayer mp = android.media.MediaPlayer.create(context, resid);
mp.setLooping(true);
mp.seekTo(0);
//mp.prepare();
mediaPlayers.put(resid, mp);
//mp.seekTo(0);
//mp.setAudioStreamType(android.media.AudioManager.STREAM_MUSIC);
}
catch(Exception e)
{
Log.d("ERROR",e.getMessage());
}
}
}
public void run()
{
android.media.MediaPlayer mp = null;
while(isRunning)
{
try
{
while(soundEvents.size()>0)
{
SoundPoolEvent event = soundEvents.remove();
if(event!=null)
{
switch(event.eventType)
{
case SoundPoolEvent.SOUND_PLAY:
android.media.AudioManager mgr = (android.media.AudioManager) context.getSystemService(android.content.Context.AUDIO_SERVICE);
int streamVolume = mgr.getStreamVolume(android.media.AudioManager.STREAM_MUSIC);
soundPool.play(handles.get( event.eventSound).intValue(), streamVolume, streamVolume, 1, 0, 1.0f);
break;
case SoundPoolEvent.SOUND_STOP:
break;
case SoundPoolEvent.SOUND_MUSIC_PLAY:
currentPlayer = event.eventSound;
if(sounds.get(currentPlayer)!=null)
{
mp = mediaPlayers.get(currentPlayer);
if(!mp.isPlaying())
{
mp.seekTo(0);
mp.start();
}
}
break;
case SoundPoolEvent.SOUND_MUSIC_STOP:
currentPlayer = event.eventSound;
mp = mediaPlayers.get(currentPlayer);
mp.pause();
break;
case SoundPoolEvent.SOUND_MUSIC_PAUSE:
currentPlayer = event.eventSound;
mp = mediaPlayers.get(currentPlayer);
mp.pause();
break;
case SoundPoolEvent.SOUND_MUSIC_RESUME:
currentPlayer = event.eventSound;
mp = mediaPlayers.get(currentPlayer);
mp.start();
break;
}
}
}
}
catch(Exception e)
{
//Log.d("Error",e.getMessage());
}
try
{
this.wait(100);
//java.lang.Thread.currentThread().sleep(100);
}
catch(Exception e)
{
}
}
}
public void startSound()
{
this.soundPool = new android.media.SoundPool(this.sounds.size(),android.media.AudioManager.STREAM_MUSIC,100);
java.util.Iterator iterator = sounds.keySet().iterator();
while(iterator.hasNext())
{
int soundid = iterator.next().intValue();
int soundhandle = this.soundPool.load(this.context, soundid, 1);
handles.put(new Integer(soundid), new Integer(soundhandle));
}
isRunning=true;
this.start();
}
public void stopSound()
{
java.util.Iterator iterator = sounds.keySet().iterator();
while(iterator.hasNext())
{
int soundid = iterator.next().intValue();
if(this.sounds.get(soundid).booleanValue())
{
android.media.MediaPlayer mp = mediaPlayers.get(soundid);
mp.stop();
mp.release();
mp=null;
}
else
{
this.soundPool.pause( this.handles.get(soundid).intValue());
this.soundPool.stop(this.handles.get(soundid).intValue());
}
}
isRunning=false;
this.soundPool.release();
}
public int currentPlayer;
private boolean isRunning;
private java.util.HashMap sounds;
private java.util.HashMap handles;
private android.content.Context context;
private java.util.LinkedList soundEvents;
private java.util.HashMap mediaPlayers;
public void stopSound(int resid)
{
if(soundEvents!=null)
{
try
{
soundEvents.add(new SoundPoolEvent(SoundPoolEvent.SOUND_STOP,resid));
}
catch(Exception e)
{
}
}
}
public void playSound(int resid)
{
if(soundEvents!=null)
{
try
{
soundEvents.add(new SoundPoolEvent(SoundPoolEvent.SOUND_PLAY,resid));
this.notify();
}
catch(Exception e)
{
}
}
}
public void startMusic(int resid)
{
if(soundEvents!=null)
{
try
{
soundEvents.add(new SoundPoolEvent(SoundPoolEvent.SOUND_MUSIC_PLAY,resid));
this.notify();
}
catch(Exception e)
{
}
}
}
public void stopMusic(int resid)
{
if(soundEvents!=null)
{
try
{
soundEvents.add(new SoundPoolEvent(SoundPoolEvent.SOUND_MUSIC_STOP,resid));
this.notify();
}
catch(Exception e)
{
}
}
}
public void pauseMusic(int resid)
{
if(soundEvents!=null)
{
try
{
soundEvents.add(new SoundPoolEvent(SoundPoolEvent.SOUND_MUSIC_PAUSE,resid));
this.notify();
}
catch(Exception e)
{
}
}
}
public void resumeMusic(int resid)
{
if(soundEvents!=null)
{
try
{
soundEvents.add(new SoundPoolEvent(SoundPoolEvent.SOUND_MUSIC_RESUME,resid));
this.notify();
}
catch(Exception e)
{
}
}
}
SoundPool soundPool;
}
How do you use it?
First create an instance of the class.
Then add the resources to the SoundPoolManager (Sounds and music tracks)
Then start the SoundManager thread.
Then use the playSound() method to play a sound effect or playMusic() to play a song.
SoundPoolManager m = new SoundPoolManager(context);
m.addSound(R.raw.bang, false);
m.addSound(R.raw.mysong,true);
m.startSound();
m.playSound(R.raw.bang);
m.playMusic(R.raw.mysong);
If you want to pause the music use the pause call.
Use the stopSound() method to stop the sound thread.
The code is crude and the method names are not quite appropriate but it is published under the assumption that you may find it useful. You can take a look at the Robotic Space Rock code found at http://code.google.com/p/monolithandroid for actual examples.
Wednesday, January 28, 2009
MonolithAndroid renamed to Robotic Space Rock
Thursday, January 22, 2009
How to display a license agreement on your android 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
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
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
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?
Tuesday, December 30, 2008
Another monolithandroid beta is out
First, the prepareAsync call used in media player to play sounds caused problems. Now synchronous playback is used.
Second, The textures that I was using were pretty big. Now the texture sizes (used for the moon and earth) are reduced below 64x64 pixels. Third, I had a starfield class that drew 3d points in order to give the player the illusion of space travel. The problem was I was trying to draw 10000 points which is way too much. Now only 100 points are drawn. So go to http://code.google.com/p/monolithandroid and grab the latest apk. Give it a try on your android phone and you may even have some fun. I hope that the music won't drive you crazy! Post your comments here or use the Issue tracker found on http://code.google.com/p/monolithandroid
Oh, and don't forget to say what device you used for your tests!
I would like to take the opportunity to wish you a happy new year.
Tuesday, December 23, 2008
MonolithAndroid needs you!
I would like you to download the installation package from http://code.google.com/p/monolithandroid and try it out on your TMobile G1. And here's what I would like to know:
1. Does the application start?
2. Do you hear music?
3. Can you see the letters MonolithAndroid going on and off?
4. You only see a black screen?
5. If the game seems to run, does it run smoothly, or it feels sluggish?
Tuesday, September 23, 2008
Some thoughts on google android as a gaming platform
Android has rich multimedia and graphics api's:
1.Support for openGL/ES and 2D drawing.
2.Media api's.
3.Support for sensors (GPS and accelerometer).
4.Networking.
5.Optional touch interface.
So in theory, it should be ideal for gaming, right?
Well yes, but there are some caveats:
1. Not all devices will support touch interfaces and sensors.
2. Not all devices will have the same screen size.
3. For gaming, some sort of joystick or D-PAD device is essential. A D-PAD was standard in the various emulator images, since the first SDK, but the first device (The T-Mobile G1) comes without a D-PAD! Instead, we get a tiny trackball, not the best IO device for gaming!
So the problem is that as it seems, we will have a lot of different devices, with different configurations. Some will have touch interfaces, some will not, some will have a D-PAD, some will have trackballs, some will have acceleration sensors and so on. So, a game developer that develops for android will have the same kind of problems that a PC game programmer has. Different screen sizes and IO devices and so on... That increases the amount of time and resources a developer has to use in order to make his game playable on most phones. The same problems that drive a lot of PC game developers to game consoles.
So how can this be remedied? Well I guess that one possible solution is the introduction of a limited set of device profiles. Something like basic, gaming and advanced profiles, that will provide the developer with the same set of IO features.
Otherwise, I see a lot of developers fleeing to the apple iPhone, with it's game console simplicity, rather than the android's PC like capabilities.
I'd love to see your opinion on those thoughts, so shoot!
Search the web

