Mobile
 

Building an Advanced Java Game on Symbian OS (part 2) - Using the Mobile Media API & Using the Scalable 2D Vector Graphics API

1/3/2012 4:03:24 PM

4. Using the Mobile Media API (JSR-135)

Many games do this simply because studies have shown that music helps create a more immersive experience. By interspersing MIDI sequences with periods of silence we can change the 'feel' of the game in a subtle manner which helps maintain player interest.

To do this we use timers, some basic parameters and a random-number generator. We also need to detect when the active sequence has finished by implementing the PlayerListener interface. Whenever the current background music stops we wait for a random (bounded) interval of time and then start the next sequence:

// from PlayerListener
public void playerUpdate(Player player, String event, Object eventData){
try{
if(event.equals(PlayerListener.END_OF_MEDIA)){
if(player == backgroundPlayer1){
activeBackgroundPlayer = backgroundPlayer2;
}
else if(player == backgroundPlayer2){
activeBackgroundPlayer = backgroundPlayer3;
}
else if(player == backgroundPlayer3){
activeBackgroundPlayer = backgroundPlayer1;
}
startBackgroundFXTimer();
}
}
catch(Exception e){
e.printStackTrace();
}
}

private void startBackgroundFXTimer(){
stopBackgroundFXTimer();
TimerTask task = new TimerTask(){
public void run(){
playBackgroundMusic();
}
};
backgroundTimer = new Timer();
backgroundTimer.schedule(task, musicDelay);
musicDelay = Utilities.random(BACKGROUND_WAIT_MIN,BACKGROUND_WAIT_MAX);
}


5. Using the Scalable 2D Vector Graphics API (JSR-226)

As explained earlier, this game uses a menu system based on the Scalable Vector Graphics API, when it is detected on the device. Figure 8.6a shows the results of a very simple linear menu using scaling and transparency. The best way to get started using JSR-226 is to read [Nokia 2006e] and [Powers 2005].

An SVG image is simply an XML document containing a set of drawing instructions which allows an image to be created using high-level instructions. You can say, for example, 'draw a circle radius 5 at point 2,10'. The main benefits you get by using SVG images instead of traditional raster images is their scalability, ease of manipulation and the fact that they compress extremely well in a JAR since they are just a text document.

The full SVG specification defines support for a wide range of features but not all of these are yet supported on mobile phones. Instead phones support a subset of the specification called SVG-Tiny also referred to as SVG-T. The current version of SVG-T is 1.1 and this is the version currently shipped on Symbian OS 9.x devices. To determine from Java ME what version of SVG-T your phone supports, you can query the system property as follows:

String svgVersion = System.getProperty("microedition.m2g.version");
boolean useSVG = svgVersion.equals("1.1");

In order to read the XML, the SVG-T specification defines a micro-DOM that the implementation of the JSR must provide. This is a small XML parser specifically designed to parse SVG elements. Note that as part of the SVG-T implementation, it should not be considered an XML parser for general use.

There are two ways to create SVG content: SVG images can be created programmatically through a series of API calls but it is far more common to load and manipulate SVG images prepared using a third-party graphics tool such as Adobe Illustrator. If you don't have access to this, a common open-source, free alternative for SVG content creation is Inkscape.


Before you attempt to load or display an SVG image from a MIDlet, you need to convert it to SVG-T format. The S60 3rd Edition SDKs come with an SVG to SVG-T conversion tool which you can use for this. The installer can be found in the \S60Tools\ subdirectory of your SDK root. There are some incompatibilities with support for the 'text' element on the Symbian OS implementation at this stage so it is best to convert any text to a path (a series of line segments and arcs) in Illustrator or Inkscape (see Figure 5) before converting it to SVG-T. The resulting SVG file will be quite a bit bigger, depending on how much text it contains but for simple menus like ours this is not an issue – remember that we don't need to care too much about JAR size on Symbian OS.

Rendering to screen is done with an instance of the ScalableGraphics class. Within our paint() method, we simply bind our Graphics context to our scalable context, directly render SVG images to our canvas and then release our context. By obtaining a handle to the root element of an SVGImage instance we can also directly scale, rotate and translate the image itself as well as change its properties such as its CSS style attribute which defines fills, strokes, color, and so on.

The following code snippets are taken from the BasicSVGMenu-Screen class which forms the base class for all the SVG menus in the game. It is surprising how easy it is to get good effects with very little code.

Figure 5. Converting text objects to paths with Inkscape

