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のコードを整理しましょう.そして、コードができたら、各ドキュメントのコードに対して設計構想と原理を補完し始めます.