android游戏开发自学笔记3 接口impl设计

Mr.Nom接口框架实现:

AndroidFileIO.java
package com.gamestudy.mrnom.framework.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.res.AssetManager;
import android.os.Environment;

import com.gamestudy.mrnom.framework.FileIO;

public class AndroidFileIO implements FileIO {
	AssetManager assets;
	String externalStoragePath;
	
	public AndroidFileIO(AssetManager assets) {
		this.assets = assets;
		this.externalStoragePath = Environment.getExternalStorageDirectory()
		.getAbsolutePath() + File.separator;
	}
	@Override
	public InputStream readAsset(String fileName) throws IOException {
		return assets.open(fileName);
	}
	@Override
	public InputStream readFile(String fileName) throws IOException {
		return new FileInputStream(externalStoragePath + fileName);
	}
	@Override
	public OutputStream writeFile(String fileName) throws IOException {
		return new FileOutputStream(externalStoragePath + fileName);
	}

}
package com.gamestudy.mrnom.framework.impl;

import java.io.IOException;

import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;

import com.gamestudy.mrnom.framework.Music;

public class AndroidMusic implements Music, OnCompletionListener {
	MediaPlayer mediaPlayer;
	boolean isPrepared = false;
	
	public AndroidMusic(AssetFileDescriptor assetDescriptor) {
		mediaPlayer = new MediaPlayer();
		try {
			mediaPlayer.setDataSource(assetDescriptor.getFileDescriptor(),
			assetDescriptor.getStartOffset(),
			assetDescriptor.getLength());
			mediaPlayer.prepare();
			isPrepared = true;
			mediaPlayer.setOnCompletionListener(this);
		} catch (Exception e) {
			throw new RuntimeException("Couldn't load music");
		}
	}
	
	@Override
	public void dispose() {
		if (mediaPlayer.isPlaying())
			mediaPlayer.stop();
			mediaPlayer.release();
	}

	@Override
	public boolean isLooping() {
		return mediaPlayer.isLooping();
	}
	@Override
	public boolean isPlaying() {
		return mediaPlayer.isPlaying();
	}
	@Override
	public boolean isStopped() {
		return !isPrepared;
	}

	@Override
	public void play() {
		if (mediaPlayer.isPlaying()) return;
		try {
			synchronized (this) {
				if (!isPrepared) mediaPlayer.prepare();
				mediaPlayer.start();
			}
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void setLooping(boolean isLooping) {
		mediaPlayer.setLooping(isLooping);
	}
	@Override
	public void setVolume(float volume) {
		mediaPlayer.setVolume(volume, volume);
	}

	@Override
	public void stop() {
		mediaPlayer.stop();
		synchronized (this) {
			isPrepared = false;
		}
	}

	@Override
	public void onCompletion(MediaPlayer player) {
		synchronized (this) {
			isPrepared = false;
		}
	}

	@Override
	public void pause() {
	    if (mediaPlayer.isPlaying())
	        mediaPlayer.pause();
	}
}


package com.gamestudy.mrnom.framework.impl;

import android.media.SoundPool;

import com.gamestudy.mrnom.framework.Sound;

public class AndroidSound implements Sound {
	int soundId;
	SoundPool soundPool;
	public AndroidSound(SoundPool soundPool, int soundId) {
		this.soundId = soundId;
		this.soundPool = soundPool;
	}
	@Override
	public void play(float volume) {
		soundPool.play(soundId, volume, volume, 0, 0, 1);
	}
	@Override
	public void dispose() {
		soundPool.unload(soundId);
	}

}

package com.gamestudy.mrnom.framework.impl;

import java.io.IOException;

import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioManager;
import android.media.SoundPool;

import com.gamestudy.mrnom.framework.Audio;
import com.gamestudy.mrnom.framework.Music;
import com.gamestudy.mrnom.framework.Sound;

public class AndroidAudio implements Audio {
	AssetManager assets;
	SoundPool soundPool;

	public AndroidAudio(Activity activity) {
		activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
		this.assets = activity.getAssets();
		this.soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
	}

	@Override
	public Music newMusic(String filename) {
		try {
			AssetFileDescriptor assetDescriptor = assets.openFd(filename);
		return new AndroidMusic(assetDescriptor);
		} catch (IOException e) {
			throw new RuntimeException("Couldn't load music '" + filename + "'");
		}
	}

	@Override
	public Sound newSound(String filename) {
		try {
			AssetFileDescriptor assetDescriptor = assets.openFd(filename);
			int soundId = soundPool.load(assetDescriptor, 0);
			return new AndroidSound(soundPool, soundId);
		} catch (IOException e) {
			throw new RuntimeException("Couldn't load sound '" + filename + "'");
		}
	}

}


package com.gamestudy.mrnom.framework.impl;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class AccelerometerHandler implements SensorEventListener {
	float accelX;
	float accelY;
	float accelZ;
	public AccelerometerHandler(Context context) {
		SensorManager manager = (SensorManager) context
		.getSystemService(Context.SENSOR_SERVICE);
		if (manager.getSensorList(Sensor.TYPE_ACCELEROMETER).size() != 0) {
			Sensor accelerometer = manager.getSensorList(
			Sensor.TYPE_ACCELEROMETER).get(0);
			manager.registerListener(this, accelerometer,
			SensorManager.SENSOR_DELAY_GAME);
		}
	}
	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
	// nothing to do here
	}
	@Override
	public void onSensorChanged(SensorEvent event) {
		accelX = event.values[0];
		accelY = event.values[1];
		accelZ = event.values[2];
	}
	public float getAccelX() {
		return accelX;
	}
	public float getAccelY() {
		return accelY;
	}
	public float getAccelZ() {
		return accelZ;
	}

}

尽管onSensorChanged()方法有可能在别的线程被调用,这里也没有用synchronization.因为java的内存模式可以保证原始类型譬如boolean,intbyte操作的原子性。

如果不是目前代码情况,需要加上适当的同步保护,譬如说如果在onSensorChanged()中有对成员变量的操作。

package com.gamestudy.mrnom.framework.impl;

import java.util.ArrayList;
import java.util.List;

public class Pool<T> {
	public interface PoolObjectFactory<T> {
		public T createObject();
	}

	private final List<T> freeObjects;
	private final PoolObjectFactory<T> factory;
	private final int maxSize;

	public Pool(PoolObjectFactory<T> factory, int maxSize) {
		this.factory = factory;
		this.maxSize = maxSize;
		this.freeObjects = new ArrayList<T>(maxSize);
	}

	public T newObject() {
		T object = null;
		if (freeObjects.size() == 0)
		object = factory.createObject();
		else
		object = freeObjects.remove(freeObjects.size() - 1);
		return object;
	}

	public void free(T object) {
		if (freeObjects.size() < maxSize)
		freeObjects.add(object);
		}

}


你可能感兴趣的:(android游戏开发自学笔记3 接口impl设计)