Thursday, February 15, 2007

Orange Pixel - Softkey buttons

A generic solution to softkey buttons on most populair phone models. Tried and tested on nokia,sony,siemens, samsung and motorola phones.
One of the problems for cross-phone code are the softkey codes, although with most midp2 phones there seems to be an attempt at using a standard value, but there is still a long way to go.
Since we don't like having many different ports just for small things like different keycodes, a generic softkey code would be perfect but is also hard to implenent without breaking things on certain phones. An attempt at this generic code is available below, it is tested on nokia,sony,siemens,motorola and samsung phones.
If you have any add-ons, or fixes to this code then please let me know, the ifdef for nokia phones can be removed but it's there cause I personally use special builds for nokia fullcanvas usage.


/*-===-==-==-===-==-==-===-==-==-===-==-==-===
OrangePortal Rumble FrameWork version 2.0
(c) 2005 OrangePixel - www.orangepixel.net

void retrieveSoftKeys()
requires:
public static int LeftSoftKey;
public static int RightSoftKey;
-===-==-==-===-==-==-===-==-==-===-==-==-===-*/

public static int LeftSoftKey;
public static int RightSoftKey;

// Generic soft-key detection
protected final void retrieveSoftKeys() {
//#ifdef nokia
LeftSoftKey=-6;
RightSoftKey=-7;
//#else
LeftSoftKey=0;
RightSoftKey=0;

try {
// Set Siemens specific keycodes
Class.forName("com.siemens.mp.game.Light");
LeftSoftKey=-1;
RightSoftKey=-4;
} catch (ClassNotFoundException ignore) {
try {
// Set Motorola specific keycodes
Class.forName("com.motorola.phonebook.PhoneBookRecord");
if (getKeyName(-21).toUpperCase().indexOf("SOFT")>=0) {
LeftSoftKey=-21;
RightSoftKey=-22;
} else {
LeftSoftKey=21;
RightSoftKey=22;
}
} catch (ClassNotFoundException ignore2) {
boolean found;

// check for often used values
// This fixes bug with some Sharp phones and others
try {
// Check for "SOFT" in name description
if (getKeyName(21).toUpperCase().indexOf("SOFT")>=0) {
LeftSoftKey=21; // check for the 1st softkey
RightSoftKey=22; // check for 2nd softkey
found=true;
}

// Check for "SOFT" in name description
if (getKeyName(-6).toUpperCase().indexOf("SOFT")>=0) {
LeftSoftKey=-6; // check for the 1st softkey
RightSoftKey=-7; // check for 2nd softkey
found=true;
}
}catch(Exception e) {}

// run thru all the keys
for (int i=-127;i<127;i++)>
try {
// Check for "SOFT" in name description
if (getKeyName(i).toUpperCase().indexOf("SOFT")>=0) {
// check for the 1st softkey
if (getKeyName(i).indexOf("1")>=0) LeftSoftKey=i;
// check for 2nd softkey
if (getKeyName(i).indexOf("2")>=0) RightSoftKey=i;
}
}catch(Exception e){
// Sony calls exception on some keys
// including softkeys
// bugfix is to set the values ourself
LeftSoftKey=-6;
RightSoftKey=-7;

}
}
}
}
//#endif
}

The original article can be found at Orange Pixel.

Tuesday, February 13, 2007

Orange Pixel - Scrolling tile engine

Most games use some form of scrolling background, with midp2 there comes a tiled-layer engine but it is often advised to not use this. The implementation of the tiled-layer engine is slow, memory consuming and completely unoptimised. We show you how it can be done better.
This is a very fast explanation of how to do a basic tile engine, we include some optimising and tricks and tips, if you can't figure things out we suggest you read the Java documentation on what some things mean.
The basics
First steps are obviously the basics. A tiled-engine is very simple, you basically draw the tiles on the screen according to the location of the player. Best practice is to use tiles of 16x16 or 32x32 in size (notice the power of 2).
The most basic version of a tile engine is:

for (int y=8; --y>=0; ) {
for (int x=8; --x>=0; ) {
Graphics.drawImage(TILEIMAGE,(x<<4), (y<<4), Graphics.LEFT|Graphics.TOP);
}
}


This draws 8x8 tiles on the screen with each tile being 16x16 pixels in size.
The (x<<4) and (y<<4) are bitshifting operations (see java docs!) and is simply a faster way to multiply by 16 (the magical power of 2 comes into play).
A map
Drawing all the same tiles isn't going to be an interesting game, so we need some variation. The best way to do this is to create a game map.
The game map is a very simple array of integers or bytes (ints are faster, bytes take up less memory, so make the decision). Best practice is to make this map dimension also a power of 2 in width. So a map of 128x10 is better then 120x10, we get to the reason later, first lets update our map code:

for (int y=8; --y>=0; ) {
for (int x=8; --x>=0; ) {
Graphics.drawImage(TILEIMAGE[map[x+(y<<7)]],(x<<4), (y<<4), Graphics.LEFT|Graphics.TOP);
}
}


The difference is that our TILEIMAGE become an array of images/tiles, and we now locate the correct image index using our map[] array. Noticed the (y<<7) ? To get our offset in the map, we can multiply Y by the width of our map, so thats why we want this map to be a width of 128 or 256, we can multiply it faster using bitshifting.
Instead of using an array of images we can also put alot of tiles into one image, this is another decision to be made in terms of memory and speed. Using a single image and clipping it will be alot slower due to most phones walking through every pixel of the image no matter how much you clip it. On the other hand the heap overhead of having multiple images can also be a major problem for older phones. Try to find the best route and possibly mix both options a bit.
When using a single image you simply add a setClip() and shift the drawimage coordinates depending on where the specific map[x+(y<<7)] tile is in your image.
Player offset
To make the screen scroll you will have to follow the player or a camera. You then add those X+Y values to the map offset of the tiles you draw. A very simple way to center your player is using these lines:

