Tahakki's Blog
I spak verreh gud england.
I spak verreh gud england.
Jun 16th
Jun 9th
Just a very quick update – Button Puzzle and Button Puzzle Lite have been removed from the market and combined into Code Breaker. It is free and has all the features of the full version of Button Puzzle, and is ad-supported. Nobody was buying the full version so I thought I’d just fire it out for free. QR code is below, enjoy.
May 17th
Just a quick update on what I’ve been doing in terms of development over the last couple of weeks. Firstly, Portada is temporarily on hold until I can be bothered. Secondly, I created a small ‘video diary’ app, at the request of one of the commenters on OMG! Ubuntu! – that’ll hit Launchpad soon enough. For the last little while, though, the bulk of my work has been back on Folk, my Android game. I’ve been building the actual ground-level interface, since before all you could do was fly around in your ship. I now have something approaching a top-down action RPG. I have drawn all the sprites and tiles myself. Quick screenshot:

The green alien is the PC, and is controlled by a 4-way control stick. The button is context-sensitive, it lights up green for interaction and red for combat. Otherwise, it's grey.
A demo of some sort should eventually be available, but there’s a lot to do first. Stay tuned!
Apr 21st
Just wanted to briefly share something I’ve started work on – a coverart screensaver called Portada. It hooks into your Banshee album art. The image above is of the rather sexy settings menu I’m currently working on. More to follow – this is by far the most challenging software thingy I’ve ever done, dealing with different resolutions etc.
Apr 21st
Some of you may have seen the following website:
I find that website intensely useful. As such, I thought – what if I’m on the move and have no internet connection on my phone? What happens then? Thus, the Android app was born.
The app informs you at a high speed how August it is, on a scale of No to Yes.
It’s available in the Android market for free. Go get it, and never lie awake wondering again.
Feb 21st
We have released version 1.0 of Photostory! This version brings in a load of new features…
You want it, don’t you? Yes you do. Launchpad page here. Go wild.
Feb 15th
You can use Python to create some interesting patterns and shapes. Try these out! Here’s one:
import time val = 0.02 while 1: print "|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........\n" time.sleep(val) print ".|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|........\n" time.sleep(val) print "..|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.......\n" time.sleep(val) print "...|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|......\n" time.sleep(val) print "....|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.....\n" time.sleep(val) print ".....|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|....\n" time.sleep(val) print "......|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|...\n" time.sleep(val) print ".......|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|..\n" time.sleep(val) print "........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.\n" time.sleep(val) print ".........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|\n" time.sleep(val) print "........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.\n" time.sleep(val) print ".......|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|..\n" time.sleep(val) print "......|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|...\n" time.sleep(val) print ".....|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|....\n" time.sleep(val) print "....|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.....\n" time.sleep(val) print "...|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|......\n" time.sleep(val) print "..|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|.......\n" time.sleep(val) print ".|.........|.........|.........|.........|.........|.........|.........|.........|.........|.........|........\n" time.sleep(val) |
And another:
import random while 1: a = random.randint(0, 9) print a, |
Yep, four lines. It looks kinda cool though:
Jan 8th
You remember that little puzzle I showed you in my last post, that was going to be included in Folk?
I scrapped that idea – and turned it into a full app all by itself! Instead of one code to be solved, there are lots. Here’s how it works – the user has to match the colours of the buttons with the colours shown in the grid above. They do this by pressing buttons, but each button press triggers a change in not only the one pressed, but those adjacent also. Each puzzle has a theme or shape, and a title. Here’s a screenshot:
You can try the app out for yourself! The Lite version has 20 levels, ads and no saving, while the full version has 40 levels with more to follow, no ads and your progress is automatically saved. It also has 5×5 levels, which are quite tricky! Here are the QR codes!
Nov 29th
Decided to make a small puzzle for Folk – this takes the form of a keypad on a door. The player has to crack the code to get in.
The puzzle is very simple. There are nine buttons, arranged in a square. Initially eight are red and one is green. The objective is to turn all the buttons green. Pressing a button changes its colour – but also the colour of those buttons adjacent to it! The puzzle is actually fairly tricky but once it has been done once it becomes much easier. Here is a screenshot:

