4-Displaying Images with Android

來源:互聯網
上載者:User
文章目錄
  • 移動圖形

在開始實際的遊戲迴圈之前,讓我們先顯示一些圖片,使得我們能夠得到一些尺寸的概念(不太清楚這句什麼意思)。如果還沒有看到線程更新螢幕的內容,強烈推薦先看一下(上篇部落格)

在android上面顯示圖片非常的簡單

為了讓問題簡單,我們在左上方顯示圖形,我們需要 一個圖片,我更喜歡png,我建立了一個名為droid_1.png的檔案,大小是20*20 像素,你可以選擇自己喜歡的工具,我用gimp或者ps

為了讓程式可以使用,把圖片拷貝到/res/drawable-mdpi目錄下,我選擇mdpi,它的意思是平常螢幕 中等密度,關於螢幕類型,可以求助 android文檔

修改MainGamePanel檔案,修改onDraw函數

1 protected void onDraw(Canvas canvas) {  2     canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.droid_1), 10, 10, null);  3 } 

drawbitmap把droid_1畫到了座標10,10位置上

我們傳遞圖片id給程式的資源管理部分以獲得bitmap,當我們拷貝png到資來源目錄時候,外掛程式會自動在R.java裡面產生標識

也影響了線程的一部分code,檢查下面的run函數