// calcualte amount of tiles on screen
amountX=((getWidth()+16)>>4)+1;
amountY=((getHeight()+16)>>4)+1;
// calculate player center
mapX=(player1.x>>4)-(amountX>>1)+2;
mapY=(player1.y>>4)-(amountY>>1)+1;


The amountX and amountY only have to be calculated once, or if the screen dimensions would change. So you don't have to calculate those every game loop, the mapX and mapY values will change everytime the player makes a move, so it's best to have these calculated after doing the player's movements.
What we do is simple, we take the players horizontal position, divide it by 16 to get the tile-index and then we substract half the amount of tiles that can fit on the screen (amountX>>1). The adding of 2 at the end is just position your player slightly more to the left of the center, very handy if your player is running to the right of the screen as it gives the player a bigger area of incomming traffic.
Do the same for the vertical offset, and then we have the top,left corner of what our map should draw. Using these values, we add them to the tile-engine and we get this :

for (int y=amountY; --y>=0; ) {
for (int x=amountX; --x>=0; ) {
Graphics.drawImage(TILEIMAGE[map[mapX+x+((mapY+y)<<7)]],(x<<4), (y<<4), Graphics.LEFT|Graphics.TOP);
}
}


The X,Y now run through all the tiles possibly fitting on the screen (amountX and amountY). We then look up the tile at ( (mapX+x),(mapY+y) ) and we draw it at the correct position on screen.
Smoothing it out
There you have it, your basic tile engine! But wait, this screen now scrolls in a very blocky way!? Well, ofcourse it does, we now draw in tiles and not taking into account that the player might move only 4 or 8 pixels, thats less then a full tile. To take this into account we can do a very simple trick by shifting the screen with the amount of pixels the player has moved.
xOffset=-(player1.x&15);
yOffset=-(player1.y&15);
Well there you have it! The power of simplicity. What we do here is we calculate the offset of the players position with the size of a tile. The &15 is a bitwise AND comparing so check the java docs again if you don't understand this. Using the xOffset and yOffset values we can now add them to the drawing-offset of our tiles and create smooth scrolling:

for (int y=amountY; --y>=0; ) {
for (int x=amountX; --x>=0; ) {
Graphics.drawImage(TILEIMAGE[map[mapX+x+((mapY+y)<<7)]],xOffset+(x<<4), yOffset+(y<<4), Graphics.LEFT|Graphics.TOP);
}
}


Homework!
This is all a very basic engine, and you can extend it all and optimise things even more. For one you will need to check the scrolling boundaries, make sure the player doesn't move to far to the left or right. You can also optimise some of the calculations removing some of the multiplying.
This however should help most people getting their own tiled-engine running, and it will run alot faster then the standard midp2 implementation. It is also possible to have much larger maps and add special game specific tweaks and tricks.

The original article can be found at Orange Pixel.

Monday, February 5, 2007

Emulators Guide




  • Download and install Samsung emulators. The latest version is here (login required).
    (Assume that you install Samsung emulators after installing other emulators)
  • Goto this folder "C:\SAMSUNG_WTK20\wtklib\devices" and you'll see a list of samsung devices.
  • Goto each device folder, and open the file with extension ".properties" with NotePad.
    Ex: Open file "C:\SAMSUNG_WTK20\wtklib\devices\SGH_X100\SGH_X100.properties"
  • Scroll down the file till you see this line: "colorCount=0x10000". Then you change it to "colorCount=0x1000000". The same for other files.
  • Goto Start Menu => "SAMSUNG JaUmi Wireless Toolkit 2.0" => "Default Device Selection" and choose which emulator you'd like to run the games. (Can skip this step)
  • Now double click on the ".jad" file of the game and enjoy.




  • Download and install SE Emulators.
    (Assume that you install SE emulators after installing other emulators)
  • Goto Start Menu => "Sony Ericsson" => "Java ME SDK for CLDC" => "WTK2" => "Default Device Selection" and choose which emulator you'd like to run the games. (Can skip this step)
  • If you have two files ".jad" and ".jar" for the game. You symply click on the ".jad" file to run the game.
  • If you have just one ".jar" file for the game. You have to open "Sony Ericsson\Java ME SDK for CLDC\WTK2\KToolbar" in the Start Menu. Goto menu "File" => "Create project from jad/jar" and select the ".jar" file. Then click "Run" button in the "KToolbar" windows.
Megaman Zero

Grab the Toolkits

Till now, there are many tools for creating mobile games now. But let me show you some pupular wireless toolkits.
Sun
Sony Ericsson
Samsung
Nokia
First download and install them. (If you just want to play mobile games using emulators, you can stop at this step)
Then you should use NetBeans and integrate those toolkits as below.
- Open NetBeans.
- Goto menu Tools => Java Platform Manager.
- In the "Java Platform Manager" dialogue, choose "J2ME" in tab "Platforms" and click buttom "Add Platform..." at the bottom.
- Next, you select "Java Micro Edition Platform Emulator" and click "Next". NetBeans will search for Wireless Toolkits installed in your computer.
- After searching, you will select which platforms you want (if available) and click "Next" till finish.

OK, now you got all the necessary tools to Let the Games Begin!
Megaman Zero

Friday, February 2, 2007

Welcome to Mobile Games Vietnam!

Hi Programmers!
Welcome to Mobile Games Vietnam Blog. This blog is all about
mobile games, a very interesting industry which attracts thousands of players and programmers around the world.
You'll find here many mobile games tutorials, tips, tricks and more...
Hope they're helpful for you in programming and creating great games for mobile gaming industry.
OK now. Let the Games Begin!
Regards.
Megaman Zero