Chinese Version (中文版)

Nice Simple Clock 1.1.0

I thought my clock widget would probably be buried in the seas of Android apps, but it seems that it is doing better than I expected. I even received a nice warm thank-you comment from Russia (the warmness is not lost in the Google translation), I am very happy with that. :D

Upon a request from a VIP, I added a new feature to this nice simple clock. And so here we have 1.1.0.
Version 1.1.0:

- New feature: users can choose to launch an installed application (e.g. an alarm clock) when the time area is clicked.
- Added 2 more formats for the am/pm text
- Fixed some default option display issue in the Chinese version
- Fixed some color issue in the readme display
- Some minor tweaks

Nice Simple Clock Released

After releasing my first Android game, Ninja Dodge!, I have been working on my second Android project - a clock widget.

As my first project was a game, I worked with OpenGL mostly, so I haven't really learned much the "app development" side of Android. For example, I had almost zero practical knowledge about those Android layouts, views, preferences, etc.. To make things "worse" I picked a widget project. That means I needed to learn about the Android widget stuff as well. The whole journey was quite challenging yet fruitful.

There are already millions of clock widgets out there, why do I still make one more? Well, I looked at some of the most popular ones, and I found each of them lacks some features that I would like to have. Of course, I haven't looked at all clock widgets in the market, but I figured that I should make my own so that I have total control of how it looks and works. Basically, I want it to be simple yet highly customizable. It would also definitely "feel right" to me because I make it myself. :D

Anyway, I made it in about 10 days of spare time. I learned a lot indeed. I think I can tell others that I can develop Android programs now as I released a game and an app. :D

So, here it is - a Nice Simple Clock.
Features:

- Minimalistic style
- Colorful semi-transparent background (You have the complete control of the color and transparency)
- Customizable text size, fatness, and color
- Customizable time and date formats
- Live preview of the customized clock in the setting screen
- Possibility to have more than one Nice Simple Clock widgets on the home screen, each with its own customization settings
- Different widget sizes support
- Battery-friendly design
And here are some screenshots:


Yup, I like simplicity and colors. :D

Ninja Dodge! Released

Yes. This is my first Android game. Finally!

It has already been published on the Android market, but I can't find it except using this direct link yet. You can find it here.

I am very excited and also very sleepy right now. I worked so hard to finish the last bits of it, I am so glad that it is finally done. I don't expect much from it tho as this is my first game and as I said it is more like a warm-up. I hope at least the game runs well on most android devices.

Here is the game description followed by a youtube gameplay video I quickly made:

Challenge and train your reflexes!

The gameplay is simple - try to dodge the balls and survive as long as you can. As the game progresses, the balls will get bigger, faster, and more in number!

Are you a failed ninja? a good ninja? or actually a GODLY ninja?

Come take the challenge! Compete with your friends and other competent ninjas all over the world.

Online leaderboards and achievements are supported. (OpenFeint network)



Game modes:

- Normal: Survive as long as you can. Control is simple: tap to move the ninja. Reflexivity is all that matters.

- Extreme: Ready for some extreme ninja challenges? Yes. EXTREME.

- Time Race: Collect as many hearts as you can while dodging those evil balls in 60 seconds.



More features and unlockable achievements will come. Tell me what you think. :)

Have fun!




OK I can sleep now. :)

glScissor Fails on HTC Devices

After I got my first android device, I immediately downloaded and tested my game with it. The first thing I noticed was that the rendering was weird. In a previous post, I talked about rendering within the viewport only with the use of glScissor. It worked well on my emulator and my borrowed android phones, but it didn't work on my own HTC Flyer. The regions outside my viewport were being rendered in a strange way.

After some searching, I found this issue has been reported. I don't have swap() in my program but I got the idea. The following works for me:

glScissor(0, 0, screenW, screenH);


//do the rendering here


glScissor(viewportX, viewportY, viewportW, viewportH);


Update (2011/11/14, noon):

It worked on my HTC Flyer but it didn't work on the emulator. When I think about the previous solution and how it worked somehow, I guess I now understand the problem. My guess is, we need to reset the scissor region to the whole screen, perform a complete screen cleaning by glClear, and then set the scissor to our viewport. The new solution, that appears to work for me on both my emulator and HTC Flyer, is:

glScissor(0, 0, screenW, screenH); 

glClear(GL10.GL_COLOR_BUFFER_BIT);

glScissor(viewportX, viewportY, viewportW, viewportH);

//then do the rendering here

Finally Got a Real Android Device

My first Android game is basically finished. :) Now I am just doing some testing and final changes, and preparing the materials for publishing to the Android Market.

I didn't have a real Android device to work with, so I had been developing my game with the emulator. The android emulator is great that you can test your program with it in different resolutions easily. However, it is very slow. Therefore, most of the time when I just needed to test the gameplay of my game, I would run the desktop version of my game. It launched and ran much faster. I have to thank libgdx for its convenient cross-platform feature.

Unfortunately when I had to test the android part and some rendering part of my game, I had no choice but to use the emulator. Launching and running my game there were very slow. It wasted me a lot of time. On top of that I had no idea how fast my game would run on real devices. Therefore, I borrowed android phones from my beloved one and a friend of mine from time to time for testing. At times I thought myself was too annoying. :P