01 public void run() {  02         Canvas canvas;  03         Log.d(TAG, "Starting game loop");  04         while (running) {  05             canvas = null;  06             // try locking the canvas for exclusive pixel editing on the surface  07             try {  08                 canvas = this.surfaceHolder.lockCanvas();  09                 synchronized (surfaceHolder) {  10                     // update game state  11                     // draws the canvas on the panel  12                     this.gamePanel.onDraw(canvas);  13                 }  14             } finally {  15                 // in case of an exception the surface is not left in  16                 // an inconsistent state  17                 if (canvas != null) {  18                     surfaceHolder.unlockCanvasAndPost(canvas);  19                 }  20             }   // end finally  21         }  22     } 

第二行 我們聲明了我們要畫圖形的畫布,畫布是surface的圖形要畫的地方,也是我們編輯像素的地方,8行我們得到了畫布,12行我們觸發了onDraw函數,並把畫布傳遞過去,注意這是同步塊,別人是無法使用的。

這個函數很簡單和基礎,每次執行的時候,遊戲迴圈得到畫布,傳遞給game panel去畫東西,game panel把圖片畫到座標10,10處。回到FPS,如果每秒圖片顯示的次數低於20,就會被人注意到,我們的挑戰就是保持到一定的水平以上,很快我們就會看到

運行一下代碼,我們看到droid在左上方顯示了

Droid in top left corner

移動圖形

我們已經顯示圖形了,讓我們移動它,怎麼移動呢?用我們的手指。 我們會實現一個拖放的操作。為了選擇一個圖片,我們只是觸摸它,當我們的手指還在螢幕的時候,我們的也會更新圖片的座標,當觸摸接觸,圖片會放到最後觸摸的位置

我們需要建立一個對象來儲存圖片和座標

我建立了Droid.java,放到了net.obviam.droidz.model包下

01 package net.obviam.droidz.model;  02    03 import android.graphics.Bitmap;  04    05 public class Droid {  06    07     private Bitmap bitmap;  // the actual bitmap  08     private int x;          // the X coordinate  09     private int y;          // the Y coordinate  10    11     public Droid(Bitmap bitmap, int x, int y) {  12         this.bitmap = bitmap;  13         this.x = x;  14         this.y = y;  15     }  16    17     public Bitmap getBitmap() {  18         return bitmap;  19     }  20     public void setBitmap(Bitmap bitmap) {  21         this.bitmap = bitmap;  22     }  23     public int getX() {  24         return x;  25     }  26     public void setX(int x) {  27         this.x = x;  28     }  29     public int getY() {  30         return y;  31     }  32     public void setY(int y) {  33         this.y = y;  34     }  35 } 

 

這是個只有幾個屬性和一個建構函式的簡單類

droid的x和y座標,還有要顯示的bitmap

還沒有什麼特殊的,但是為了要運行起來,我們需要增加一些狀態,為了保持簡單,droid就有倆狀態,被觸摸和麼有被觸摸,觸摸 就是說手指在螢幕上按著droid,按到droid的時候我們就保持觸摸狀態為真,否則就是假了

看一下新的droid的類

1 package net.obviam.droidz.model;  02    03 import android.graphics.Bitmap;  04 import android.graphics.Canvas;  05 import android.view.MotionEvent;  06    07 public class Droid {  08    09     private Bitmap bitmap;  // the actual bitmap  10     private int x;          // the X coordinate  11     private int y;          // the Y coordinate  12     private boolean touched;    // if droid is touched/picked up  13    14     public Droid(Bitmap bitmap, int x, int y) {  15         this.bitmap = bitmap;  16         this.x = x;  17         this.y = y;  18     }  19    20     public Bitmap getBitmap() {  21         return bitmap;  22     }  23     public void setBitmap(Bitmap bitmap) {  24         this.bitmap = bitmap;  25     }  26     public int getX() {  27         return x;  28     }  29     public void setX(int x) {  30         this.x = x;  31     }  32     public int getY() {  33         return y;  34     }  35     public void setY(int y) {  36         this.y = y;  37     }  38    39     public boolean isTouched() {  40         return touched;  41     }  42    43     public void setTouched(boolean touched) {  44         this.touched = touched;  45     }  46    47     public void draw(Canvas canvas) {  48         canvas.drawBitmap(bitmap, x - (bitmap.getWidth() / 2), y - (bitmap.getHeight() / 2), null);  49     }  50    51     public void handleActionDown(int eventX, int eventY) {  52         if (eventX >= (x - bitmap.getWidth() / 2) && (eventX <= (x + bitmap.getWidth()/2))) {  53             if (eventY >= (y - bitmap.getHeight() / 2) && (y <= (y + bitmap.getHeight() / 2))) {  54                 // droid touched  55                 setTouched(true);  56             } else {  57                 setTouched(false);  58             }  59         } else {  60             setTouched(false);  61         }  62    63     }  64 } 

我們加入了touched來記錄droid的狀態

看一下MainGamePanel,變了可不少呢。

001 package net.obviam.droidz;  002    003 import net.obviam.droidz.model.Droid;  004 import android.app.Activity;  005 import android.content.Context;  006 import android.graphics.BitmapFactory;  007 import android.graphics.Canvas;  008 import android.graphics.Color;  009 import android.util.Log;  010 import android.view.MotionEvent;  011 import android.view.SurfaceHolder;  012 import android.view.SurfaceView;  013    014 public class MainGamePanel extends SurfaceView implements 015         SurfaceHolder.Callback {  016    017     private static final String TAG = MainGamePanel.class.getSimpleName();  018    019     private MainThread thread;  020     private Droid droid;  021    022     public MainGamePanel(Context context) {  023         super(context);  024         // adding the callback (this) to the surface holder to intercept events  025         getHolder().addCallback(this);  026    027         // create droid and load bitmap  028         droid = new Droid(BitmapFactory.decodeResource(getResources(), R.drawable.droid_1), 50, 50);  029    030         // create the game loop thread  031         thread = new MainThread(getHolder(), this);  032    033         // make the GamePanel focusable so it can handle events  034         setFocusable(true);  035     }  036    037     @Override 038     public void surfaceChanged(SurfaceHolder holder, int format, int width,  039             int height) {  040     }  041    042     @Override 043     public void surfaceCreated(SurfaceHolder holder) {  044         // at this point the surface is created and  045         // we can safely start the game loop  046         thread.setRunning(true);  047         thread.start();  048     }  049    050     @Override 051     public void surfaceDestroyed(SurfaceHolder holder) {  052         Log.d(TAG, "Surface is being destroyed");  053         // tell the thread to shut down and wait for it to finish  054         // this is a clean shutdown  055         boolean retry = true;  056         while (retry) {  057             try {  058                 thread.join();  059                 retry = false;  060             } catch (InterruptedException e) {  061                 // try again shutting down the thread  062             }  063         }  064         Log.d(TAG, "Thread was shut down cleanly");  065     }  066    067     @Override 068     public boolean onTouchEvent(MotionEvent event) {  069         if (event.getAction() == MotionEvent.ACTION_DOWN) {  070             // delegating event handling to the droid  071             droid.handleActionDown((int)event.getX(), (int)event.getY());  072    073             // check if in the lower part of the screen we exit  074             if (event.getY() > getHeight() - 50) {  075                 thread.setRunning(false);  076                 ((Activity)getContext()).finish();  077             } else {  078                 Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY());  079             }  080         } if (event.getAction() == MotionEvent.ACTION_MOVE) {  081             // the gestures  082             if (droid.isTouched()) {  083                 // the droid was picked up and is being dragged  084                 droid.setX((int)event.getX());  085                 droid.setY((int)event.getY());  086             }  087         } if (event.getAction() == MotionEvent.ACTION_UP) {  088             // touch was released  089             if (droid.isTouched()) {  090                 droid.setTouched(false);  091             }  092         }  093         return true;  094     }  095    096     @Override 097     protected void onDraw(Canvas canvas) {  098         // fills the canvas with black  099         canvas.drawColor(Color.BLACK);  100         droid.draw(canvas);  101     }  102 } 

 

Line 28 creates the droid object at the the coordinates
50,50.
It is declared as an attribute in line 20.

In the onTouchEvent (method line 71) if the action is the touch of the screen (MotionEvent.ACTION_DOWN) we want to know if our finger landed on the droid. To do this is easy. We need to check if the event’s coordinates
are inside the droid’s bitmap. In order not to clutter the onTouch event we just delegate this to the droid object. Now you can go back to the
Droid.java class and check the handleActionDown method.

28行 建立了droid對象,在座標50,50

在onTouchEvent方法中,如果觸控螢幕幕的動作,我們確認是否在droid上面,就是看看觸摸事件的座標是否在圖形的座標內。為了不讓onTouchEvent雜亂,我們把這個放到droid對象中(其實我覺得在droid內部也可以,要是droid類是怎麼設計的),現在回到droid.java,看一下handleActionDown方法。

public void handleActionDown(int eventX, int eventY) {if (eventX >= (x - bitmap.getWidth() / 2) && (eventX <= (x + bitmap.getWidth()/2))) {if (eventY >= (y - bitmap.getHeight() / 2) && (y <= (y + bitmap.getHeight() / 2))) {// droid touchedsetTouched(true);} else {setTouched(false);}} else {setTouched(false);}}

很簡單,如果在droid內部,把touched狀態設成true。

回到onTouched方法,看一下MotionEvent.ACTION_MOVE,如果droid是touched,我們更新一下它的座標。

而ondraw函數 就是把droid畫到surface上。

就是這樣

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.