Over the last couple of years, we have seen ever more advanced games for mobile devices. 3D graphics are no longer something you can only experience on the cutting edge devices, but are available on many mid-range mobile phones. For game developers focused on Java ME, there are two APIs available for creating 3D graphics, the Mobile 3D API (JSR-184) and the OpenGL ES bindings for Java ME (JSR-239). The Mobile 3D API is basically the Java ME equivalent to the Java 3D API we know from Java SE, while JSR-239 is a Java implementation of the OpenGL ES standard managed by the Khronos Group (there is also a Java SE implementation of the standard OpenGL API called JOGL). It is my belief that the JSR-239 will be more successful in the long run, since it is a more widespread standard than JSR-184 and is also better prepared for the new 3D graphics chips. We have seen the same behavior with Java3D versus JOGL, where developers abandoned Java 3D since it was too difficult to extend, and make use of new graphics features. 3D graphics can make very cool games, but unless you can interact with the game using more sensitive controls than binary buttons, the gaming experience will be limited. A touchscreen would be one way to raise the gaming experience, but there is another solution that I believe is likely to be even more successful. Several mobile devices on the market today have a built in accelerometer, much like the one used in the controls for the Nintendo Wii. These can be used to detect motion and the current tilt of the device. Since the feedback from the accelerometer is near real-time, it provides a new way to interact with our devices. We have just recently started to see the use of accelerometers in applications and games, and I believe that built-in accelerometers in mobile phones will become even more common as new mobile games appear. For Java ME, we already have an API for reading these accelerometers, the Mobile Sensor API (JSR-256). This article will describe a very simple game for a Sony Ericsson w910i that uses both the OpenGL ES API for Java ME and the Mobile Sensor API. The game is a simple space game where you fly straight ahead and try to avoid colliding with incoming asteroids. You steer the ship by tilting the phone in the direction you wish to go. Since I'm no 3D artist, and severely color blind, the graphics are quite crude, but I hope that you'll all see the possibilities of using these APIs together anyway. All the code for the game is available as a download at https://mobilespaceracer.dev.java.net/. Feel free to experiment with this and use it as you wish. Contents
The OpenGL ES is a standard managed by the Khronos Group, which also manages several other graphics and audio standards (OpenGL, OpenAL). OpenGL ES is based on the standard OpenGL API, so if you are already familiar with OpenGL, much of the code shown below will not be new to you. The Java ME implementation of OpenGL ES supports version 1.1, which is based on the standard OpenGL version 1.5. There is also an OpenGL ES version 2.0, but that version requires much more of the hardware and is currently not suitable for our mobile phones. I will not go into the details of 3D programming; there are plenty of other resources available that will give you a good introduction to OpenGL and 3D programming in general. Here I will focus on the details of initiating the OpenGL ES on Java ME and how to configure it properly for your device. JSR-239 is basically a direct implementation of the OpenGL ES API for the C programming language. There is also a package named To draw 3D with JSR-239 we use a
This method must be called before we can start drawing our 3D scene or initialize any textures or other resources that require the use of JSR-239. To start drawing our 3D scene, we create a new thread with a loop that runs as fast as possible (no delays between each iteration). This way we get the maximum number of frames per second. The actual game logic is managed by the game loop (see below). Typically, when designing a 3D scene using OpenGL, we use a scene graph to structure all the 3D objects. This way we can construct a complex object of several smaller ones and move them as a single unit. The code below shows how we tell the JSR-239 to capture the
The The Mobile Sensor API (JSR-256) is a general specification focused on communicating with the different sensors that are integrated on a Java ME device. It can be any type of sensor, like a thermometer, light sensor, or, as in this case, an accelerometer. An accelerometer measures accelerations, and the acceleration we are interested in for this game is the most common of all, gravity. Since gravity is constant, it is used to determine the tilt of our phone. In the Sony Ericsson w910i we have a built in three-axis accelerometer, which means that we can measure the acceleration in all three dimensions. If the phone was placed flat, the accelerometer would tell us that the acceleration along the z-axis (up and down) is about 1000 (this value represents 1G). The accelerations along the X and Y axises (sideways) would be about 0 since the phone is sitting still and gravity only works downwards. Flipping the phone over with the screen facing down, the accelerometer would give us the value of -1000 on the Z-axis. Standing on its side, would give us a value of 1000 or -1000 along either the X- or the Y-axis, depending on which side you put it. Putting the phone in a 45 degree angle along the X-axis would give us a value of ±707 on the Z-axis and ±707 on the Y-axis, since gravity cannot affect either axis with its full force (You can easily calculate what the value should be for a certain angle for each axis using the sine and cosine functions). Using the values from the X and Y-axis from the accelerometer, we can determine the position of the phone at any time, and then use that value to move our ship to avoid the incoming asteroids. The API for JSR-256 is very simple. To get access to the accelerometer, you use the Generic Connection Framework to open a connection given a device-specific URL. You can also use a When you have a reference to a sensor (implemented as a The code below is an implementation of an adapter that is suitable for games. It automatically registers itself as a
The core of this game (and most other games) is the game loop that updates the 3D scene, checks for collisions, and keeps track of the status of all objects in the game. It is what drives the game. Our game loop consists of a thread that keeps running until the user decides to exit the game. Since our game is quite simple, it basically does the following things in this order:
Once the game loop has completed these steps, we call When moving the ship forward we are actually moving, or translating in 3D terms, all the asteroids and leaving the ship in the same position. Since the positions of every object in our 3D scene is determined by a simple translation using three float values, one for each axis, we need to consider the fact that we might end up with a loss of precision if the values gets large enough. If this were to happen, the 3D object would become distorted and things would start looking quite strange. To avoid this we make sure that the “camera” and the ship are located near the origin, and when moving ahead we simply apply a negative translation to all the other objects in the 3D scene. This is actually the way most 3D games are implemented, regardless if it is a simple 3D game on a mobile device or a huge MMO game on your PC. Collision detection can be very difficult, depending on how good and precise detection is needed. In this game I've used one of the simplest forms of collision detection, axis-aligned bounding box. We create a virtual box around every object and when testing two objects for collision, we use a simple check to see if the boxes intersect. We now have a simple 3D game for Java ME, controlled using a built-in accelerometer. Feel free to download the source code for the game and make your own changes. Hopefully this can give you ideas for your own game or application, using either JSR-239 or JSR-256. The use of the accelerometer in this game is very basic. We're not bothering about the values from the Z-axis at all. I'm certain that there are several other usages of the Mobile Sensor API that I haven't thought of and that are much more interesting than the one described in this article. One idea I'm working on is to use the phone as a game controller for my PC, sending the accelerometer data to my computer over Bluetooth. Could be useful to implement a tennis game. That would also give me a reason for doing more advanced 3D stuff using JOGL. I also believe that there are great opportunities besides games for the Mobile Sensor API. A cordless mouse that could be used during presentations is one idea that pops into my mind. I hope this article has given you some ideas of what is possible, and that you come up with your own cool games or applications using either OpenGL ES or the Mobile Sensor API. Feel free to contact me if you have any questions or would like to share ideas you have.
Erik Hellman has been working with Java for a little more than ten years. After working with Java EE on large telecom systems for Ericsson he switched to Java consultant and did several presentations at various conferences on a wide range of different topics. He is currently working as the team leader on the development of the Java SDK at Sony Ericsson in Lund, Sweden. | |||||||||||||||||||||||||||||
|
| ||||||||||||