Androidゲーム開発独学ノート5 Activity関連

19986 ワード

GameScreen.java
package com.gamestudy.mrnom;

import java.util.List;

import android.graphics.Color;

import com.gamestudy.mrnom.framework.Game;
import com.gamestudy.mrnom.framework.Graphics;
import com.gamestudy.mrnom.framework.Input.TouchEvent;
import com.gamestudy.mrnom.framework.Pixmap;
import com.gamestudy.mrnom.framework.Screen;

public class GameScreen extends Screen {
		enum GameState {
		Ready,
		Running,
		Paused,
		GameOver
		}
		
		GameState state = GameState.Ready;
		World world;
		int oldScore = 0;
		String score = "0";
		
		public GameScreen(Game game) {
			super(game);
			world = new World();
		}

		@Override
		public void update(float deltaTime) {
			List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
			game.getInput().getKeyEvents();
			if(state == GameState.Ready)
			updateReady(touchEvents);
			if(state == GameState.Running)
			updateRunning(touchEvents, deltaTime);
			if(state == GameState.Paused)
			updatePaused(touchEvents);
			if(state == GameState.GameOver)
			updateGameOver(touchEvents);
		}

		private void updateReady(List<TouchEvent> touchEvents) {
			if(touchEvents.size() > 0)
			state = GameState.Running;
		}

		private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
			int len = touchEvents.size();
			for(int i = 0; i < len; i++) {
				TouchEvent event = touchEvents.get(i);
				if(event.type == TouchEvent.TOUCH_UP) {
					if(event.x < 64 && event.y < 64) {
					if(Settings.soundEnabled)
						Assets.click.play(1);
						state = GameState.Paused;
						return;
					}
				}
				if(event.type == TouchEvent.TOUCH_DOWN) {
					if(event.x < 64 && event.y > 416) {
						world.snake.turnLeft();
					}
					if(event.x > 256 && event.y > 416) {
						world.snake.turnRight();
					}
				}
			}
			world.update(deltaTime);
			if(world.gameOver) {
				if(Settings.soundEnabled)
					Assets.bitten.play(1);
				state = GameState.GameOver;
			}
			if(oldScore != world.score) {
				oldScore = world.score;
				score = "" + oldScore;
				if(Settings.soundEnabled)
					Assets.eat.play(1);
				}
			}
		
		private void updatePaused(List<TouchEvent> touchEvents) {
			int len = touchEvents.size();
			for(int i = 0; i < len; i++) {
				TouchEvent event = touchEvents.get(i);
				if(event.type == TouchEvent.TOUCH_UP) {
					if(event.x > 80 && event.x <= 240) {
						if(event.y > 100 && event.y <= 148) {
							if(Settings.soundEnabled)
							Assets.click.play(1);
							state = GameState.Running;
							return;
						}
						if(event.y > 148 && event.y < 196) {
							if(Settings.soundEnabled)
							Assets.click.play(1);
							game.setScreen(new MainMenuScreen(game));
							return;
						}
					}//end of if(event.x > 80 && event.x <= 240) 
				}// end of if(event.type == TouchEvent.TOUCH_UP)
			}
	  }

	private void updateGameOver(List<TouchEvent> touchEvents) {
		int len = touchEvents.size();
		for(int i = 0; i < len; i++) {
			TouchEvent event = touchEvents.get(i);
			if(event.type == TouchEvent.TOUCH_UP) {
				if(event.x >= 128 && event.x <= 192 &&
				event.y >= 200 && event.y <= 264) {
					if(Settings.soundEnabled)
					Assets.click.play(1);
					game.setScreen(new MainMenuScreen(game));
					return;
				}
			}
		}
	}
	
	@Override
	public void present(float deltaTime) {
		Graphics g = game.getGraphics();
		g.drawPixmap(Assets.background, 0, 0);
		drawWorld(world);
		if(state == GameState.Ready)
			drawReadyUI();
		if(state == GameState.Running)
			drawRunningUI();
		if(state == GameState.Paused)
			drawPausedUI();
		if(state == GameState.GameOver)
			drawGameOverUI();
		drawText(g, score, g.getWidth() / 2 - score.length()*20 / 2, g.getHeight() -42);
	}

	private void drawWorld(World world) {
		Graphics g = game.getGraphics();
		Snake snake = world.snake;
		SnakePart head = snake.parts.get(0);
		Stain stain = world.stain;
		Pixmap stainPixmap = null;
		if(stain.type == Stain.TYPE_1)
			stainPixmap = Assets.stain1;
		if(stain.type == Stain.TYPE_2)
			stainPixmap = Assets.stain2;
		if(stain.type == Stain.TYPE_3)
			stainPixmap = Assets.stain3;
		int x = stain.x * 32;
		int y = stain.y * 32;
		g.drawPixmap(stainPixmap, x, y);
		int len = snake.parts.size();
		for(int i = 1; i < len; i++) {
			SnakePart part = snake.parts.get(i);
			x = part.x * 32;
			y = part.y * 32;
			g.drawPixmap(Assets.tail, x, y);
		}
		Pixmap headPixmap = null;
		if(snake.direction == Snake.UP)
			headPixmap = Assets.headUp;
		if(snake.direction == Snake.LEFT)
			headPixmap = Assets.headLeft;
		if(snake.direction == Snake.DOWN)
			headPixmap = Assets.headDown;
		if(snake.direction == Snake.RIGHT)
			headPixmap = Assets.headRight;
		x = head.x * 32 + 16;
		y = head.y * 32 + 16;
		g.drawPixmap(headPixmap, x - headPixmap.getWidth() / 2, y -
		headPixmap.getHeight() / 2);
	}

	private void drawReadyUI() {
		Graphics g = game.getGraphics();
		g.drawPixmap(Assets.ready, 47, 100);
		g.drawLine(0, 416, 480, 416, Color.BLACK);
	}
	
	private void drawRunningUI() {
		Graphics g = game.getGraphics();
		g.drawPixmap(Assets.buttons,
				0, 0, 64, 128, 64, 64);	
		g.drawLine(0, 416, 480, 416,
				Color.BLACK);
		g.drawPixmap(Assets.buttons,
				0, 416, 64, 64, 64, 64);
		g.drawPixmap(Assets.buttons,
				256, 416, 0, 64, 64, 64);
	}
	
	private void drawPausedUI() {
		Graphics g = game.getGraphics();
		g.drawPixmap(Assets.pause, 80, 100);
		g.drawLine(0, 416, 480, 416, Color.BLACK);
	}
	private void drawGameOverUI() {
		Graphics g = game.getGraphics();
		g.drawPixmap(Assets.gameOver, 62, 100);
		g.drawPixmap(Assets.buttons, 128, 200, 0, 128, 64, 64);
		g.drawLine(0, 416, 480, 416, Color.BLACK);
	}
	
	public void drawText(Graphics g, String line, int x, int y) {
		int len = line.length();
		for (int i = 0; i < len; i++) {
			char character = line.charAt(i);
			if (character == ' ') {
				x += 20;
				continue;
			}
			int srcX = 0;
			int srcWidth = 0;
			if (character == '.') {
				srcX = 200;
				srcWidth = 10;
			} else {
				srcX = (character - '0') * 20;
				srcWidth = 20;
			}
			g.drawPixmap(Assets.numbers, x, y, srcX, 0, srcWidth, 32);
			x += srcWidth;
		}
	}

	@Override
	public void pause() {
		if(state == GameState.Running)
			state = GameState.Paused;
		if(world.gameOver) {
			Settings.addScore(world.score);
			Settings.save(game.getFileIO());
		}
	}
	@Override
	public void resume() {
	}
	@Override
	public void dispose() {
	}

}
HighscoreScreen.java
package com.gamestudy.mrnom;

import java.util.List;


import com.gamestudy.mrnom.framework.Game;
import com.gamestudy.mrnom.framework.Graphics;
import com.gamestudy.mrnom.framework.Input.TouchEvent;
import com.gamestudy.mrnom.framework.Screen;

public class HighscoreScreen extends Screen {
	String lines[] = new String[5];
	public HighscoreScreen(Game game) {
		super(game);
		for (int i = 0; i < 5; i++) {
			lines[i] = "" + (i + 1) + ". " + Settings.highscores[i];
		}
	}

	@Override
	public void update(float deltaTime) {
		List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
		game.getInput().getKeyEvents();
		int len = touchEvents.size();
		for (int i = 0; i < len; i++) {
			TouchEvent event = touchEvents.get(i);
			if (event.type == TouchEvent.TOUCH_UP) {
				if (event.x < 64 && event.y > 416) {
					if(Settings.soundEnabled)
						Assets.click.play(1);
						game.setScreen(new MainMenuScreen(game));
						return;
				}
			}
		}// end of for (int i = 0; i < len; i++) 
	}

	@Override
	public void present(float deltaTime) {
		Graphics g = game.getGraphics();
		g.drawPixmap(Assets.background, 0, 0);
		g.drawPixmap(Assets.mainMenu, 64, 20, 0, 42, 196, 42);
		int y = 100;
		for (int i = 0; i < 5; i++) {
			drawText(g, lines[i], 20, y);
			y += 50;
		}
		g.drawPixmap(Assets.buttons, 0, 416, 64, 64, 64, 64);
	}

