Android Game Framework Part 6
Part 5 에서 작성된 프레임워크에 GraphicObject 클래스를 추가함
IntroState 클래스 안에서 GraphicObject를 테스트함
GameActivity.java
package game.framework;
import android.app.Activity;
import android.os.Bundle;
public class GameActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GameView(this));
}
}
GameView.java
package game.framework;
import android.content.*;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.media.AudioManager;
import android.media.SoundPool;
import android.view.*;
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
GameViewThread gameThread;
SoundManager sm;
IState state;
public GameView(Context context) {
super(context);
getHolder().addCallback(this);
setFocusable(true);
/* AppManager 실행 테스트 */
AppManager.getInstance().setGameView(this);
AppManager.getInstance().setResources(getResources());
/* SoundManager 실행 테스트 */
sm = SoundManager.getInstance();
sm.init(getContext());
sm.addSound(1, R.raw.shuffling);
changeGameState(new IntroState());
gameThread = new GameViewThread(getHolder(), this);
}
public void update() {
state.update();
}
public void changeGameState(IState state) {
if(this.state != null) this.state.destroy();
state.init();
this.state = state;
}
/* SoundManager 를 이용한 사운드의 이용 테스트 */
@Override
public boolean onTouchEvent(MotionEvent event) {
sm.play(1);
return state.onTouchEvent(event);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return state.onKeyDown(keyCode, event);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
state.render(canvas);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
gameThread.setRunning(true);
gameThread.start();
sm.play(1);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameThread.setRunning(false);
while(retry){
try{
gameThread.join();
retry = false;
}catch(InterruptedException ie){
}
}
}
}
GameViewThread.java
package game.framework;
import android.graphics.*;
import android.view.*;
public class GameViewThread extends Thread {
private SurfaceHolder surfaceHolder;
private GameView gameView;
private boolean m_run;
public GameViewThread(SurfaceHolder surfaceHolder, GameView gameView) {
this.surfaceHolder = surfaceHolder;
this.gameView = gameView;
}
public void setRunning(boolean run) {
this.m_run = run;
}
@Override
public void run() {
Canvas canvas = null;
while(m_run) {
canvas = null;
try{
gameView.update();
canvas = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
gameView.onDraw(canvas);
}
}catch(Exception ex){
}finally {
if(canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
AppManager.java
package game.framework;
import android.content.res.*;
import android.graphics.*;
public class AppManager {
private GameView gameView;
private Resources resources;
private AppManager() {}
void setGameView(GameView gameView) {
this.gameView = gameView;
}
void setResources(Resources resources ){
this.resources = resources;
}
public GameView getGameView() {
return gameView;
}
public Resources getResources() {
return resources;
}
public Bitmap getBitmap(int resId) {
return BitmapFactory.decodeResource(getResources(), resId);
}
private static AppManager instance;
public static AppManager getInstance() {
if(instance==null) instance = new AppManager();
return instance;
}
}
SoundManager.java
package game.framework;
import java.util.*;
import android.content.*;
import android.media.*;
public class SoundManager {
private SoundPool soundPool;
private HashMap<Integer, Integer> soundPoolMap;
private AudioManager audioManager;
private Context context;
private SoundManager(){}
public void init(Context context) {
soundPool = new SoundPool(4,AudioManager.STREAM_MUSIC, 0);
soundPoolMap = new HashMap<Integer, Integer>();
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
/* 사운드가 로드될 때 자동으로 호출되는 핸들러 메소드
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundPool.play(sampleId, 1, 1, 1, 0, 1);
}
}); */
this.context = context;
}
public void addSound(int idx, int resId) {
int id = soundPool.load(context, resId, 1);
soundPoolMap.put(idx, id);
}
public void play(int idx) {
float streamVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
streamVolume = streamVolume / audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
soundPool.play((Integer) soundPoolMap.get(idx), streamVolume, streamVolume, 1, 0, 1);
}
public void playLoop(int idx) {
float streamVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
streamVolume = streamVolume / audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
soundPool.play((Integer) soundPoolMap.get(idx), streamVolume, streamVolume, 1, -1, 1);
}
private static SoundManager instance;
public static SoundManager getInstance() {
if(instance ==null) instance = new SoundManager();
return instance;
}
}
IState.java
package game.framework;
import android.graphics.*;
import android.view.*;
public interface IState {
public void init();
public void destroy();
public void update();
public void render(Canvas canvas);
public boolean onKeyDown(int keyCode, KeyEvent event);
public boolean onTouchEvent(MotionEvent event);
}
IntroState.java
package game.framework;
import android.graphics.*;
import android.view.*;
public class IntroState implements IState {
Bitmap icon;
int x, y;
GraphicObject go; // GraphicObject 를 테스트하는 부분
@Override
public void init() {
icon = AppManager.getInstance().getBitmap(R.drawable.ic_launcher);
go = new GraphicObject(icon); // GraphicObject 를 테스트하는 부분
}
@Override
public void destroy() {
}
@Override
public void update() {
go.setPosition(x++, y++); // GraphicObject 를 테스트하는 부분
}
@Override
public void render(Canvas canvas) {
//canvas.drawBitmap(icon, x, y, null);
go.draw(canvas); // GraphicObject 를 테스트하는 부분
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return false;
}
}
GraphicObject.java
package game.framework;
import android.graphics.*;
public class GraphicObject {
protected Bitmap bitmap;
protected int x, y;
public GraphicObject(Bitmap bitmap) {
this.bitmap = bitmap;
}
public void setPosition(int x, int y){
this.x = x;
this.y = y;
}
public void draw(Canvas canvas){
canvas.drawBitmap(bitmap, x, y, null);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}