一、Activity生命週期
遊戲開發時我們只需要重載 onCreate(), onResume(), 和onPause() 方法,因為無論如何onResume(), 和onPause() 都會調用。當onPause() 之後,系統可能由於記憶體過低殺掉該activity,然後 onStop() 和onDestroy()就不會被執行,而onStart()要在onStop()執行了才會被調用,onpause()之後喚醒activity只會調用onResume().
1)In onCreate(), we set up our window and UI component that we
render to and receive input from.
2)In onResume(), we (re)start our main loop thread .
3)In onPause(), we simply pause our main loop thread, and if
Activity.isFinishing() returns true, we also save any state we want
to persist to disk.
二、事件處理
1)多點觸控
比單點觸控多的新事件:
1、MotionEvent.ACTION_POINTER_DOWN: This event happens for any additional finger that
touches the screen after the first finger touches. The first finger will still produce a
MotionEvent.ACTION_DOWN event.
2、MotionEvent.ACTION_POINTER_UP: This is analogous the previous action. This gets
fired when a finger is lifted up from the screen and more than one finger is touching
the screen. The last finger on the screen to go up will produce a
MotionEvent.ACTION_UP event. This finger doesn’t necessarily have to be the first
finger that touched the screen.
三、按鍵事件
public boolean onKey(View view, int keyCode, KeyEvent event)
keycode:代表手機上按鍵的唯一標示符,例如 KeyCode.KEYCODE_A代表按了A鍵
keyEvent:它和MotionEvent類似,有兩個重要方法
KeyEvent.getAction(): 這個方法返回 KeyEvent.ACTION_DOWN,
KeyEvent.ACTION_UP, and KeyEvent.ACTION_MULTIPLE.
KeyEvent.getUnicodeChar() :將點擊事件當做字元處理
註:擷取按鍵事件,view必須擷取了focus,
View.setFocusableInTouchMode(true);
View.requestFocus();
四、加速度感應器
1、通過Context介面擷取感應器服務
SensorManager manager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
2、檢測是否含有加速度感應器(可選,因為所有的android裝置都裝有加速度感應器)
boolean hasAccel = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).size() > 0;
3、註冊監聽器
Sensor sensor = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0); boolean success = manager.registerListener(listener, sensor,
SensorManager.SENSOR_DELAY_GAME);
五、音效處理
context.setVolumeControlStream(AudioManager.STREAM_MUSIC); //設定音量鍵為調節音量大小
用soundpool播放即時音效
1、SoundPool soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
2、把音效檔案載入到記憶體
AssetManager assetManager = getAssets();
AssetFileDescriptor descriptor = assetManager.openFd("explosion.ogg"); //遊戲開發通常把音效圖片等資源放到assets中,便於用分級檔案夾管理
int explosionId = soundPool.load(descriptor, 1);
3、播放
soundPool.play(explosionId, 1.0f, 1.0f, 0, 0, 1);
4、當不用的時候記得釋放記憶體
soundPool.unload(explosionId);
SoundPool.release();//釋放所有SoundPool所用的資源
用MediaPlayer播放背景音樂
1、MediaPlayer mediaPlayer = new MediaPlayer();
2、AssetManager assetManager = getAssets();
AssetFileDescriptor descriptor = assetManager.openFd("music.ogg");
mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(),
descriptor.getLength());
3、 開啟音樂檔案並檢查是否可播放
mediaPlayer.prepare();
4、播放
mediaPlayer.start();
mediaPlayer.pause();
mediaPlayer.stop(); //再次播放需要先mediaPlayer.prepare(),再mediaPlayer.start()
mediaPlayer.setLooping(true);
5釋放資源
mediaPlayer.release();
MediaPlayer佔用相當大的資源,所以只用於播放背景音樂
六、2D影像處理
1、載入圖片
AssetManager assetManager = context.getAssets();
InputStream inputStream = assetManager.open("bob.png");
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
inputStream.close();
2、繪製
Canvas.drawBitmap(Bitmap bitmap, float topLeftX, float topLeftY, Paint paint);
或Canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint);
2、釋放圖片資源
Bitmap.recycle();
Unless absolutely necessary, refrain from drawing bitmaps scaled. If you know their scaled size, prescale them offline or during loading time. Always make sure you call the Bitmap.recycle() method if you no longer need a Bitmap. Otherwise you’ll get some memory leaks or run low on memory.
SurfaceView
SurfaceView比View的好處是可以在一個單獨的線程中處理遊戲邏輯,從而避免阻塞UI線程
1、在建構函式中擷取SurfaceHolder
SurfaceHolder holder = surfaceView.getHolder();
The SurfaceHolder is a wrapper around the Surface, and does some bookkeeping for us. It provides us with two methods: Canvas SurfaceHolder.lockCanvas(); //鎖定要繪製的Surface並返回一個可用的Canvas SurfaceHolder.unlockAndPost(Canvas canvas); //解鎖Surface並且將我們剛才在Canvas上的繪製在螢幕上顯示
2、繪製
Canvas canvas = holder.lockCanvas(); canvas.draw#ff0000;
holder.unlockCanvasAndPost(canvas);