| Reply | « Previous Thread | Next Thread » |
|
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: 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
...
}
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);
}
}
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);
}
}
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! |
|
bartekn wrote:
>I designed LightCanvas class which has a reference to a Canvas >(the real Canvas which is used to draw on). LightCanvas has >blah blah blah blah blah blah blah blah blah blah to extend >LightCanvas. This approach is just too heavyweight for mobile phones - It is a much better solution to use preprocessing on your source files to include phone specific stuff. I use Antenna (http://antenna.sourceforge.net) which quite frankly rocks and so can do: //#ifdef NOKIA class GameCanvas extends FullCanvas //#else class GameCanvas extends Canvas //#endif { } This also avoids having to have multiple copies of the code in the same midlet to cater for different phones.... |
|
Thanks for pointing out a quite nice tool, Antenna. I wish I had knew about that tool earlier.
However, I don't agree with you that using my solution is THAT heavy weight. I want my game to run on different phones without providing different versions of JARs (of course it's not possible for all phones, especially for color and B/W devices). As a matter of fact both solutions have advantages and disadvantages ;-) |
|
To save you some time: I wrote something similar a while ago, for exactly the same reason. Anyway, it worked quite well on the emulators... then I tried it on real phones - most models failed to install the midlet because, I suspect, it referenced non-existent classes. If the midlet had any class that called or extended the Siemens API, for example, it wouldn't install on a Nokia or Motorola handset. I decided in the end just to go with different builds (I use CodeWarrior, so it's quite easy to substitute classes tailored for different phones).
Carl. |
|
Hmmm... strange indeed. I thought that class loaders are supposed to load classes if, and only if, a class is needed, not all of them at once.
There is one thing that must be pointed out here - you can't use directly a device specific class, this class should be looked up by name i.e. Class.forName(...). BTW: I found a bug in my framework, now it works fine. I tested it on Nokia phones and various emulators... I haven't tested it on real phones other than Nokia, but I'll do it soon. |
|
I suspect there's some verifying and checking going off when the midlet is installed. Motorola phones, IIRC, do a whole load of stuff to the contents of the jar (like separating the classes and data) on install (which explains why it takes so long).
Carl. |
|
Quote:
shmoove |
|
@shmoove - where did you read it? I'm really interested in it.
|
|
I don't remember exactly where, but I remember it was during my baby steps in J2ME, so it was probably one of the documents linked from sun's site.
I'll check through my documentation and see if I can find it. shmoove |
| Reply | « Previous Thread | Next Thread » |
| Thread Tools | Search this Thread |
|---|---|