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
 
- Windows 8 : Network and Sharing Center (part 2)
- Windows 8 : Creating a Windows Network - Installing a Wireless Network (part 1) - Wireless Network Setup Choices
- SQL Server 2012 : Delivering Manageability and Performance (part 1) - POLICY-BASED MANAGEMENT - Enterprise Policy Evaluation
- Microsoft Visio 2010 : Adding Structure to Your Diagrams - Finding Containers and Lists in Visio (part 2) - Wireframes
- SQL Server 2012 : Query Optimization (part 2) - Understanding Statistics
- Using the Windows 8 Interface : Navigating the Start Screen (part 3) - Navigating the Start Screen with a Touch Interface
- Microsoft Exchange Server 2013 : Role-based access control - Scopes
- SQL Server 2012 : Delivering Manageability and Performance (part 5) - POLICY-BASED MANAGEMENT - Object Naming Conventions
- Windows 8 : Customizing the Start Screen (part 4) - Pinning a Website to the Start Screen,Displaying the Administrative Tools on the Start Screen
- Sharepoint 2013 : Customizing a SharePoint Site - Modify a Content Type
 
 
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