三 開始移植 小白找到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代碼了。第一個移植任務花費了一個周,之後一天就能移植一個小遊戲啦。哈哈哈。」