Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android游戲開發的技術實現分析

android游戲開發的技術實現分析

編輯:關於Android編程

在android開發中,你可能會有想要開發一個小游戲的沖動,那麼用android來開發游戲如何實現呢?幸運的是,google提供了一些已經開發好的游戲實例.我們從他的兩個游戲實例入手來探究探究.

對於輕量級的小游戲,其游戲的核心顯示內容,我們可以寫一個自己的view來實現!然後以一定的頻率刷新這個view,我們調用view的invalidate()來實現.具體的我們來看看一個大家常見的游戲:Snake(貪吃蛇),下面來分析一些實現這個游戲的關鍵代碼.

和其他app一樣,Snake也由一個Activity開始的,同樣的通過setContentView(R.layout.snake_layout);這行代碼來確定顯示內容的布局,這裡有必要看看這個布局文件的內容(如下):

 

 


上面的代碼,我們首先需要注意的是這個布局文件采用了merge來限定:因為我們的布局是framelayout,所以這裡就采用了merge,因為任何加入activity的view的父groupview都是framelayout.

 

這裡我們重點關注的時SnakeView,這個view就是實現這個游戲的核心.這裡需要注意這一行代碼:app:tileSize=24dp.這是SnakeView自己定義的一個屬性,用於定義貪吃蛇的大小.能夠這樣使用,你需要先在attrs.xml裡面為SnakeView定義這樣的屬性,看看這裡時如何定義的:

 

  
    
  
你肯定會奇怪,怎麼是TileView呢? 其實SnakeView是TileView的子類,而TileView是view的子類.

 

所以我們重點來看看SnakeView的實現.(貪吃蛇的具體實現就不設計,這裡只是介紹一個游戲開發的實現核心).其實游戲的動畫效果就是反復的調用invalidate來促使view重現繪制,通過重寫View的onDraw(Canvas canvas)來實現.這樣以來,當調用invalidate(),就會觸發view自己回調onDraw(Canvas canvas),而游戲每一次需要顯示的內容都由onDraw來繪制.

下面是定時刷新view的代碼:

 

    class RefreshHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            SnakeView.this.update();
            SnakeView.this.invalidate();
        }

        public void sleep(long delayMillis) {
            this.removeMessages(0);
            sendMessageDelayed(obtainMessage(0), delayMillis);
        }
    };

上面定義的是一個handle,該handle起到一個定時器的作用,每隔delayMillis這麼長的時間,來更新update()需要下次繪制的內容,然後invalidate()來刷新.

 

下面是他的onDraw的實現:

 

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int x = 0; x < mXTileCount; x += 1) {
            for (int y = 0; y < mYTileCount; y += 1) {
                if (mTileGrid[x][y] > 0) {
                    canvas.drawBitmap(mTileArray[mTileGrid[x][y]], mXOffset + x * mTileSize,
                            mYOffset + y * mTileSize, mPaint);
                }
            }
        }

    }
通過上面代碼可以知道,其實就繪制了一些圖片,這些圖片按照一定的坐標就組成來一條蛇.所以每次只要mTileGrid裡面的信息准確其繪制出的圖像就是准確的.

 

對於像貪吃蛇/象棋等這樣的輕量級游戲我們可以這麼做,不過對於一些格斗類的游戲就不太實用了,當要繪制大量的圖片資源/鈴聲資源的時候就滿足不了需要.這個時候我們需要用到一個特殊的view:SurfaceView

還好,google給我提供了一個實例:JetBoy.下面我們來看看如何使用SurfaceView.

(1)首先,你寫的SurfaceView需要實現這個接口SurfaceHolder.Callback, 其目的是我們需要獲取我們的SurfaceView的狀態變化(創建成功/大小變化/銷毀).如下代碼:

 

public class JetBoyView extends SurfaceView implements SurfaceHolder.Callback {
(2) 我們需要得到 SurfaceView的SurfaceHolder,並且使用SurfaceHolder.Callback,你需要在構造方法裡面完成,如下代碼:

 

 

    public JetBoyView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // register our interest in hearing about changes to our surface
        SurfaceHolder holder = getHolder();
        holder.addCallback(this);

(3)由於,我們需要繪制大量的內容,所以我們一般需要開啟一個線程來做這些工作.下面來詳細介紹其中緣由: 我們通過上面獲得的SurfaceHolder就可以獲得這個SurfaceView的Canvas,所以只要我們用這個Canvas來繪制我們需要的東西即可,這些工作我們都是在我們定義的線程裡面來完成的,當然這一切都應該在SurfaceView創建完成以後(surfaceCreated(SurfaceHolder arg0) 回調以後)才能完成.下面來看thread裡面的run裡面核心代碼:

 

 

        public void run() {
            // while running do stuff in this loop...bzzz!
            while (mRun) {
                Canvas c = null;

                ...
				...
				...

                try {
                    c = mSurfaceHolder.lockCanvas(null);
                    // synchronized (mSurfaceHolder) {
                    doDraw(c);
                    // }
                } finally {
                    // do this in a finally so that if an exception is thrown
                    // during the above, we don't leave the Surface in an
                    // inconsistent state
                    if (c != null) {
                        mSurfaceHolder.unlockCanvasAndPost(c);
                    }
                }// end finally block
            }// end while mrun block
        }

上面代碼通過mSurfaceHolder.lockCanvas(null);來獲取我們SurfaceView的canvas, 然後繪制內容,繪制完成指向這行代碼mSurfaceHolder.unlockCanvasAndPost(c);

 

(4)所以我們需要在surfaceCreated的時候開始我們的游戲:

 

    public void surfaceCreated(SurfaceHolder arg0) {
        // start the thread here so that we don't busy-wait in run()
        // waiting for the surface to be created
        thread.setRunning(true);
        thread.start();
    }
在surfaceDestroyed的時候結束我們的線程:

 

 

    public void surfaceDestroyed(SurfaceHolder arg0) {
        boolean retry = true;
        thread.setRunning(false);
        while (retry) {
            try {
                thread.join();
                retry = false;

            } catch (InterruptedException e) {
            }
        }
    }

其實都很簡單的大家使用一下就明白的.

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved