Android千好萬好,唯獨模擬器不是太好,在不更換舊有硬體的前提下,使用Android模擬器通常會遭遇效率問題,況且在logcat下面調試,也始終不如開發案頭遊戲時那麼直觀。有沒有什麼辦法,能夠解決這一問題呢?
其實很容易做到。
Android首先是一個精簡的Linux平台,其次才是一個手機系統,Java在PC上可以做到的事情,Android不但可以做到,而且能以近乎一致的手段做到。事實上,如果有人故意通過封裝抹殺Android與PC上Java應用差異性的話,任何Java遊戲,都可以在很少更改代碼(或者完全不更改代碼)的情況下移植到Android之上。
比如,筆者下面提供的這個拼圖遊戲樣本,就可以在幾乎不改變程式結構(部分相關類需要替換,不過可以利用正則自動完成)的前提下,運行在Android上。
PC版源碼(架構為LGame-Simple-0.2.0):
package org.loon.game.simple.test;<br />import java.awt.Graphics;<br />import java.awt.Graphics2D;<br />import java.awt.Image;<br />import java.awt.event.KeyEvent;<br />import java.awt.event.MouseEvent;<br />import org.loon.framework.game.simple.GameScene;<br />import org.loon.framework.game.simple.core.Deploy;<br />import org.loon.framework.game.simple.core.Screen;<br />import org.loon.framework.game.simple.utils.GraphicsUtils;<br />/**<br /> *<br /> * Copyright 2008<br /> *<br /> * Licensed under the Apache License, Version 2.0 (the "License");<br /> * you may not use this file except in compliance with the License.<br /> * You may obtain a copy of the License at<br /> *<br /> * http://www.apache.org/licenses/LICENSE-2.0<br /> *<br /> * Unless required by applicable law or agreed to in writing, software<br /> * distributed under the License is distributed on an "AS IS" BASIS,<br /> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,<br /> * either express or implied. See the License for the specific language<br /> * governing permissions and limitations under the License.<br /> *<br /> * @project loonframework<br /> * @author chenpeng<br /> * @email:ceponline@yahoo.com.cn<br /> * @version 0.1<br /> */<br />public class ScreenTest1 extends Screen {<br />private Image imageBack, tmp_imageBack, imageForward;<br />private Graphics tmp_graphics;<br />private int blocks[];<br />private boolean isEvent;<br />private int count, rs, cs, row, col, width, height;<br />public ScreenTest1(String file1, String file2, int row, int col) {<br />this.col = col;<br />this.row = row;<br />this.imageBack = GraphicsUtils.loadImage(file1);<br />this.width = imageBack.getWidth(null);<br />this.height = imageBack.getHeight(null);<br />this.rs = width / row;<br />this.cs = height / col;<br />this.tmp_imageBack = GraphicsUtils<br />.createImage(width, height + cs, true);<br />this.tmp_graphics = tmp_imageBack.getGraphics();<br />this.count = col * row;<br />this.blocks = new int[count];<br />this.imageForward = GraphicsUtils.loadImage(file2);<br />for (int i = 0; i < count; i++) {<br />blocks[i] = i;<br />}<br />rndBlocks();<br />}<br />/**<br /> * 複製拼圖中圖片塊<br /> *<br /> * @param x1<br /> * @param y1<br /> * @param x2<br /> * @param y2<br /> */<br />private void copy(int x1, int y1, int x2, int y2) {<br />tmp_graphics.copyArea(x1 * rs, y1 * cs, rs, cs, (x2 - x1) * rs,<br />(y2 - y1) * cs);<br />}<br />/**<br /> * 隨機產生拼圖內容<br /> *<br /> */<br />private void rndBlocks() {<br />tmp_graphics.drawImage(imageBack, 0, 0, null);<br />for (int i = 0; i < (count * row); i++) {<br />int x1 = (int) ((double) row * Math.random());<br />int y1 = (int) ((double) col * Math.random());<br />int x2 = (int) ((double) row * Math.random());<br />int y2 = (int) ((double) col * Math.random());<br />copy(x1, y1, 0, col);<br />copy(x2, y2, x1, y1);<br />copy(0, col, x2, y2);<br />int j1 = blocks[y1 * row + x1];<br />blocks[y1 * row + x1] = blocks[y2 * row + x2];<br />blocks[y2 * row + x2] = j1;<br />}<br />}<br />/**<br /> * 點擊滑鼠<br /> */<br />public void leftClick(MouseEvent e) {<br />if (isEvent) {<br />return;<br />}<br />int x = e.getX() / rs;<br />int y = e.getY() / cs;<br />copy(0, 0, 0, col);<br />copy(x, y, 0, 0);<br />copy(0, col, x, y);<br />int no = blocks[0];<br />blocks[0] = blocks[y * row + x];<br />blocks[y * row + x] = no;<br />int index;<br />for (index = 0; index < count; index++) {<br />if (blocks[index] != index) {<br />break;<br />}<br />}<br />if (index == count) {<br />isEvent = true;<br />}<br />return;<br />}<br />public void draw(Graphics2D g) {<br />if (!isEvent) {<br />g.drawImage(tmp_imageBack, 0, 0, null);<br />for (int i = 0; i < row; i++) {<br />for (int j = 0; j < col; j++)<br />g.drawRect(i * rs, j * cs, rs, cs);<br />}<br />}<br />if (isEvent && imageForward != null) {<br />g.drawImage(imageBack, 0, 0, null);<br />g.drawImage(imageForward, 0, 0, null);<br />tmp_graphics.dispose();<br />}<br />}<br />public boolean isEvent() {<br />return isEvent;<br />}<br />public void setEvent(boolean isEvent) {<br />this.isEvent = isEvent;<br />}<br />public void middleClick(MouseEvent e) {<br />}<br />public void onKey(KeyEvent e) {<br />}<br />public void onKeyUp(KeyEvent e) {<br />}<br />public void rightClick(MouseEvent e) {<br />}<br />public static void main(String[] args) {<br />GameScene frame = new GameScene("拼圖", 320, 480);<br />Deploy deploy = frame.getDeploy();<br />deploy.setScreen(new ScreenTest1("images/backimage1.jpg",<br />"images/over.png", 4, 4));<br />deploy.setShowFPS(true);<br />deploy.setLogo(false);<br />deploy.setFPS(100);<br />deploy.mainLoop();<br />frame.showFrame();<br />}<br />}<br />
Android版源碼(架構為LAGame-Simple-prototype):
樣本源碼:http://code.google.com/p/loon-simple/downloads/list
package org.loon.framework.android.game;<br />import android.view.KeyEvent;<br />import android.view.MotionEvent;<br />/**<br /> *<br /> * Copyright 2008 - 2009<br /> *<br /> * Licensed under the Apache License, Version 2.0 (the "License"); you may not<br /> * use this file except in compliance with the License. You may obtain a copy of<br /> * the License at<br /> *<br /> * http://www.apache.org/licenses/LICENSE-2.0<br /> *<br /> * Unless required by applicable law or agreed to in writing, software<br /> * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT<br /> * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the<br /> * License for the specific language governing permissions and limitations under<br /> * the License.<br /> *<br /> * @project loonframework<br /> * @author chenpeng<br /> * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn<br /> * @version 0.1.0<br /> */<br />public class ScreenTest1 extends LAScreen {<br />private LAImage imageBack, tmp_imageBack, imageForward;<br />private LAGraphics tmp_graphics;<br />private int blocks[];<br />private boolean isEvent;<br />private int count, rs, cs, row, col, width, height;<br />public ScreenTest1(String file1, String file2, int row, int col) {<br />this.col = col;<br />this.row = row;<br />this.imageBack = getLAImage(file1);<br />this.width = imageBack.getWidth();<br />this.height = imageBack.getHeight();<br />this.rs = width / row;<br />this.cs = height / col;<br />this.tmp_imageBack = new LAImage(width, height + cs);<br />this.tmp_graphics = tmp_imageBack.getLAGraphics();<br />this.count = col * row;<br />this.blocks = new int[count];<br />this.imageForward = getLAImage(file2);<br />for (int i = 0; i < count; i++) {<br />blocks[i] = i;<br />}<br />rndBlocks();<br />}<br />/**<br /> * 複製拼圖中圖片塊<br /> *<br /> * @param x1<br /> * @param y1<br /> * @param x2<br /> * @param y2<br /> */<br />private void copy(int x1, int y1, int x2, int y2) {<br />tmp_graphics.copyArea(x1 * rs, y1 * cs, rs, cs, (x2 - x1) * rs,<br />(y2 - y1) * cs);<br />}<br />/**<br /> * 隨機產生拼圖內容<br /> *<br /> */<br />private void rndBlocks() {<br />tmp_graphics.drawImage(imageBack, 0, 0);<br />for (int i = 0; i < (count * row); i++) {<br />int x1 = (int) ((double) row * Math.random());<br />int y1 = (int) ((double) col * Math.random());<br />int x2 = (int) ((double) row * Math.random());<br />int y2 = (int) ((double) col * Math.random());<br />copy(x1, y1, 0, col);<br />copy(x2, y2, x1, y1);<br />copy(0, col, x2, y2);<br />int j1 = blocks[y1 * row + x1];<br />blocks[y1 * row + x1] = blocks[y2 * row + x2];<br />blocks[y2 * row + x2] = j1;<br />}<br />}<br />/**<br /> * 點擊觸控螢幕<br /> */<br />public boolean onTouchDown(MotionEvent e) {<br />if (isEvent) {<br />return isEvent;<br />}<br />int x = (int) (e.getX() / rs);<br />int y = (int) (e.getY() / cs);<br />copy(0, 0, 0, col);<br />copy(x, y, 0, 0);<br />copy(0, col, x, y);<br />int no = blocks[0];<br />blocks[0] = blocks[y * row + x];<br />blocks[y * row + x] = no;<br />int index;<br />for (index = 0; index < count; index++) {<br />if (blocks[index] != index) {<br />break;<br />}<br />}<br />if (index == count) {<br />isEvent = true;<br />}<br />return isEvent;<br />}<br />/**<br /> * 繪製拼圖<br /> */<br />public void draw(LAGraphics g) {<br />if (!isEvent) {<br />g.drawImage(tmp_imageBack, 0, 0);<br />for (int i = 0; i < row; i++) {<br />for (int j = 0; j < col; j++)<br />g.drawRect(i * rs, j * cs, rs, cs);<br />}<br />}<br />if (isEvent && imageForward != null) {<br />g.drawImage(imageBack, 0, 0);<br />g.drawImage(imageForward, 0, 0);<br />tmp_graphics.dispose();<br />}<br />}<br />public boolean isEvent() {<br />return isEvent;<br />}<br />public void setEvent(boolean isEvent) {<br />this.isEvent = isEvent;<br />}<br />public boolean onKeyDown(int keyCode, KeyEvent e) {<br />return false;<br />}<br />public boolean onKeyUp(int keyCode, KeyEvent e) {<br />return false;<br />}<br />public boolean onTouchMove(MotionEvent e) {<br />return false;<br />}<br />public boolean onTouchUp(MotionEvent e) {<br />return false;<br />}<br />}<br />
package org.loon.framework.android.game;<br />import android.app.Activity;<br />import android.os.Bundle;<br />/**<br /> *<br /> * Copyright 2008 - 2009<br /> *<br /> * Licensed under the Apache License, Version 2.0 (the "License"); you may not<br /> * use this file except in compliance with the License. You may obtain a copy of<br /> * the License at<br /> *<br /> * http://www.apache.org/licenses/LICENSE-2.0<br /> *<br /> * Unless required by applicable law or agreed to in writing, software<br /> * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT<br /> * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the<br /> * License for the specific language governing permissions and limitations under<br /> * the License.<br /> *<br /> * @project loonframework<br /> * @author chenpeng<br /> * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn<br /> * @version 0.1.0<br /> */<br />public class Main extends Activity {<br />private LAGameView view;<br />public void onCreate(Bundle icicle) {<br />super.onCreate(icicle);<br />view = new LAGameView(this);<br />view.setScreen(new ScreenTest1("backimage1.jpg",<br />"over.png", 4, 4));<br />view.setShowFPS(true);<br />view.mainLoop();<br />}<br />protected void onPause() {<br />if (view != null) {<br />view.setRunning(false);<br />}<br />super.onPause();<br />}<br />protected void onStop() {<br />if (view != null) {<br />view.setRunning(false);<br />}<br />super.onStop();<br />}<br />}
樣本源碼:http://code.google.com/p/loon-simple/downloads/list
Android遊戲與Java案頭遊戲在本質上不存在任何區別,邏輯實現更可以完全一致。通過樣本我們看到,把一個以LGame-Simple架構開發的Java案頭遊戲移植到Android上居然是如此簡單。
事實上,未來的Android版LGame-Simple,函數實現將與PC版保持一致,對於差異性代碼,筆者也將提供相互轉換的協助工具輔助。
如果您正在以LGame-Simple開發Java遊戲,那麼恭喜您,至多到今年12月底,它也將可以同時運行在Android上了。