零打碎敲学Android(一)—用什么来替代Graphics

来源:互联网 发布:linux smb 访问权限 编辑:程序博客网 时间:2024/05/09 10:48

http://blog.csdn.net/cping1982/archive/2009/10/16/4683949.aspx

 

这几天开着代理研究android(主要是长期以来 developer.android.com 被墙撞……),总算初步掌握了android的图形处理方式,准备在Blog上写一些经验性的总结。


一、Android Virtual Device仿真界面对应快捷


view plaincopy to clipboardprint?
模拟项  设备键     PC键  
Home    HOME  
Menu    (left softkey)    F2 or Page-up button  
Star    (right softkey)    Shift-F2 or Page Down  
Back    ESC  
Call/dial button    F3  
Hangup/end call button    F4  
Search    F5  
Power button    F7  
Audio volume up button    KEYPAD_PLUS, Ctrl-5  
Audio volume down button    KEYPAD_MINUS, Ctrl-F6  
Camera button    Ctrl-KEYPAD_5, Ctrl-F3  
Switch to previous layout orientation (for example, portrait, landscape)    KEYPAD_7, F11  
Switch to next layout orientation (for example, portrait, landscape)    KEYPAD_9, F12  
Toggle cell networking on/off    F8  
Toggle code profiling    F9 (only with -trace startup option)  
Toggle fullscreen mode    Alt-Enter  
Toggle trackball mode    F6  
Enter trackball mode temporarily (while key is pressed)    Delete  
DPad left/up/right/down    KEYPAD_4/8/6/2  
DPad center click    KEYPAD_5  
Onion alpha increase/decrease    KEYPAD_MULTIPLY(*) / KEYPAD_DIVIDE(/) 
模拟项  设备键     PC键
Home    HOME
Menu    (left softkey)    F2 or Page-up button
Star    (right softkey)    Shift-F2 or Page Down
Back    ESC
Call/dial button    F3
Hangup/end call button    F4
Search    F5
Power button    F7
Audio volume up button    KEYPAD_PLUS, Ctrl-5
Audio volume down button    KEYPAD_MINUS, Ctrl-F6
Camera button    Ctrl-KEYPAD_5, Ctrl-F3
Switch to previous layout orientation (for example, portrait, landscape)    KEYPAD_7, F11
Switch to next layout orientation (for example, portrait, landscape)    KEYPAD_9, F12
Toggle cell networking on/off    F8
Toggle code profiling    F9 (only with -trace startup option)
Toggle fullscreen mode    Alt-Enter
Toggle trackball mode    F6
Enter trackball mode temporarily (while key is pressed)    Delete
DPad left/up/right/down    KEYPAD_4/8/6/2
DPad center click    KEYPAD_5
Onion alpha increase/decrease    KEYPAD_MULTIPLY(*) / KEYPAD_DIVIDE(/)


二、要想在View中绘制图形,至少需要用到以下三者

1、Bitmap

Android中使用Bitmap承载图像资源,其默认支持4种图像格式(调用方式,Bitmap.Config.XXXX),分别为ALPHA8、RGB565、ARGB4444、ARGB8888,单就显示效果而言以ARGB8888效果最佳,ALPHA8效果最差,当然占用资源与之相反。

不过Bitmap本身的运算量非常小,其具体操作大量依赖于native,如下所示:

   view plaincopy to clipboardprint?
private static native Bitmap nativeCreate(int[] colors, int offset,  
                                              int stride, int width, int height,  
                                            int nativeConfig, boolean mutable);  
    private static native Bitmap nativeCopy(int srcBitmap, int nativeConfig,  
                                            boolean isMutable);  
    private static native void nativeDestructor(int nativeBitmap);  
    private static native void nativeRecycle(int nativeBitmap);  
    private static native boolean nativeCompress(int nativeBitmap, int format,  
                                            int quality, OutputStream stream,  
                                            byte[] tempStorage);  
    private static native void nativeErase(int nativeBitmap, int color);  
    private static native int nativeWidth(int nativeBitmap);  
    private static native int nativeHeight(int nativeBitmap);  
    private static native int nativeRowBytes(int nativeBitmap);  
    private static native int nativeConfig(int nativeBitmap);  
    private static native boolean nativeHasAlpha(int nativeBitmap);  
     
    private static native int nativeGetPixel(int nativeBitmap, int x, int y);  
    private static native void nativeGetPixels(int nativeBitmap, int[] pixels,  
                                               int offset, int stride, int x,  
                                               int y, int width, int height);  
     
    private static native void nativeSetPixel(int nativeBitmap, int x, int y,  
                                              int color);  
    private static native void nativeSetPixels(int nativeBitmap, int[] colors,  
                                               int offset, int stride, int x,  
                                               int y, int width, int height);  
    private static native void nativeCopyPixelsToBuffer(int nativeBitmap,  
                                                        Buffer dst);  
    private static native void nativeCopyPixelsFromBuffer(int nb, Buffer src);  
    private static native Bitmap nativeCreateFromParcel(Parcel p);  
    // returns true on success  
    private static native boolean nativeWriteToParcel(int nativeBitmap,  
                                                      boolean isMutable,  
                                                      Parcel p);  
    // returns a new bitmap built from the native bitmap's alpha, and the paint  
    private static native Bitmap nativeExtractAlpha(int nativeBitmap,  
                                                    int nativePaint,  
                                                    int[] offsetXY); 
