Best practises of graphics

Developing game loops

The MIDP API specification states that the call to paint() occurs asynchronously of the call to repaint(). The repaint() method will not block waiting for paint() to finish. The paint() method will either be called after the caller of repaint() returns to the implementation (if the caller is a callback) or on another thread entirely.

MIDlets cannot assume that paint() is always called immediately after repaint() call. Several repaint() calls can be combined into one paint() call.

Recommendations

If possible, use GameCanvas, since it has better control on game painting . There is no performance difference in Canvas and GameCanvas.

In normal Canvas, to cause paint() call, use serviceRepaints() right after repaint() call.

How to consume less CPU power

The MIDP API specification states that to synchronize with its paint() routine, applications can use either Display.callSerially() or serviceRepaints(), or explicit synchronization can be coded into their paint() routine. Games use a lot of CPU time if the paint() loop is tight, causing the method to loop and waste CPU time. A game loop that continuously calls repaint() without any synchronizing with paint() causes performance issues. The thread gets as much execution time as, for example the UI thread.

Recommendations
  • Avoid using callSerially() and serviceRepaints() together.

  • Use wait() and notify() instead of Thread.sleep().

  • Avoid using Timers and TimerTasks, they are heavy operations.

Background handling

It is possible to design an application so that it releases its resources when the application goes to the background, and activates them when the application is in foreground. For Canvas applications, use hideNotify() and showNotify(). For other Displayables, pauseApp() and startApp() are used. You can do this with the JAD attribute Nokia-MIDlet-Background-Event. Normally events that go to the background causing a call to pauseApp() method do not occur during MIDlet runtime. Use the attribute to enable multiple pauseApp() / startApp() calls during MIDlet runtime session.

The application needs to handle the release of its resources itself when pauseApp() is called, call to pauseApp() does not pause any operations automatically. Normally if Canvas is the current Displayable, it gets hideNotify().

Recommendations

Stop all activities (stop the game loop) and release resources when application goes to the background. Use a tool for memory management, EnergyProfiler, to observe that MIDlet is not consuming resources in the background.

  • MMAPI: audio/video playing can be stopped (AOB to check: if attribute is not used, MMAPI playing continues normally in background, audio and video plays normally but it is not displayed, sound can be heard)

  • Networking: network connections can be closed by MIDlet (use of Timer).

  • Location API: applications can set LocationListener to null to shut down the GPS.

  • UI operations: GameCanvas allows drawing on the background. If GameCanvas is used, it is recommended not to draw anything.

Multi-threaded applications

If an application is multi-threaded, it is the application developer's responsibility to ensure that threads are synchronized properly to get desired behavior, that is, the calls are sequenced as needed. It the application does not follow basic thread synchronization, the behavior is not guaranteed.

Accessing a given MMAPI object (DataSource , Player and Controls) from different threads, behavior depends on the thread scheduling. For consistent behavior (when accessing a given MMAPI object simultaneously from different threads) it is recommended to use Java synchronization mechanism to synchronize access to MMAPI object. When working on games that use MMAPI video playback:

  • Resizing video content before playing it if video has been produced in other than mobile device, usable for non-hardware accelerated products

  • Recommended bit rates depend on resolution.

  • Accessing MMAPI objects (DataSource , Player, Controls) simultaneously from more than one thread

Documentation and tool links