三 开始移植
小白找到Android中对应的J2ME相关的替代类和替代方法后,开始噼里啪啦的改代码了。没过多久,首个俄罗斯方块算是移植成功。当他开始移植下一款游戏时,发现又要重复的改那些代码……
“可不可以减少代码的改动呢?”小白问自己。“可否用Android的相关代码构造一些和J2me里功能类似的代码呢?”
原则:尽量少改动J2ME项目的代码。用Android中对应的类改写成J2ME中的方法和类,减少以后移植的工作量,甚至实现无缝移植。
“或许我可以构造一个名为MIDlet实为Activity的类,这样J2me中的入口类就不用改动了”
用Activity类改装的MIDlet类:
public abstract class MIDlet extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startApp();
}
public abstract void destroyApp(boolean unconditional);
public String getAppProperty(String key) {
return null;
}
public abstract void startApp();
public void notifyDestroyed() {
}
public void notifyPaused() {}
public void pauseApp() {}
public void platformRequest(String URL) {}
public void resumeRequest() {}
}
MIDlet类我们解决了,接下来就是非常重要的Canvas类了。
J2me里的Canvas类相当于Android体系中的SurfaceView类,都是负责绘制显示界面的,游戏的大循环一半也在这两个类里实现,也就是都会实现Runnable类,更新逻辑和更新界面都在此类的大循环中处理。
Graphics类在J2me里负责绘图和排版样式等。
我们可以用Android里的Canvas类和Paint类共同组合一个Android里的Graphics类,如Graphics类的构造函数可这样定义:
public Graphics(Bitmap bitmap) {
this.bitmap = bitmap;
this.canvas = new Canvas(bitmap);
this.canvas.clipRect(0, 0, bitmap.getWidth(), bitmap.getHeight());
this.canvas.save(Canvas.CLIP_SAVE_FLAG);
this.paint = new Paint();
this.clip = canvas.getClipBounds();
}
Graphics里可以设置居中方式,在Android体系里我们用Paint类来实现相同的效果,例如:
public void setAlign(int align)
{
if(LEFT == align
||(Graphics.LEFT | Graphics.TOP) == align
||(Graphics.LEFT | Graphics.BOTTOM) == align)
{
paint.setTextAlign(Align.LEFT);
}else if(HCENTER == align
||(Graphics.HCENTER|Graphics.TOP) == align)
{
paint.setTextAlign(Align.CENTER);
}else if(RIGHT == align
||(Graphics.RIGHT | Graphics.TOP) == align)
{
paint.setTextAlign(Align.RIGHT);
}
}
所有的绘制方法也同样沿用J2me中的方法名,用Android体系的代码完成方法体,达到无缝移植。以绘制、填充矩形为例:
public void fillArc(int x,int y,int width,int height, int startAngle,int arcAngle) {
paint.setStyle(Style.FILL);
canvas.drawArc(new RectF(x,y,width,height), startAngle, arcAngle, true, paint);
}
public void drawArc(int x,int y,int width,int height, int startAngle,int arcAngle) {
paint.setStyle(Style.STROKE);
canvas.drawArc(new RectF(x,y,width,height), startAngle, arcAngle, true, paint);
}
再来说说按键处理:
大体思路就是获取Android中的按键消息后,修改封装一下,转换成J2me的键值和事件,然后传递给显示层。
先定义出J2me中的键值:
public class GameCanvas extends Screen {
public static final int UP = 1;
public static final int DOWN = 6;
public static final int LEFT = 2;
public static final int RIGHT = 5;
public static final int FIRE = 8;
public static final int GAME_A = 9;
public static final int GAME_B = 10;
public static final int GAME_C = 11;
public static final int GAME_D = 12;
public static final int KEY_NUM0 = 48;
public static final int KEY_NUM1 = 49;
public static final int KEY_NUM2 = 50;
public static final int KEY_NUM3 = 51;
public static final int KEY_NUM4 = 52;
public static final int KEY_NUM5 = 53;
public static final int KEY_NUM6 = 54;
public static final int KEY_NUM7 = 55;
public static final int KEY_NUM8 = 56;
public static final int KEY_NUM9 = 57;
public static final int KEY_STAR = 42;
public static final int KEY_POUND = 35;
}
经过中间一个转换方法:
public int keyCode4J2me = 0;
public int keyAction4J2me = 0;
public void changeToJ2meKey(int keyCode, KeyEvent e) {
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
keyCode4J2me = GameCanvas.DOWN;
keyAction4J2me = GameCanvas.DOWN;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
keyCode4J2me = GameCanvas.LEFT;
keyAction4J2me = GameCanvas.LEFT;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
keyCode4J2me = GameCanvas.RIGHT;
keyAction4J2me = GameCanvas.RIGHT;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
keyCode4J2me = GameCanvas.FIRE;
keyAction4J2me = GameCanvas.FIRE;
} else if (keyCode == KeyEvent.KEYCODE_0) {
keyCode4J2me = GameCanvas.KEY_NUM0;
} else if (keyCode == KeyEvent.KEYCODE_1) {
keyCode4J2me = GameCanvas.KEY_NUM1;
} else if (keyCode == KeyEvent.KEYCODE_2) {
keyCode4J2me = GameCanvas.KEY_NUM2;
}
}
转换成J2me的按键处理体系,转去调用J2me原生的keyReleased方法:
public boolean onKeyUp(int keyCode, KeyEvent e) {
changeToJ2meKey (keyCode,e);
keyReleased(keyActual);
return true;
}
其他的字体类、颜色类、等等都可以按此方法无缝移植。
Font字体类用Android中的FontMetrics重写。
而Graphics类中的setColor(int rgb)以及setColor(int r,int g,int b)方法,则可以修改Graphics类中Paint的颜色。如:
public void setColor(int r,int g,int b) {
int argb = (0xff000000)+(r<<16)+(g<<8)+b;
paint.setColor(argb);
}
小白心想: “或许我还可以用Android中的Canvas类改写一个J2me中的Graphics类,用Android中的Bitmap改装一个J2me中的Image类……然后把J2me游戏开发包javax.microedition.lcdui.game包里的GameCanvas类,Layer类,LayerManager类,Sprite类,TiledLayer类直接拿来用。嗯嗯,几乎不用改动原来的J2me代码了。第一个移植任务花费了一个周,以后一天就能移植一个小游戏啦。哈哈哈。”
小白找到Android中对应的J2ME相关的替代类和替代方法后,开始噼里啪啦的改代码了。没过多久,首个俄罗斯方块算是移植成功。当他开始移植下一款游戏时,发现又要重复的改那些代码……
“可不可以减少代码的改动呢?”小白问自己。“可否用Android的相关代码构造一些和J2me里功能类似的代码呢?”
原则:尽量少改动J2ME项目的代码。用Android中对应的类改写成J2ME中的方法和类,减少以后移植的工作量,甚至实现无缝移植。
“或许我可以构造一个名为MIDlet实为Activity的类,这样J2me中的入口类就不用改动了”
用Activity类改装的MIDlet类:
public abstract class MIDlet extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startApp();
}
public abstract void destroyApp(boolean unconditional);
public String getAppProperty(String key) {
return null;
}
public abstract void startApp();
public void notifyDestroyed() {
}
public void notifyPaused() {}
public void pauseApp() {}
public void platformRequest(String URL) {}
public void resumeRequest() {}
}
MIDlet类我们解决了,接下来就是非常重要的Canvas类了。
J2me里的Canvas类相当于Android体系中的SurfaceView类,都是负责绘制显示界面的,游戏的大循环一半也在这两个类里实现,也就是都会实现Runnable类,更新逻辑和更新界面都在此类的大循环中处理。
Graphics类在J2me里负责绘图和排版样式等。
我们可以用Android里的Canvas类和Paint类共同组合一个Android里的Graphics类,如Graphics类的构造函数可这样定义:
public Graphics(Bitmap bitmap) {
this.bitmap = bitmap;
this.canvas = new Canvas(bitmap);
this.canvas.clipRect(0, 0, bitmap.getWidth(), bitmap.getHeight());
this.canvas.save(Canvas.CLIP_SAVE_FLAG);
this.paint = new Paint();
this.clip = canvas.getClipBounds();
}
Graphics里可以设置居中方式,在Android体系里我们用Paint类来实现相同的效果,例如:
public void setAlign(int align)
{
if(LEFT == align
||(Graphics.LEFT | Graphics.TOP) == align
||(Graphics.LEFT | Graphics.BOTTOM) == align)
{
paint.setTextAlign(Align.LEFT);
}else if(HCENTER == align
||(Graphics.HCENTER|Graphics.TOP) == align)
{
paint.setTextAlign(Align.CENTER);
}else if(RIGHT == align
||(Graphics.RIGHT | Graphics.TOP) == align)
{
paint.setTextAlign(Align.RIGHT);
}
}
所有的绘制方法也同样沿用J2me中的方法名,用Android体系的代码完成方法体,达到无缝移植。以绘制、填充矩形为例:
public void fillArc(int x,int y,int width,int height, int startAngle,int arcAngle) {
paint.setStyle(Style.FILL);
canvas.drawArc(new RectF(x,y,width,height), startAngle, arcAngle, true, paint);
}
public void drawArc(int x,int y,int width,int height, int startAngle,int arcAngle) {
paint.setStyle(Style.STROKE);
canvas.drawArc(new RectF(x,y,width,height), startAngle, arcAngle, true, paint);
}
再来说说按键处理:
大体思路就是获取Android中的按键消息后,修改封装一下,转换成J2me的键值和事件,然后传递给显示层。
先定义出J2me中的键值:
public class GameCanvas extends Screen {
public static final int UP = 1;
public static final int DOWN = 6;
public static final int LEFT = 2;
public static final int RIGHT = 5;
public static final int FIRE = 8;
public static final int GAME_A = 9;
public static final int GAME_B = 10;
public static final int GAME_C = 11;
public static final int GAME_D = 12;
public static final int KEY_NUM0 = 48;
public static final int KEY_NUM1 = 49;
public static final int KEY_NUM2 = 50;
public static final int KEY_NUM3 = 51;
public static final int KEY_NUM4 = 52;
public static final int KEY_NUM5 = 53;
public static final int KEY_NUM6 = 54;
public static final int KEY_NUM7 = 55;
public static final int KEY_NUM8 = 56;
public static final int KEY_NUM9 = 57;
public static final int KEY_STAR = 42;
public static final int KEY_POUND = 35;
}
经过中间一个转换方法:
public int keyCode4J2me = 0;
public int keyAction4J2me = 0;
public void changeToJ2meKey(int keyCode, KeyEvent e) {
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
keyCode4J2me = GameCanvas.DOWN;
keyAction4J2me = GameCanvas.DOWN;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
keyCode4J2me = GameCanvas.LEFT;
keyAction4J2me = GameCanvas.LEFT;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
keyCode4J2me = GameCanvas.RIGHT;
keyAction4J2me = GameCanvas.RIGHT;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
keyCode4J2me = GameCanvas.FIRE;
keyAction4J2me = GameCanvas.FIRE;
} else if (keyCode == KeyEvent.KEYCODE_0) {
keyCode4J2me = GameCanvas.KEY_NUM0;
} else if (keyCode == KeyEvent.KEYCODE_1) {
keyCode4J2me = GameCanvas.KEY_NUM1;
} else if (keyCode == KeyEvent.KEYCODE_2) {
keyCode4J2me = GameCanvas.KEY_NUM2;
}
}
转换成J2me的按键处理体系,转去调用J2me原生的keyReleased方法:
public boolean onKeyUp(int keyCode, KeyEvent e) {
changeToJ2meKey (keyCode,e);
keyReleased(keyActual);
return true;
}
其他的字体类、颜色类、等等都可以按此方法无缝移植。
Font字体类用Android中的FontMetrics重写。
而Graphics类中的setColor(int rgb)以及setColor(int r,int g,int b)方法,则可以修改Graphics类中Paint的颜色。如:
public void setColor(int r,int g,int b) {
int argb = (0xff000000)+(r<<16)+(g<<8)+b;
paint.setColor(argb);
}
小白心想: “或许我还可以用Android中的Canvas类改写一个J2me中的Graphics类,用Android中的Bitmap改装一个J2me中的Image类……然后把J2me游戏开发包javax.microedition.lcdui.game包里的GameCanvas类,Layer类,LayerManager类,Sprite类,TiledLayer类直接拿来用。嗯嗯,几乎不用改动原来的J2me代码了。第一个移植任务花费了一个周,以后一天就能移植一个小游戏啦。哈哈哈。”
来源:oschina
链接:https://my.oschina.net/u/16/blog/16226