private static native Bitmap nativeCreate(int[] colors, int offset,
                                              int stride, int width, int height,
                                            int nativeConfig, boolean mutable);
    private static native Bitmap nativeCopy(int srcBitmap, int nativeConfig,
                                            boolean isMutable);
    private static native void nativeDestructor(int nativeBitmap);
    private static native void nativeRecycle(int nativeBitmap);
    private static native boolean nativeCompress(int nativeBitmap, int format,
                                            int quality, OutputStream stream,
                                            byte[] tempStorage);
    private static native void nativeErase(int nativeBitmap, int color);
    private static native int nativeWidth(int nativeBitmap);
    private static native int nativeHeight(int nativeBitmap);
    private static native int nativeRowBytes(int nativeBitmap);
    private static native int nativeConfig(int nativeBitmap);
    private static native boolean nativeHasAlpha(int nativeBitmap);
  
    private static native int nativeGetPixel(int nativeBitmap, int x, int y);
    private static native void nativeGetPixels(int nativeBitmap, int[] pixels,
                                               int offset, int stride, int x,
                                               int y, int width, int height);
  
    private static native void nativeSetPixel(int nativeBitmap, int x, int y,
                                              int color);
    private static native void nativeSetPixels(int nativeBitmap, int[] colors,
                                               int offset, int stride, int x,
                                               int y, int width, int height);
    private static native void nativeCopyPixelsToBuffer(int nativeBitmap,
                                                        Buffer dst);
    private static native void nativeCopyPixelsFromBuffer(int nb, Buffer src);
    private static native Bitmap nativeCreateFromParcel(Parcel p);
    // returns true on success
    private static native boolean nativeWriteToParcel(int nativeBitmap,
                                                      boolean isMutable,
                                                      Parcel p);
    // returns a new bitmap built from the native bitmap's alpha, and the paint
    private static native Bitmap nativeExtractAlpha(int nativeBitmap,
                                                    int nativePaint,
                                                    int[] offsetXY);

2、Canvas

Android中使用Canvas对应标准Java应用中的Graphics,其具体操作与Graphics类似,但实际功能却较Graphics为少,需要同Paint配合使用。

与Bitmap近似,Canvas主要实现依赖于OpenGL ES,其本身的运算量非常之小,Canvas本地接口如下所示:


    view plaincopy to clipboardprint?
