本文共 24392 字,大约阅读时间需要 81 分钟。
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!
LAGameView.java(对应LGame-Simple中的GameView)
<textarea cols="50" rows="15" name="code" class="java">package org.loon.framework.android.game;import system.images.LAGraphicsUtils;import android.app.Activity;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Rect;import android.view.SurfaceHolder;import android.view.SurfaceView;/** * * Copyright 2008 - 2009 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loonframework * @author chenpeng * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn * @version 0.1.0 */public class LAGameView extends SurfaceView implements SurfaceHolder.Callback { // SurfaceView继承自View private final static long MAX_INTERVAL = 1000L; final static private int fpsX = 5; final static private int fpsY = 20; private transient boolean start, isFPS, running; private transient int width, height; private transient long maxFrames, curTime, startTime, offsetTime, curFPS, calcInterval; private transient double frameCount; private SurfaceHolder surfaceHolder; private CanvasThread mainLoop; private LAImage screen; private LAGraphics canvasGraphics; private LAHandler handler; private Rect rect; public LAGameView(Activity activity) { this(activity, false); } public LAGameView(Activity activity, boolean isLandscape) { super(activity.getApplicationContext()); LASystem.gc(); LASystem.setupHandler(activity, this); this.handler = LASystem.getSystemHandler(); this.handler.setLandscape(isLandscape); this.setOnCreateContextMenuListener(handler); this.setOnClickListener(handler); this.setOnFocusChangeListener(handler); this.setOnKeyListener(handler); this.setOnLongClickListener(handler); this.setOnTouchListener(handler); this.screen = new LAImage(width = handler.getWidth(), height = handler .getHeight()); this.rect = new Rect(0, 0, width, height); System.out.println("width=" + width + ",height=" + height); this.mainLoop = new CanvasThread(); this.surfaceHolder = getHolder(); this.surfaceHolder.addCallback(this); this.surfaceHolder.setSizeFromLayout(); this.setRunning(true); this.setFPS(LASystem.DEFAULT_MAX_FPS); this.canvasGraphics = screen.getLAGraphics(); this.setFocusable(true); this.setFocusableInTouchMode(true); this.requestFocus(); handler.getActivity().setContentView(this); } public void setScreen(ILAScreen screen) { this.handler.setScreen(screen); } public void destroy() { if (mainLoop != null) { mainLoop = null; } LAGraphicsUtils.destroyImages(); LASystem.gc(); } class CanvasThread extends Thread { public void run() { final LTimerContext timerContext = new LTimerContext(); timerContext.setTimeMillis(startTime = System.currentTimeMillis()); ILAScreen iscreen = null; Canvas canvas = null; do { if (!start) { continue; } iscreen = handler.getScreen(); canvasGraphics.drawClear(); iscreen.createUI(canvasGraphics); curTime = System.currentTimeMillis(); timerContext.setTimeSinceLastUpdate(curTime - timerContext.getTimeMillis()); timerContext.setSleepTimeMillis((offsetTime - timerContext .getTimeSinceLastUpdate()) - timerContext.getOverSleepTimeMillis()); if (timerContext.getSleepTimeMillis() > 0) { try { Thread.sleep(timerContext.getSleepTimeMillis()); } catch (InterruptedException e) { } timerContext.setOverSleepTimeMillis((System .currentTimeMillis() - curTime) - timerContext.getSleepTimeMillis()); } else { timerContext.setOverSleepTimeMillis(0L); } timerContext.setTimeMillis(System.currentTimeMillis()); iscreen.runTimer(timerContext); if (isFPS) { tickFrames(); canvasGraphics.setColor(Color.WHITE); canvasGraphics.setAntiAlias(true); canvasGraphics.drawString(("FPS:" + curFPS).intern(), fpsX, fpsY); canvasGraphics.setAntiAlias(false); } try { canvas = surfaceHolder.lockCanvas(rect); synchronized (surfaceHolder) { canvas.drawBitmap(screen.getBitmap(), 0, 0, null); } } finally { if (canvas != null) { surfaceHolder.unlockCanvasAndPost(canvas); } } if (isFocusable()) { continue; } try { Thread.sleep(30); } catch (InterruptedException e) { } LASystem.gc(10000, 1); } while (running); destroy(); } private void tickFrames() { frameCount++; calcInterval += offsetTime; if (calcInterval >= MAX_INTERVAL) { long timeNow = System.currentTimeMillis(); long realElapsedTime = timeNow - startTime; curFPS = (long) ((frameCount / realElapsedTime) * MAX_INTERVAL); frameCount = 0L; calcInterval = 0L; startTime = timeNow; } } } public Thread getMainLoop() { return mainLoop; } public void mainLoop() { this.startPaint(); } public void mainStop() { this.endPaint(); } public void startPaint() { this.start = true; } public void endPaint() { this.start = false; } public void setFPS(long frames) { this.maxFrames = frames; this.offsetTime = (long) (1.0 / maxFrames * MAX_INTERVAL); } public long getMaxFPS() { return this.maxFrames; } public long getCurrentFPS() { return this.curFPS; } public void setShowFPS(boolean isFPS) { this.isFPS = isFPS; } public boolean isRunning() { return running; } public void setRunning(boolean running) { this.running = running; } public LAHandler getLHandler() { return handler; } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { holder.setFixedSize(width, height); } public void surfaceCreated(SurfaceHolder holder) { mainLoop.start(); } public void surfaceDestroyed(SurfaceHolder holder) { boolean result = true; setRunning(false); while (result) { try { mainLoop.join(); result = false; } catch (InterruptedException e) { } } mainLoop = null; }}</textarea>
LAScreen.java(对应LGame-Simple中的Screen)
<textarea cols="50" rows="15" name="code" class="java">package org.loon.framework.android.game;import system.images.LAGraphicsUtils;import android.view.ContextMenu;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.View;import android.view.ContextMenu.ContextMenuInfo;/** * * Copyright 2008 - 2009 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loonframework * @author chenpeng * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn * @version 0.1.0 */public abstract class LAScreen implements ILAScreen { private ILAHandler handler; private int width, height; public LAScreen() { this.handler = LASystem.getSystemHandler(); this.width = handler.getWidth(); this.height = handler.getHeight(); } public LAImage getLAImage(String fileName){ return LAGraphicsUtils.loadLAImage(fileName); } public synchronized void createUI(LAGraphics g) { draw(g); } public abstract void draw(LAGraphics g); public synchronized void runTimer(LTimerContext timer) { alter(timer); } public abstract void alter(LTimerContext timer); public void setScreen(ILAScreen screen) { this.handler.setScreen(screen); } public int getWidth() { return width; } public int getHeight() { return height; } public abstract boolean onKey(int keyCode, KeyEvent e); public boolean onKey(View v, int keyCode, KeyEvent event) { return onKey(keyCode, event); } public abstract void onFocusChange(boolean hasFocus); public void onFocusChange(View v, boolean hasFocus) { onFocusChange(hasFocus); } public abstract boolean onLongClick(); public boolean onLongClick(View v) { return onLongClick(); } public abstract boolean onClick(); public void onClick(View v) { onClick(); } public abstract void onCreateContextMenu(ContextMenu menu, ContextMenuInfo menuInfo); public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { onCreateContextMenu(menu, menuInfo); } public abstract boolean onTouch(MotionEvent e); public boolean onTouch(View v, MotionEvent event) { return onTouch(event); }}</textarea>
Main.java(启动类)
package org.loon.framework.android.game;import android.app.Activity;import android.os.Bundle;/** * * Copyright 2008 - 2009 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loonframework * @author chenpeng * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn * @version 0.1.0 */public class Main extends Activity { private LAGameView view; public void onCreate(Bundle icicle) { super.onCreate(icicle); view = new LAGameView(this); view.setScreen(new ScreenTest()); view.setShowFPS(true); view.mainLoop(); } protected void onPause() { if (view != null) { view.setRunning(false); } super.onPause(); } protected void onStop() { if (view != null) { view.setRunning(false); } super.onStop(); }}
ScreenTest.java(测试类)
<textarea cols="50" rows="15" name="code" class="java">package org.loon.framework.android.game;import android.view.ContextMenu;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.ContextMenu.ContextMenuInfo;/** * * Copyright 2008 - 2009 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loonframework * @author chenpeng * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn * @version 0.1.0 */public class ScreenTest extends LAScreen { private LAImage image; private int tx = 0, ty = 0; public ScreenTest() { image = getLAImage("image.png"); } public void alter(LTimerContext timer) { } public void draw(LAGraphics g) { g.drawImage(image, 55, 55); g.drawString("Touch X=" + ty, 70, 70); g.drawString("Touch Y=" + tx, 70, 90); } public boolean onClick() { return false; } public void onCreateContextMenu(ContextMenu menu, ContextMenuInfo menuInfo) { } public void onFocusChange(boolean hasFocus) { } /** * 手机按键(对应键盘) */ public boolean onKey(int keyCode, KeyEvent e) { return false; } public boolean onLongClick() { return false; } /** * 手机触摸屏(对应鼠标) */ public boolean onTouch(MotionEvent e) { this.tx = (int) e.getX(); this.ty = (int) e.getY(); return false; }}</textarea>
横屏效果:
纵屏效果:
源码下载地址:
可以看到,此示例虽为LGame-Simple的简写,但最基础的功能已经实现,我们仅需设定一个继承自LAScreen的游戏屏幕,就可以同LGame-Simple中一样,分模块开发游戏,并且随意更换当前游戏模块及更替按键设定了。
实际上如果您愿意,即使偶不出Android版的LGame-Simple,将其自行移植到Android上的难度也绝对比您所想象的要小得多(当然,Android版偶是肯定会出的^.^)
————————————天下大势,—————————————
事实上Android与标准Java应用近乎一致,唯独在多线程方面有些“恶心”,比如View中的invalidate()函数只能在Handler中做类似递归的handleMessage与sleep相互调用,Thread.currentThread().getContextClassLoader()也无法获得jar内部资源,感觉上就像Google要强制你学习它那套samples应用,而不能更改一样。把LGame-Simple移植到Android上比我想象的要简单,刚刚又试验了一下,除了有关图形接口与线程的部分,其余直接copy过来就可以用,甚至连代码都不必改,所以12月出LGame-Simple的Android版肯定没问题。(事实上,如果偶现在开始什么都不干只写这个的话,大约5天左右就可以搞定……可惜不现实……)另外偶可能尝试开发一个函数移植器,看看能不能做到PC与Android上的LGame-Simple游戏间自动代码转换,目前看来可行性蛮高的。分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!