The graphics were, of course, very easy to do. I made a white button, and then colourise it using code. Here’s the full source:
import org.anddev.andengine.engine.Engine; import org.anddev.andengine.engine.camera.Camera; import org.anddev.andengine.engine.options.EngineOptions; import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation; import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy; import org.anddev.andengine.entity.scene.Scene; import org.anddev.andengine.entity.scene.background.ColorBackground; import org.anddev.andengine.entity.sprite.Sprite; import org.anddev.andengine.input.touch.TouchEvent; import org.anddev.andengine.opengl.texture.Texture; import org.anddev.andengine.opengl.texture.TextureOptions; import org.anddev.andengine.opengl.texture.region.TextureRegion; import org.anddev.andengine.opengl.texture.region.TextureRegionFactory; import org.anddev.andengine.ui.activity.BaseGameActivity; public class CodePuzzle extends BaseGameActivity { // =========================================================== // Constants // =========================================================== private static final int CAMERA_WIDTH = 800; private static final int CAMERA_HEIGHT = 480; // =========================================================== // Fields // =========================================================== private Camera mCamera; private Texture backTex; private TextureRegion backTexR; private Texture buttonTex; private TextureRegion buttonR; private Sprite button1; private Sprite button2; private Sprite button3; private Sprite button4; private Sprite button5; private Sprite button6; private Sprite button7; private Sprite button8; private Sprite button9; // =========================================================== // Constructors // =========================================================== // =========================================================== // Getter & Setter // =========================================================== // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== @Override public Engine onLoadEngine() { this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT); return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera)); } @Override public void onLoadResources() { backTex = new Texture(512, 512, TextureOptions.BILINEAR_PREMULTIPLYALPHA); buttonTex = new Texture(128, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA); buttonR = TextureRegionFactory.createFromAsset(this.buttonTex, this, "gfx/codepuzzle_button.png", 0, 0); backTexR = TextureRegionFactory.createFromAsset(this.backTex, this, "gfx/codepuzzle_back.png", 0, 0); this.mEngine.getTextureManager().loadTextures(backTex, buttonTex); } @Override public Scene onLoadScene() { final Scene scene = new Scene(2); scene.setBackground(new ColorBackground(0, 0, 0)); final Sprite back = new Sprite(200, 40, 400, 400, backTexR); button1 = new Sprite(225, 65, 100, 100, buttonR){ @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { switch (pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: buttonPushed(1); } return true; }; }; button2 = new Sprite(350, 65, 100, 100, buttonR){ @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { switch (pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: buttonPushed(2); } return true; }; }; button3 = new Sprite(475, 65, 100, 100, buttonR){ @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { switch (pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: buttonPushed(3); } return true; }; }; button4 = new Sprite(225, 190, 100, 100, buttonR){ @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { switch (pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: buttonPushed(4); } return true; }; }; button5 = new Sprite(350, 190, 100, 100, buttonR){ @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { switch (pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: buttonPushed(5); } return true; }; }; button6 = new Sprite(475, 190, 100, 100, buttonR){ @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { switch (pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: buttonPushed(6); } return true; }; }; button7 = new Sprite(225, 315, 100, 100, buttonR){ @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { switch (pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: buttonPushed(7); } return true; }; }; button8 = new Sprite(350, 315, 100, 100, buttonR){ @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { switch (pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: buttonPushed(8); } return true; }; }; button9 = new Sprite(475, 315, 100, 100, buttonR){ @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { switch (pSceneTouchEvent.getAction()) { case TouchEvent.ACTION_DOWN: buttonPushed(9); } return true; }; }; scene.getBottomLayer().addEntity(back); scene.getTopLayer().addEntity(button1); scene.getTopLayer().addEntity(button2); scene.getTopLayer().addEntity(button3); scene.getTopLayer().addEntity(button4); scene.getTopLayer().addEntity(button5); scene.getTopLayer().addEntity(button6); scene.getTopLayer().addEntity(button7); scene.getTopLayer().addEntity(button8); scene.getTopLayer().addEntity(button9); button1.setColor(1.0f, 0.0f, 0.0f); button2.setColor(1.0f, 0.0f, 0.0f); button3.setColor(0.0f, 1.0f, 0.0f); button4.setColor(1.0f, 0.0f, 0.0f); button5.setColor(1.0f, 0.0f, 0.0f); button6.setColor(1.0f, 0.0f, 0.0f); button7.setColor(1.0f, 0.0f, 0.0f); button8.setColor(1.0f, 0.0f, 0.0f); button9.setColor(1.0f, 0.0f, 0.0f); scene.registerTouchArea(button1); scene.registerTouchArea(button2); scene.registerTouchArea(button3); scene.registerTouchArea(button4); scene.registerTouchArea(button5); scene.registerTouchArea(button6); scene.registerTouchArea(button7); scene.registerTouchArea(button8); scene.registerTouchArea(button9); return scene; } @Override public void onLoadComplete() { // TODO Auto-generated method stub } public void buttonPushed(final int buttPressed){ if (buttPressed == 1){ button1.setColor(button1.getGreen(), button1.getRed(), 0.0f); button2.setColor(button2.getGreen(), button2.getRed(), 0.0f); button4.setColor(button4.getGreen(), button4.getRed(), 0.0f); button5.setColor(button5.getGreen(), button5.getRed(), 0.0f); } else if (buttPressed == 2){ button2.setColor(button2.getGreen(), button2.getRed(), 0.0f); button1.setColor(button1.getGreen(), button1.getRed(), 0.0f); button3.setColor(button3.getGreen(), button3.getRed(), 0.0f); button5.setColor(button5.getGreen(), button5.getRed(), 0.0f); } else if (buttPressed == 3){ button3.setColor(button3.getGreen(), button3.getRed(), 0.0f); button2.setColor(button2.getGreen(), button2.getRed(), 0.0f); button6.setColor(button6.getGreen(), button6.getRed(), 0.0f); button5.setColor(button5.getGreen(), button5.getRed(), 0.0f); } else if (buttPressed == 4){ button4.setColor(button4.getGreen(), button4.getRed(), 0.0f); button1.setColor(button1.getGreen(), button1.getRed(), 0.0f); button5.setColor(button5.getGreen(), button5.getRed(), 0.0f); button7.setColor(button7.getGreen(), button7.getRed(), 0.0f); } else if (buttPressed == 5){ button2.setColor(button2.getGreen(), button2.getRed(), 0.0f); button5.setColor(button5.getGreen(), button5.getRed(), 0.0f); button4.setColor(button4.getGreen(), button4.getRed(), 0.0f); button6.setColor(button6.getGreen(), button6.getRed(), 0.0f); button8.setColor(button8.getGreen(), button8.getRed(), 0.0f); } else if (buttPressed == 6){ button6.setColor(button6.getGreen(), button6.getRed(), 0.0f); button3.setColor(button3.getGreen(), button3.getRed(), 0.0f); button5.setColor(button5.getGreen(), button5.getRed(), 0.0f); button9.setColor(button9.getGreen(), button9.getRed(), 0.0f); } else if (buttPressed == 7){ button4.setColor(button4.getGreen(), button4.getRed(), 0.0f); button5.setColor(button5.getGreen(), button5.getRed(), 0.0f); button7.setColor(button7.getGreen(), button7.getRed(), 0.0f); button8.setColor(button8.getGreen(), button8.getRed(), 0.0f); } else if (buttPressed == 8){ button5.setColor(button5.getGreen(), button5.getRed(), 0.0f); button7.setColor(button7.getGreen(), button7.getRed(), 0.0f); button8.setColor(button8.getGreen(), button8.getRed(), 0.0f); button9.setColor(button9.getGreen(), button9.getRed(), 0.0f); } else if (buttPressed == 9){ button5.setColor(button5.getGreen(), button5.getRed(), 0.0f); button6.setColor(button6.getGreen(), button6.getRed(), 0.0f); button8.setColor(button8.getGreen(), button8.getRed(), 0.0f); button9.setColor(button9.getGreen(), button9.getRed(), 0.0f); } } } |
Nov 22nd
I uploaded a very basic demo of Folk onto the Android Market. One of the suggestions was some indication of which direction the ship was travelling in. I decided to use a ParticleSystem, whereby the ship would have all these wee circles shooting out the back, then fading away. It actually looks and works very well. Here’s a little screenshot (taken from the emulator, so quality is not as good as it could be):
Here’s the code I used. Very simple.
final ParticleSystem particleSystem = new ParticleSystem(new PointParticleEmitter(face.getX(), face.getY()), 1, 5, 200, this.mParticleTextureRegion);particleSystem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE);particleSystem.addParticleInitializer(new ColorInitializer(1.0f, 0.0f, 0.0f));particleSystem.addParticleModifier(new ExpireModifier(2.0f));particleSystem.addParticleModifier(new ColorModifier(0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.5ffinal ParticleSystem particleSystem = new ParticleSystem(new PointParticleEmitter(face.getX(), face.getY()), 1, 5, 200, this.mParticleTextureRegion);
particleSystem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
particleSystem.addParticleInitializer(new ColorInitializer(1.0f, 0.0f, 0.0f));
particleSystem.addParticleModifier(new ExpireModifier(2.0f));
particleSystem.addParticleModifier(new ColorModifier(0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.5f));
I also have it set the particle spawner to the ship on every update.
For those interested, here’s a quick shot of what my desktop looks like when programming:
That’s all for now. Laters!