private static native int initRaster(int nativeBitmapOrZero);  
    private static native int initGL();  
    private static native void native_setBitmap(int nativeCanvas, int bitmap);  
    private static native void nativeSetViewport(int nCanvas, int w, int h);  
    private static native int native_saveLayer(int nativeCanvas, RectF bounds,  
                                               int paint, int layerFlags);  
    private static native int native_saveLayer(int nativeCanvas, float l,  
                                               float t, float r, float b,  
                                               int paint, int layerFlags);  
    private static native int native_saveLayerAlpha(int nativeCanvas,  
                                                    RectF bounds, int alpha,  
                                                    int layerFlags);  
    private static native int native_saveLayerAlpha(int nativeCanvas, float l,  
                                                    float t, float r, float b,  
                                                    int alpha, int layerFlags);  
    private static native void native_concat(int nCanvas, int nMatrix);  
    private static native void native_setMatrix(int nCanvas, int nMatrix);  
    private static native boolean native_clipRect(int nCanvas,  
                                                  float left, float top,  
                                                  float right, float bottom,  
                                                  int regionOp);  
    private static native boolean native_clipPath(int nativeCanvas,  
                                                  int nativePath,  
                                                  int regionOp);  
    private static native boolean native_clipRegion(int nativeCanvas,  
                                                    int nativeRegion,  
                                                    int regionOp);  
    private static native void nativeSetDrawFilter(int nativeCanvas,  
                                                   int nativeFilter);  
    private static native boolean native_getClipBounds(int nativeCanvas,  
                                                       Rect bounds);  
    private static native void native_getCTM(int canvas, int matrix);  
    private static native boolean native_quickReject(int nativeCanvas,  
                                                     RectF rect,  
                                                     int native_edgeType);  
    private static native boolean native_quickReject(int nativeCanvas,  
                                                     int path,  
                                                     int native_edgeType);  
    private static native boolean native_quickReject(int nativeCanvas,  
                                                     float left, float top,  
                                                     float right, float bottom,  
                                                     int native_edgeType);  
    private static native void native_drawRGB(int nativeCanvas, int r, int g,  
                                              int b);  
    private static native void native_drawARGB(int nativeCanvas, int a, int r,  
                                               int g, int b);  
    private static native void native_drawColor(int nativeCanvas, int color);  
    private static native void native_drawColor(int nativeCanvas, int color,  
                                                int mode);  
    private static native void native_drawPaint(int nativeCanvas, int paint);  
    private static native void native_drawLine(int nativeCanvas, float startX,  
                                               float startY, float stopX,  
                                               float stopY, int paint);  
    private static native void native_drawRect(int nativeCanvas, RectF rect,  
                                               int paint);  
    private static native void native_drawRect(int nativeCanvas, float left,  
                                               float top, float right,  
                                               float bottom, int paint);  
    private static native void native_drawOval(int nativeCanvas, RectF oval,  
                                               int paint);  
    private static native void native_drawCircle(int nativeCanvas, float cx,  
                                                 float cy, float radius,  
                                                 int paint);  
    private static native void native_drawArc(int nativeCanvas, RectF oval,  
                                              float startAngle, float sweep,  
                                              boolean useCenter, int paint);  
    private static native void native_drawRoundRect(int nativeCanvas,  
                                                    RectF rect, float rx,  
                                                    float ry, int paint);  
    private static native void native_drawPath(int nativeCanvas, int path,  
                                               int paint);  
    private native void native_drawBitmap(int nativeCanvas, int bitmap,  
                                                 float left, float top,  
                                                 int nativePaintOrZero, boolean autoScale,  
                                                 float densityScale);  
    private native void native_drawBitmap(int nativeCanvas, int bitmap,  
                                                 Rect src, RectF dst,  
                                                 int nativePaintOrZero);  
    private static native void native_drawBitmap(int nativeCanvas, int bitmap,  
                                                 Rect src, Rect dst,  
                                                 int nativePaintOrZero);  
    private static native void native_drawBitmap(int nativeCanvas, int[] colors,  
                                                int offset, int stride, float x,  
                                                 float y, int width, int height,  
                                                 boolean hasAlpha,  
                                                 int nativePaintOrZero);  
    private static native void nativeDrawBitmapMatrix(int nCanvas, int nBitmap,  
                                                      int nMatrix, int nPaint);  
    private static native void nativeDrawBitmapMesh(int nCanvas, int nBitmap,  
                                                    int meshWidth, int meshHeight,  
                                                    float[] verts, int vertOffset,  
                                                    int[] colors, int colorOffset, int nPaint);  
    private static native void nativeDrawVertices(int nCanvas, int mode, int n,  
                   float[] verts, int vertOffset, float[] texs, int texOffset,  
                   int[] colors, int colorOffset, short[] indices,  
                   int indexOffset, int indexCount, int nPaint);  
     
    private static native void native_drawText(int nativeCanvas, char[] text,  
                                               int index, int count, float x,  
                                               float y, int paint);  
    private static native void native_drawText(int nativeCanvas, String text,  
                                               int start, int end, float x,  
                                               float y, int paint);  
    private static native void native_drawPosText(int nativeCanvas,  
                                                  char[] text, int index,  
                                                  int count, float[] pos,  
                                                  int paint);  
    private static native void native_drawPosText(int nativeCanvas,  
                                                  String text, float[] pos,  
                                                  int paint);  
    private static native void native_drawTextOnPath(int nativeCanvas,  
                                                     char[] text, int index,  
                                                     int count, int path,  
                                                     float hOffset,  
                                                     float vOffset, int paint);  
    private static native void native_drawTextOnPath(int nativeCanvas,  
                                                     String text, int path,  
                                                     float hOffset,  
                                                     float vOffset, int paint);  
    private static native void native_drawPicture(int nativeCanvas,  
                                                  int nativePicture);  
    private static native void finalizer(int nativeCanvas); 