	public void drawText(Graphics g, String line, int x, int y) {
		int len = line.length();
		for (int i = 0; i < len; i++) {
			char character = line.charAt(i);
			if (character == ' ') {
				x += 20;
				continue;
			}
			int srcX = 0;
			int srcWidth = 0;
			if (character == '.') {
				srcX = 200;
				srcWidth = 10;
			} else {
				srcX = (character - '0') * 20;
				srcWidth = 20;
			}
			g.drawPixmap(Assets.numbers, x, y, srcX, 0, srcWidth, 32);
			x += srcWidth;
		}
	}
		@Override
		public void pause() {
		}
		@Override
		public void resume() {
		}
		@Override
		public void dispose() {
		}
} 
MainMenuScreen.java
package com.gamestudy.mrnom;

import java.util.List;

import com.gamestudy.mrnom.framework.Game;
import com.gamestudy.mrnom.framework.Graphics;
import com.gamestudy.mrnom.framework.Input.TouchEvent;
import com.gamestudy.mrnom.framework.Screen;

public class MainMenuScreen  extends Screen {
	public MainMenuScreen(Game game) {
		super(game);
	}

	@Override
	public void update(float deltaTime) {
	Graphics g = game.getGraphics();
	List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
	game.getInput().getKeyEvents();
	int len = touchEvents.size();
	for(int i = 0; i < len; i++) {
		TouchEvent event = touchEvents.get(i);
		if(event.type == TouchEvent.TOUCH_UP) {
		if(inBounds(event, 0, g.getHeight() - 64, 64, 64)) {
		Settings.soundEnabled = !Settings.soundEnabled;
		if(Settings.soundEnabled)
		Assets.click.play(1);
		}
		if(inBounds(event, 64, 220, 192, 42) ) {
		game.setScreen(new GameScreen(game));
		if(Settings.soundEnabled)
		Assets.click.play(1);
		return;
		}
		if(inBounds(event, 64, 220 + 42, 192, 42) ) {
		game.setScreen(new HighscoreScreen(game));
		if(Settings.soundEnabled)
		Assets.click.play(1);
		return;
		}
		if(inBounds(event, 64, 220 + 84, 192, 42) ) {
		game.setScreen(new HelpScreen(game));
		if(Settings.soundEnabled)
		Assets.click.play(1);
		return;
		}
		}
		}
		}

	private boolean inBounds(TouchEvent event, int x, int y, int width, int height) {
		if(event.x > x && event.x < x + width - 1 &&
		event.y > y && event.y < y + height - 1)
		return true;
		else
		return false;
		}

	@Override
	public void present(float deltaTime) {
		Graphics g = game.getGraphics();
		g.drawPixmap(Assets.background, 0, 0);
		g.drawPixmap(Assets.logo, 32, 20);
		g.drawPixmap(Assets.mainMenu, 64, 220);
		if(Settings.soundEnabled)
			g.drawPixmap(Assets.buttons, 0, 416, 0, 0, 64, 64);
		else
			g.drawPixmap(Assets.buttons, 0, 416, 64, 0, 64, 64);
	}

	@Override
	public void pause() {
		Settings.save(game.getFileIO());
	}

	@Override
	public void resume() {
	}
	@Override
	public void dispose() {
	}

}

 
package com.gamestudy.mrnom;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import com.gamestudy.mrnom.framework.FileIO;

public class Settings {
	public static boolean soundEnabled = true;
	public static int[] highscores = new int[] { 100, 80, 50, 30, 10 };
	public static void load(FileIO files) {
		BufferedReader in = null;
		try {
		in = new BufferedReader(new InputStreamReader(
		files.readFile(".mrnom")));
		soundEnabled = Boolean.parseBoolean(in.readLine());
		for (int i = 0; i < 5; i++) {
		highscores[i] = Integer.parseInt(in.readLine());
		}
		} catch (IOException e) {
		// :( It's ok we have defaults
		} catch (NumberFormatException e) {
		// :/ It's ok, defaults save our day
		} finally {
		try {
		if (in != null)
		in.close();
		} catch (IOException e) {
		}
		}
	}

	public static void save(FileIO files) {
		BufferedWriter out = null;
		try {
			out = new BufferedWriter(new OutputStreamWriter(files.writeFile(".mrnom")));
			out.write(Boolean.toString(soundEnabled));
			for (int i = 0; i < 5; i++) {
				out.write(Integer.toString(highscores[i]));
			}
		} catch (IOException e) {
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
			}
		}// end of finally
	}
	
	public static void addScore(int score) {
		for (int i = 0; i < 5; i++) {
			if (highscores[i] < score) {
				for (int j = 4; j > i; j--)
				highscores[j] = highscores[j - 1];
				highscores[i] = score;
				break;
			}
		}
	}

}
package com.gamestudy.mrnom;

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

public class Snake {
	public static final int UP = 0;
	public static final int LEFT = 1;
	public static final int DOWN = 2;
	public static final int RIGHT = 3;

	public List<SnakePart> parts = new ArrayList<SnakePart>();
	public int direction;
	
	public Snake() {
		direction = UP;
		parts.add(new SnakePart(5, 6));
		parts.add(new SnakePart(5, 7));
		parts.add(new SnakePart(5, 8));
	}

	public void turnLeft() {
		direction += 1;
		if(direction > RIGHT)
		direction = UP;
	}
	
	public void turnRight() {
		direction -= 1;
		if(direction < UP)
		direction = RIGHT;
	}
	
	public void eat() {
		SnakePart end = parts.get(parts.size()-1);
		parts.add(new SnakePart(end.x, end.y));
	}

	public void advance() {
		SnakePart head = parts.get(0);
		int len = parts.size() - 1;
		for(int i = len; i > 0; i--) {
			SnakePart before = parts.get(i-1);
			SnakePart part = parts.get(i);
			part.x = before.x;
			part.y = before.y;
		}
		if(direction == UP)
			head.y -= 1;
		if(direction == LEFT)
			head.x -= 1;
		if(direction == DOWN)
			head.y += 1;
		if(direction == RIGHT)
			head.x += 1;
		if(head.x < 0)
			head.x = 9;
		if(head.x > 9)
			head.x = 0;
		if(head.y < 0)
			head.y = 12;
		if(head.y > 12)
			head.y = 0;
		}

	public boolean checkBitten() {
		int len = parts.size();
		SnakePart head = parts.get(0);
		for(int i = 1; i < len; i++) {
			SnakePart part = parts.get(i);
			if(part.x == head.x && part.y == head.y)
			return true;
		}
		return false;
	}

}
package com.gamestudy.mrnom;

public class SnakePart {
	public int x, y;
	
	public SnakePart(int x, int y) {
		this.x = x;
		this.y = y;
	}

}
package com.gamestudy.mrnom;

public class Stain {
	public static final int TYPE_1 = 0;
	public static final int TYPE_2 = 1;
	public static final int TYPE_3 = 2;
	public int x, y;
	public int type;
	public Stain(int x, int y, int type) {
	this.x = x;
	this.y = y;
	this.type = type;
	}

}
package com.gamestudy.mrnom;

import java.util.Random;

public class World {
	static final int WORLD_WIDTH = 10;
	static final int WORLD_HEIGHT = 13;
	static final int SCORE_INCREMENT = 10;
	static final float TICK_INITIAL = 0.5f;
	static final float TICK_DECREMENT = 0.05f;
	public Snake snake;
	public Stain stain;
	public boolean gameOver = false;
	public int score = 0;

	boolean fields[][] = new boolean[WORLD_WIDTH][WORLD_HEIGHT];
	Random random = new Random();
	float tickTime = 0;
	static float tick = TICK_INITIAL;

	public World() {
		snake = new Snake();
		placeStain();
	}
	
	private void placeStain() {
		for (int x = 0; x < WORLD_WIDTH; x++) {
		for (int y = 0; y < WORLD_HEIGHT; y++) {
		fields[x][y] = false;
		}
		}
		int len = snake.parts.size();
		for (int i = 0; i < len; i++) {
		SnakePart part = snake.parts.get(i);
		fields[part.x][part.y] = true;
		}
		int stainX = random.nextInt(WORLD_WIDTH);
		int stainY = random.nextInt(WORLD_HEIGHT);
		while (true) {
		if (fields[stainX][stainY] == false)
		break;
		stainX += 1;
		if (stainX >= WORLD_WIDTH) {
		stainX = 0;
		stainY += 1;
		if (stainY >= WORLD_HEIGHT) {
		stainY = 0;
		}
		}
		}
		stain = new Stain(stainX, stainY, random.nextInt(3));
		}

	public void update(float deltaTime) {
		if (gameOver)
			return;
		tickTime += deltaTime;
		while (tickTime > tick) {
			tickTime -= tick;
			snake.advance();
			if (snake.checkBitten()) {
				gameOver = true;
				return;
			}
			SnakePart head = snake.parts.get(0);
			if (head.x == stain.x && head.y == stain.y) {
				score += SCORE_INCREMENT;
				snake.eat();
			if (snake.parts.size() == WORLD_WIDTH * WORLD_HEIGHT) {
				gameOver = true;
				return;
			} else {
				placeStain();
			}
			if (score % 100 == 0 && tick - TICK_DECREMENT > 0) {
				tick -= TICK_DECREMENT;
			}
			}
		}//end of while (tickTime > tick)
		}
}
これで、Mr.Nomの原理は一度通りました.ただし,ノート3のコードはまだきちんと整理されていないため,現在のコードは実行できない.今日はノート3のコードを整理しましょう.そして、コードができたら、各ドキュメントのコードに対して設計構想と原理を補完し始めます.