I planned to wait for the new Android tablet, like the Kindle Fire and ASUS Transformer Prime, to come out. However, I can't wait any longer - I want to release my first game already and I have to complete the final development steps and testing with a real device. HTC Flyer was very expensive when it first came out, but now it is priced like half of its original price. Sounds like a bargain to me. Its spec is of course a bit out-dated as it has been in the market for half an year. I don't mind as I probably use it for android app development mostly. The not-too-big-not-too-small 7-inch monitor size looks also great. After much comparing with other devices and struggling, I went for it at the end. So far I am quite happy with it. :)

Testing on a real device is really different. In my emulator I used a mouse to play my game but on my HTC Flyer I had to use a touchscreen. It feels so different and controlling the character in my game is a little bit difficult with a touchscreen. I reckon I probably need to change the game control a bit to make it suit better on a touchscreen device.

Game Scaling and Rendering Inside the Viewport Only

Game graphics took me a lot of time but my first android game is about 70% finished now. As I could only work on it in my spare time, I am pretty happy with the progress. Hopefully I can release it to the world in 1 or 2 weeks of time. Things look a bit amateurish but I learned A LOT in the process. I am quite excited about it.

One thing I don't like developing games for the Android platform is that there are too many different screen sizes. I mean, it is fine to have screens with different sizes / resolutions, but it would be great if they all are of the same aspect ratio. (In this post I calculate aspect ratios by screen height / screen width.) So we have the common 480 x 800 / ratio 1.67 ones (Desire / Nexus One / Liquid). We have some slightly taller ones 480 x 854 / ratio 1.78 (Milestone / Defy). We also have some small ones: 240 x 320 / ratio 1.33 (Tattoo / Wildfire). And then some more... Well, don't forget the tablets too.

It is good to the customers as they got more choices at different price levels but that is probably a burden to the developers.

For application developers, it means they need to design their GUI layouts carefully and possibly provide different sets of their GUI graphics for different screen classes. I haven't really looked into the application development side yet, so I am not sure how difficult / trouble that actually is.

For game developers, they first need to make scalable game graphics and then they have to pay attention to the screen aspect ratio issue.

Using OpenGL, what the player see on the screen is basically a portion of the game world through the viewport (think of it as a window). Usually we just fit the viewport to the whole screen. Viewport and screen can have different sizes / resolutions. For example, the viewport can be of size 1000x1000 and your screen size can be of size 1200x600. In that case, your game world objects will look fatter than they actually are because you have more screen pixels for the width than the height.

So there are many different screen aspect ratios and they can be quite different, for example, it could be 1.33 vs 1.78. If you designed your game graphics for the screens with aspect ratio 1.33, and then you simply scale all your game graphics for other screens, that is, fitting the same viewport to different screens, then your game graphics may look just fine on the 1.33 screens but look too tall and weird on those 1.78 screens.

There are two ways of solving this.

The first one is to change the size of the viewport according to the screen size. For example, if the screen size is 480 x 800, then you will set the viewport size to 480 x 800 or 240 x 400 so that their aspect ratios match each other. Therefore, instead of showing taller than usual game world objects in a big screen with an aspect ratio of 1.78, you may just vertically expand your viewport to avoid destroying the apparent aspect ratio of the game world objects. By changing the viewport size according to the screen size, the player will see different sizes of the game world portion with different screens. It might be fine for some. However, this approach doesn't work for those games that require some kind of "fairness". For example, if the players of your game can compete with each others through the internet, then players that can see a larger portion of the game world may have an unfair advantage over the ones that can only see a smaller portion of the game world.

The second approach would be only using a part of the screen for the viewport. For example, if you want the viewport to be always showing a square portion of the game world, then in a 800x480 screen you will only use the 480x480 region in the middle as the viewport, and in a 320x240 screen you will only use the 240x240 region in the middle. You may not be able to use the whole screen for your game but all players will see the same size of the game world portion.

The code of setting up the viewport using the second approach looks something like this with OpenGL or any game library that uses it (I used libgdx myself):
viewportWidth = screenWidth;   
viewportHeight = screenWidth * fixedViewportAspectRatio;
if( viewportHeight > screenHeight )
{
    viewportHeight = screenHeight;
    viewportWidth = screenHeight * 1 / fixedViewportAspectRatio;
}
viewportX = ( screenWidth - viewportWidth ) / 2;
viewportY = ( screenHeight - viewportHeight ) / 2;
glViewport( viewportX, viewportY, viewportWidth, viewportHeight );
glScissor( viewportX, viewportY, viewportWidth, viewportHeight );
glEnable( GL_SCISSOR_TEST );
At first I didn't have the last two lines. When I ran the game I found that in the Android emulator the regions outside my viewport were being rendered. (interestingly, those regions were not rendered on my desktop) I did some searching with Google, and it turns out that believing that the viewport would clip or scissor is a common OpenGL pitfall. It s necessary to use a scissor box to make sure nothing got rendered outside the viewport. I added those 2 lines, and now I have a "proper viewport" that keeps my game graphics from getting destroyed by "bad scaling".



Update 1 (2011/11/04): Fixed some typos - I was too sleepy when I wrote this post last night. :P

Update 2 (2011/11/14): I found that glScissor falis on HTC devices. A solution is posted there.