private static native int initRaster(int nativeBitmapOrZero);
    private static native int initGL();
    private static native void native_setBitmap(int nativeCanvas, int bitmap);
    private static native void nativeSetViewport(int nCanvas, int w, int h);
    private static native int native_saveLayer(int nativeCanvas, RectF bounds,
                                               int paint, int layerFlags);
    private static native int native_saveLayer(int nativeCanvas, float l,
                                               float t, float r, float b,
                                               int paint, int layerFlags);
    private static native int native_saveLayerAlpha(int nativeCanvas,
                                                    RectF bounds, int alpha,
                                                    int layerFlags);
    private static native int native_saveLayerAlpha(int nativeCanvas, float l,
                                                    float t, float r, float b,
                                                    int alpha, int layerFlags);
    private static native void native_concat(int nCanvas, int nMatrix);
    private static native void native_setMatrix(int nCanvas, int nMatrix);
    private static native boolean native_clipRect(int nCanvas,
                                                  float left, float top,
                                                  float right, float bottom,
                                                  int regionOp);
    private static native boolean native_clipPath(int nativeCanvas,
                                                  int nativePath,
                                                  int regionOp);
    private static native boolean native_clipRegion(int nativeCanvas,
                                                    int nativeRegion,
                                                    int regionOp);
    private static native void nativeSetDrawFilter(int nativeCanvas,
                                                   int nativeFilter);
    private static native boolean native_getClipBounds(int nativeCanvas,
                                                       Rect bounds);
    private static native void native_getCTM(int canvas, int matrix);
    private static native boolean native_quickReject(int nativeCanvas,
                                                     RectF rect,
                                                     int native_edgeType);
    private static native boolean native_quickReject(int nativeCanvas,
                                                     int path,
                                                     int native_edgeType);
    private static native boolean native_quickReject(int nativeCanvas,
                                                     float left, float top,
                                                     float right, float bottom,
                                                     int native_edgeType);
    private static native void native_drawRGB(int nativeCanvas, int r, int g,
                                              int b);
    private static native void native_drawARGB(int nativeCanvas, int a, int r,
                                               int g, int b);
    private static native void native_drawColor(int nativeCanvas, int color);
    private static native void native_drawColor(int nativeCanvas, int color,
                                                int mode);
    private static native void native_drawPaint(int nativeCanvas, int paint);
    private static native void native_drawLine(int nativeCanvas, float startX,
                                               float startY, float stopX,
                                               float stopY, int paint);
    private static native void native_drawRect(int nativeCanvas, RectF rect,
                                               int paint);
    private static native void native_drawRect(int nativeCanvas, float left,
                                               float top, float right,
                                               float bottom, int paint);
    private static native void native_drawOval(int nativeCanvas, RectF oval,
                                               int paint);
    private static native void native_drawCircle(int nativeCanvas, float cx,
                                                 float cy, float radius,
                                                 int paint);
    private static native void native_drawArc(int nativeCanvas, RectF oval,
                                              float startAngle, float sweep,
                                              boolean useCenter, int paint);
    private static native void native_drawRoundRect(int nativeCanvas,
                                                    RectF rect, float rx,
                                                    float ry, int paint);
    private static native void native_drawPath(int nativeCanvas, int path,
                                               int paint);
    private native void native_drawBitmap(int nativeCanvas, int bitmap,
                                                 float left, float top,
                                                 int nativePaintOrZero, boolean autoScale,
                                                 float densityScale);
    private native void native_drawBitmap(int nativeCanvas, int bitmap,
                                                 Rect src, RectF dst,
                                                 int nativePaintOrZero);
    private static native void native_drawBitmap(int nativeCanvas, int bitmap,
                                                 Rect src, Rect dst,
                                                 int nativePaintOrZero);
    private static native void native_drawBitmap(int nativeCanvas, int[] colors,
                                                int offset, int stride, float x,
                                                 float y, int width, int height,
                                                 boolean hasAlpha,
                                                 int nativePaintOrZero);
    private static native void nativeDrawBitmapMatrix(int nCanvas, int nBitmap,
                                                      int nMatrix, int nPaint);
    private static native void nativeDrawBitmapMesh(int nCanvas, int nBitmap,
                                                    int meshWidth, int meshHeight,
                                                    float[] verts, int vertOffset,
                                                    int[] colors, int colorOffset, int nPaint);
    private static native void nativeDrawVertices(int nCanvas, int mode, int n,
                   float[] verts, int vertOffset, float[] texs, int texOffset,
                   int[] colors, int colorOffset, short[] indices,
                   int indexOffset, int indexCount, int nPaint);
  
    private static native void native_drawText(int nativeCanvas, char[] text,
                                               int index, int count, float x,
                                               float y, int paint);
    private static native void native_drawText(int nativeCanvas, String text,
                                               int start, int end, float x,
                                               float y, int paint);
    private static native void native_drawPosText(int nativeCanvas,
                                                  char[] text, int index,
                                                  int count, float[] pos,
                                                  int paint);
    private static native void native_drawPosText(int nativeCanvas,
                                                  String text, float[] pos,
                                                  int paint);
    private static native void native_drawTextOnPath(int nativeCanvas,
                                                     char[] text, int index,
                                                     int count, int path,
                                                     float hOffset,
                                                     float vOffset, int paint);
    private static native void native_drawTextOnPath(int nativeCanvas,
                                                     String text, int path,
                                                     float hOffset,
                                                     float vOffset, int paint);
    private static native void native_drawPicture(int nativeCanvas,
                                                  int nativePicture);
    private static native void finalizer(int nativeCanvas);

