Android遊戲開發菜鳥之路(四)

最近一直在搭一個框架吧,基本是參照《Beginning Android Games》一書的方法,以後可能還會在此基礎上更改。

此框架主要實現遊戲中的一些基本功能:

FileIO

AudioManager

InputManager

Graphics


FileIO:

FileIO模塊主要實現三個內容:從Ram中讀取內容,從SD卡中讀取內容,將內容寫入SD中。

從Ram中讀取內容,即從assets/目錄中讀取內容,利用AssetManager類:

AssetManagerassets = activity.getAssets();
assets.open(fileName);

從SD卡中讀取內容,要用到Environment類。首先判斷外部存儲是否存在:

this.state = Environment.getExternalStorageState();
if(!state.equals(Environment.MEDIA_MOUNTED)){
           // don’t exist
}
else{
           // exist
}

如果存在,得到外部存儲的路徑:

externalStoragePath = Environment.getExternalStorageDirectory()
                                          .getAbsolutePath()+
                                          File.separator;

讀入和輸出代碼爲:

FileInputStream(externalStoragePath+fileName);
FileOutputStream(externalStoragePath+fileName);

而用戶通過調研這些接口,便可以獲得想要的文件的輸入輸出的Handler了,不是這裏說Handler是否合適。


AudioManager:

這裏我們將根據音頻的大小來處理。如果音頻較小(或者說是短),我們利用SoundPool類來處理,建立一個SoundPool實例:

this.soundPool = newSoundPool(20,AudioManager.STREAM_MUSIC,0);

然後通過AssetManager得到某個音頻的AssetFileDescriptor:

AssetFileDescriptorassetDescriptor = assets.openFd(fileName);

我們可以利用這個描述符去加載一個音頻

int soundId = soundPool.load(assetDescriptor,0)

soundId爲音頻號,開啓音頻和關閉音頻都靠它了:

soundPool.play(soundId, volume, volume,0, 0, 1);
soundPool.unload(soundId);

如果音頻較大,我們可以用MediaPlayer類。在這之前,我們應當設置音頻流:

activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);

相同的,獲得音頻的描述符:

AssetFileDescriptorassetDescriptor = assets.openFd(fileName);

最後音頻加載:

mediaPlayer.setDataSource(assetFD.getFileDescriptor(),assetFD.getStartOffset(), assetFD.getLength());

那麼怎麼去開啓一個音頻呢?首先要prepare它,然後纔可以start,pause和stop它,如果不想用了,可以release它。

 

InputManager:

遊戲的輸入分爲三類:儀器的加速度(重力感應器)、鍵盤觸發和觸摸屏。而這三類都需要Listener來監聽,即要實現對應的Listener的接口。


儀器的加速度的實現很簡單,其要實現SensorEventListener接口,並且通過Context來註冊SensorManager,然後通過SensorManager來得到加速器的Sensor,最後通過Sensor來註冊監聽器:

SensorManager sensor =(SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
if(sensor.getSensorList(Sensor.TYPE_ACCELEROMETER).size() != 0){
    Sensor accelerometer =sensor.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
    sensor.registerListener(this, accelerometer,SensorManager.SENSOR_DELAY_GAME);
}

然後在Listener中的onSensorChanged中讀取加速度:

public void onSensorChanged(SensorEvent event) {
       // TODO Auto-generatedmethod stub
       accelX = event.values[0];
       accelY = event.values[1];
       accelZ = event.values[2];
 
}

接下來實現鍵盤觸發,其要實現OnKeyListener接口,然後就是給指定的View設置監聽器:

view.setOnKeyListener(this);
view.setFocusableInTouchMode(true);
view.requestFocus();

然後再Listener中的onKey中處理按鍵事件,主要對KeyEvent.ACTION_UP和KeyEvent.ACTION_DOWN兩個事件進行處理。

 

最後是觸摸屏,其要實現OnTouchListener接口,先說說單手指觸摸屏的處理,其處理起來很簡單,先對指定的View設置監聽器:

view.setOnTouchListener(this);

然後再Listener中的onTouch中進行處理,主要處理MotionEvent.ACTION_DOWN,MotionEvent.ACTION_UP,MotionEvent.ACTION_MOVE和MotionEvent.ACTION_CANCEL。

再說說多手指觸摸屏觸發,其與單手指的最大不同在於獲得action和pointerId上,pointerId可以理解爲是哪隻手在觸發:

int action = event.getAction() & MotionEvent.ACTION_MASK;
int pointerIndex =(event.getAction() &MotionEvent.ACTION_POINTER_ID_MASK)
                            >>MotionEvent.ACTION_POINTER_ID_SHIFT;
intpointerId = event.getPointerId(pointerIndex);

最後就是處理事件了。

 

Graphics:

其思想就是封裝一種類,可以在屏幕上畫一些基本類型的圖和Bitmap。我們的思想是先在屏幕上鋪一個大的Bitmap作爲畫紙,任何圖形和圖層都在這上面畫。

我們先封裝一下Bitmap,bitmap可以有一個format的屬性,分別是:

public static enum PixmapFormat{
       ARGB8888, ARGB4444, RGB565
}

通過這個封裝類還可以得到Bitmap的高和寬。我們稱這個封裝類(其實是個接口)爲Pixmap。

還有一個Graphics接口,他定義了創造一個Pixmap,繪畫一個Pixmap和基本圖形的方法。

 

整合:

最後,也是最關鍵的就是將上面講的這4項進行整合,那就是Game接口來定義的,他定義了獲得上面五個方面的方法,以及獲得當前窗口和設置窗口的方法。然後就是利用AndroidGame類來實現,他會新建一個SurfaceView實例,通過它來將圖紙畫到屏幕上。

源碼可以從這裏下載:http://download.csdn.net/detail/whosemario/3754024


接下來就是用這個框架寫一個貪吃蛇的程序,甚至有可能將此遊戲移植到html5上,敬請期待~


發佈了54 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章