public abstract class BasicSVGMenuScreen extends BasicScreen {
protected ScalableGraphics sg;
protected static final float BASE_SCALE = 2.0f;
protected static final float ACTIVE_SCALE = 2.5f;

protected static final float BASE_TRANSPARENCY = 0.70f;
protected static final float ACTIVE_TRANSPARENCY = 0.90f;
...
// constructor
...
sg = ScalableGraphics.createInstance();
sg.setRenderingQuality(ScalableGraphics.RENDERING_QUALITY_HIGH);
sg.setTransparency(BASE_TRANSPARENCY);
...
public void paint(Graphics g){
Graphics context = g;
sg.bindTarget(context);
sg.setTransparency(BASE_TRANSPARENCY); // more transparent
...
// now render the active item
sg.setTransparency(ACTIVE_TRANSPARENCY); // more opaque
sg.render(x,activeY,menuOptions[selectedIndex].getImage());
sg.releaseTarget();
...
}

// load SVG content from the JAR file
protected void setImage(String imageName, boolean active){
InputStream svgStream = null;
try{
svgStream = getResourceAsStream(imageName);
image = (SVGImage) (SVGImage.createImage(svgStream, null));


image.setViewportWidth(getWidth());
image.setViewportHeight(getHeight());
setActive(active);
}
catch(Exception e){
e.printStackTrace();
}
finally{
if(svgStream != null){
try{
svgStream.close();
}
catch(IOException ioe){} // ignore
}
}
}

public void setActive(boolean active){
SVGSVGElement svgDoc = (SVGSVGElement)
image.getDocument().getDocumentElement();
if(active)
svgDoc.setCurrentScale(ACTIVE_SCALE); // bigger
else
svgDoc.setCurrentScale(BASE_SCALE); // normal
}

 
Others
 
- Building an Advanced Java Game on Symbian OS (part 1)
- jQuery 1.3 : Simultaneous versus queued effects (part 2) - Working with multiple sets of elements & Callbacks
- jQuery 1.3 : Simultaneous versus queued effects (part 1) - Working with a single set of elements
- iPhone 3D Programming : Crisper Text with Distance Fields (part 3) - Implementing Outline, Glow, and Shadow Effects
- iPhone 3D Programming : Crisper Text with Distance Fields (part 2) - Smoothing and Derivatives
- iPhone 3D Programming : Crisper Text with Distance Fields (part 1) - Generating Distance Fields with Python
- Mapping Well-Known Patterns onto Symbian OS : Singleton
- Mapping Well-Known Patterns onto Symbian OS : Model–View–Controller
- The Anatomy of a Mobile Site : STYLING WITH CSS - CSS Considerations for Mobile & Optimizing CSS
- The Anatomy of a Mobile Site : INVOKING OTHER DEVICE CAPABILITIES & THE STATE OF JAVASCRIPT
- iPad Development : The Dual-Action Color Popover (part 3) - Serving Two Masters
- iPad Development : The Dual-Action Color Popover (part 2) - Hooking Up the Grid
- iPad Development : The Dual-Action Color Popover (part 1) - Creating a Simple Color Grid
- XNA Game Studio 3.0 : Creating Fake 3-D - Creating Shadows Using Transparent Colors
- Android Application Development : ViewGroups (part 2) - ListView, ListActivity, ScrollView & TabHost
- Android Application Development : ViewGroups (part 1) - Gallery and GridView
- Java ME on Symbian OS : MIDP 2.0 Game API Core Concepts
- Java ME on Symbian OS : Building a Simple MIDP Game
- jQuery 1.3 : Compound effects & Creating custom animations
- jQuery 1.3 : Effects and speed
 
 
Most View
 
- SQL Server 2012 : Query Optimization (part 1) - Parallel Plans, Algebrizer Trees
- Windows Phone 8 : Exploring the Execution Model (part 4) - Restoring Transient State, Saving Persistent State
- Windows 7 : Programming Drivers for the Kernel Mode Driver Framework (part 2) - KMDF Driver Structure and Concepts - Object Creation
- Installing Exchange 2013 : Deploying an Exchange 2013 server (part 1) - Running Setup
- Active Directory 2008 : Configuring Active Directory Certificate Services (part 2) - Enrolling User and Computer Certificates
- SQL Server 2012 : The XML Data Type (part 1)
- Overview of Oauth in Sharepoint 2013 : Application Authorization - On-Premises App Authentication with S2S
- Windows 7 : Windows Media Player - Taking Your Music and Video on the Go (part 3) - Sharing Media Throughout Your Home
- Microsoft Lync Server 2013 : Lync Online and Hybrid Deployments - AD FS Deployment for SSO (part 2)
- Windows Server 2008 R2 Remote Desktop Services : Installing and Configuring Remote Desktop Services (part 3)
 
 
Top 10
 
- Sharepoint 2013 : Developing Integrated Apps for Office and Sharepoint Solutions - The New App Model for Office
- Overview of Oauth in Sharepoint 2013 : Application Authorization - On-Premises App Authentication with S2S
- Overview of Oauth in Sharepoint 2013 : Application Authorization - Requesting Permissions Dynamically
- Microsoft Excel 2010 : Working with Graphics - Inserting a Diagram,Inserting an Object
- Microsoft Excel 2010 : Working with Graphics - Inserting WordArt, Using Smart Art in Excel
- Microsoft Excel 2010 : Working with Graphics - Using AutoShapes
- Overview of Oauth in Sharepoint 2013 : Application Authentication (part 2) - Managing Tokens in Your Application
- Overview of Oauth in Sharepoint 2013 : Application Authentication (part 1) - Using TokenHelper
- Overview of Oauth in Sharepoint 2013 : Creating and Managing Application Identities
- Overview of Oauth in Sharepoint 2013 : Introduction to OAuth