3、Paint

用以设定图像的绘制方式,可以同Canvas一道看作Graphics功能的拆分,只有当Canvas与Paint共同使用时,才可能实现Graphics的大部分功能(并非全部)。

Paint依旧大量依赖于本地接口,具体函数如下:

    view plaincopy to clipboardprint?
private static native int native_init();  
    private static native int native_initWithPaint(int paint);  
    private static native void native_reset(int native_object);  
    private static native void native_set(int native_dst, int native_src);  
    private static native int native_getStyle(int native_object);  
    private static native void native_setStyle(int native_object, int style);  
    private static native int native_getStrokeCap(int native_object);  
    private static native void native_setStrokeCap(int native_object, int cap);  
    private static native int native_getStrokeJoin(int native_object);  
    private static native void native_setStrokeJoin(int native_object,  
                                                    int join);  
    private static native boolean native_getFillPath(int native_object,  
                                                     int src, int dst);  
    private static native int native_setShader(int native_object, int shader);  
    private static native int native_setColorFilter(int native_object,  
                                                    int filter);  
    private static native int native_setXfermode(int native_object,  
                                                 int xfermode);  
    private static native int native_setPathEffect(int native_object,  
                                                   int effect);  
    private static native int native_setMaskFilter(int native_object,  
                                                   int maskfilter);  
    private static native int native_setTypeface(int native_object,  
                                                 int typeface);  
    private static native int native_setRasterizer(int native_object,  
                                                   int rasterizer);  
    private static native int native_getTextAlign(int native_object);  
    private static native void native_setTextAlign(int native_object,  
                                                   int align);  
    private static native float native_getFontMetrics(int native_paint,  
                                                      FontMetrics metrics);  
    private static native int native_getTextWidths(int native_object,  
                            char[] text, int index, int count, float[] widths);  
    private static native int native_getTextWidths(int native_object,  
                            String text, int start, int end, float[] widths);  
    private static native void native_getTextPath(int native_object,  
                char[] text, int index, int count, float x, float y, int path);  
    private static native void native_getTextPath(int native_object,  
                String text, int start, int end, float x, float y, int path);  
    private static native void nativeGetStringBounds(int nativePaint,  
                                String text, int start, int end, Rect bounds);  
    private static native void nativeGetCharArrayBounds(int nativePaint,  
                                char[] text, int index, int count, Rect bounds);  
    private static native void finalizer(int nativePaint);  
