Hi all!
I've been developing a Java game for the MIDP platform for a while. When I was about to port my game to other phones I didn't want to create different versions for different phones. Instead, I tried to use a generic solution and I designed a few classes.
A typical game must have at least one class that extends Canvas (or FullCanvas in case of Nokia's phones). Therefore if porting to another device a class extending device's specific class must be refactoried.
I designed LightCanvas class which has a reference to a Canvas (the real Canvas which is used to draw on). LightCanvas has similiar methods to Canvas class but it doesn't extend it. Every class in my game that extended Canvas or FullCanvas has been refactoried to extend LightCanvas.
I designed an abstract factory (MIDletPlatform) with createCanvas(LightCanvas lightCanvas) method that creates a device specific class e.g. FullCanvas and wraps the lightCanvas into it.
The LightCanvas class:
A method from MIDletPlatform class:Code:public abstract class LightCanvas { private Canvas canvas; protected LightCanvas() { canvas = MIDletPlatform.getInstance().createCanvas(this); } public abstract void paint(Graphics g); public void keyPressed(int keyCode) { //do nothing } public void keyReleased(int keyCode) { //do nothing } public void repaint() { canvas.repaint(); } public void serviceRepaints() { canvas.serviceRepaints(); } //other methods that delegate to canvas methods ... }
Here is one of HeavyCanvases: NokiaCanvas that just delegates to a light canvas.Code:public Canvas createCanvas(LightCanvas canvas) { try { HeavyCanvas heavyCanvas = (HeavyCanvas)Class.forName("pl.ganimedes.midp.device.nokia.NokiaCanvas").newInstance(); heavyCanvas.setCanvas(canvas); return (Canvas)heavyCanvas; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Cannot create heavy canvas: " + e); } }
Here is a sample code:Code:public class NokiaCanvas extends FullCanvas implements HeavyCanvas { private LightCanvas canvas; public void setCanvas(LightCanvas canvas) { this.canvas = canvas; } protected void paint(Graphics g) { canvas.paint(g); } protected void keyPressed(int keyCode) { canvas.keyPressed(keyCode); } protected void keyReleased(int keyCode) { canvas.keyReleased(keyCode); } }
And everything works fine except one thing: when I call repaint() and then serviceRepaints() within my MyLightCanvas the screen isn't refreshed even though LightCanvas delegates to the real canvas. I wonder why it doesn't work... I tried on different emulators and none of them worked as expected. The only emulator that works is mine ;-) Maybe it's because the serviceRepaints is declared in Canvas as final. Or maybe the devices have a bug...Code:class MyLightCanvas extends LightCanvas { public void paint(Graphics g) { //a code that draws something ... } ... } aDisplay.setCurrent(MIDletPlatform.getInstance().createCanvas(new MyLightCanvas()));
Has anyone encountered a similar problem?
I'm looking forward to your feedback! Thanks in advance!


Reply With Quote