private static native int native_init();
    private static native int native_initWithPaint(int paint);
    private static native void native_reset(int native_object);
    private static native void native_set(int native_dst, int native_src);
    private static native int native_getStyle(int native_object);
    private static native void native_setStyle(int native_object, int style);
    private static native int native_getStrokeCap(int native_object);
    private static native void native_setStrokeCap(int native_object, int cap);
    private static native int native_getStrokeJoin(int native_object);
    private static native void native_setStrokeJoin(int native_object,
                                                    int join);
    private static native boolean native_getFillPath(int native_object,
                                                     int src, int dst);
    private static native int native_setShader(int native_object, int shader);
    private static native int native_setColorFilter(int native_object,
                                                    int filter);
    private static native int native_setXfermode(int native_object,
                                                 int xfermode);
    private static native int native_setPathEffect(int native_object,
                                                   int effect);
    private static native int native_setMaskFilter(int native_object,
                                                   int maskfilter);
    private static native int native_setTypeface(int native_object,
                                                 int typeface);
    private static native int native_setRasterizer(int native_object,
                                                   int rasterizer);
    private static native int native_getTextAlign(int native_object);
    private static native void native_setTextAlign(int native_object,
                                                   int align);
    private static native float native_getFontMetrics(int native_paint,
                                                      FontMetrics metrics);
    private static native int native_getTextWidths(int native_object,
                            char[] text, int index, int count, float[] widths);
    private static native int native_getTextWidths(int native_object,
                            String text, int start, int end, float[] widths);
    private static native void native_getTextPath(int native_object,
                char[] text, int index, int count, float x, float y, int path);
    private static native void native_getTextPath(int native_object,
                String text, int start, int end, float x, float y, int path);
    private static native void nativeGetStringBounds(int nativePaint,
                                String text, int start, int end, Rect bounds);
    private static native void nativeGetCharArrayBounds(int nativePaint,
                                char[] text, int index, int count, Rect bounds);
    private static native void finalizer(int nativePaint); 


Android绘图的基本示例:  canvas.drawBitmap(bitmap, 0, 0, paint) // canvas代表画布 bitmap作为图像资源 paint决定绘图方式

3、Android的窗口构成,即Activity + View = Form。

Android以Activity类作为窗体容器,以View(或SurfaceView等)绘制所有的按钮及界面,以AndroidManifest.xml配置相关的初始化资源,Android图形应用的一切通过它们衍生开来。

由于Android的线程安全机制并不等同于标准Java应用,invalidate()不能循环绘制View(偶实际试验了,丢到Thread里就死|||),所以View的图形绘制需要通过Handler处理,它将在函数内实现了一个类似于递归的循环线程,结构如下(具体实现请见Android提供的snake示例):

sendMessageDelayed->handleMessage->handleMessage 再次呼叫 sendMessageDelayed->handleMessage 被呼叫->循环

这种线程结构虽然简单且高效,但是很多常见的线程手段却无法在其中实现,因此只适合简单的应用(比如计时器,定时绘图等),复杂的线程结构则需要SurfaceView。

SurfaceView是View的子类,它继承自View。与只能使用Handler方式循环绘制图像的View不同,SurfaceView通过调用一对lockCanvas()和unlockCanvasAndPost()进行绘图,具体实现可见Google提供的LunarLander示例。

根据鄙人实测,View的Handler方式较SurfaceView的lockCanvas()与unlockCanvasAndPost()方式FPS为高,惟独可控性太差,本人推荐在简单应用使用View,在复杂应用使用SurfaceView。

另外xml中屏幕纵、横核定项如下:

screenOrientation="portrait" 纵向屏幕

screenOrientation="landscape" 横向屏幕

与之对应的代码设定方式是在Activity中setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)与setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)

PS:Android中所有图形设备都基于OpenGL ES,默认存在Z-Buffer,绝对不会出现Java桌面应用中的闪烁问题,算是一项进步。

下面我给出一个简单的Android绘图示例,也是LGame-Simple在Android中的最初原型代码,我们可以看到Android与标准Java桌面应用的差异实际上是极为细微的。


源码下载地址:http://code.google.com/p/loon-simple/downloads/list


PS:此用例中所有[LA]开头Java文件为Android下专用,否则皆为LGame-Simple通用。

LAGameView.java(对应LGame-Simple中的GameView)

view plaincopy to clipboardprint?
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;  
    }  

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;
 }
}
 

LAScreen.java(对应LGame-Simple中的Screen)

view plaincopy to clipboardprint?
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);  
    }  

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);
 }
}
 


Main.java(启动类)

view plaincopy to clipboardprint?
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();  
    }  

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(测试类)

view plaincopy to clipboardprint?
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;  
    }  

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;
 }
}
 

横屏效果:

 

纵屏效果:

 


源码下载地址:http://code.google.com/p/loon-simple/downloads/list

可以看到,此示例虽为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游戏间自动代码转换,目前看来可行性蛮高的。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cping1982/archive/2009/10/16/4683949.aspx

原创粉丝点击