トップ » はっかかー日記 » Androidリバーシ

Androidリバーシ はてなブックマーク数 このエントリーをブックマークに追加

ソースをダウンロード:Reversiソース

今日、社内の有志が集まり、Androidの発表会をしました。といっても、まだAndroidを始めたばかりなので、それぞれ思い思いのプログラムを作って発表するというものでした。私は描画部分に興味があったのでリバーシを作ることにしました。

つくりかた

普通に作ってもつまらないので、なるべく移植性を高くするような作りにしようと思いました。そこでボード状態の管理や、AI等のゲームのコアとなる部分と描画処理やキー操作などの環境依存の部分を分けて設計しました。

コアとなるクラスは、以下のクラスです(クリックで拡大)。ソースコードは簡単なので略。

reversi.cld

リバーシは、静的なゲームなのでアクションゲームのように毎フレーム更新するような仕組みは不要です。ゲームに何らかの変化があったときだけ画面を更新すればよいのです。この部分は、Javaではおなじみのリスナを使用しました。ゲームスレッドで何らかの状態が変化した時、描画スレッドにイベントが通知されます。本来であれば、イベントクラスも作成して、もう少し詳しい情報(現在のプレイヤーや裏返った石の場所等)も渡してあげるべきなのですが、今回は、手を抜きました。

このゲームクラスを使用したAndroidのソースは下記のようになります。

package net.hakkaku.android.reversi;

import net.hakkaku.reversi.Board;
import net.hakkaku.reversi.BoardPoint;
import net.hakkaku.reversi.Game;
import net.hakkaku.reversi.SimpleAI;
import net.hakkaku.reversi.Stone;
import net.hakkaku.reversi.Game.OnGameStateChangeListener;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;

public class Reversi extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		final Game game = new Game();

		ReversiView reversiView = new ReversiView(this, game.getBoard());
		setContentView(reversiView);

		TouchPlayer touchPlayer = new TouchPlayer();
		reversiView.setOnTouchListener(touchPlayer);

		//プレイヤを設定
		game.setPlayer(Stone.Black, touchPlayer);
		//game.setPlayer(Stone.White, touchPlayer);
//		game.setPlayer(Stone.Black, new SimpleAI());
		game.setPlayer(Stone.White, new SimpleAI());

		game.setOnGameStateChangeListener(reversiView);

		//ゲームスレッド開始
		new Thread(game).start();

	}

	class ReversiView extends View implements OnGameStateChangeListener {

		private Board board;

		public ReversiView(Context context, final Board board) {
			super(context);
			this.board = board;
			setBackgroundColor(Color.GREEN);
			this.invalidate();
		}

		private float getCellSize() {
			int width = getWidth();
			int height = getHeight();

			return width < height ? width / 8 : height / 8;
		}

		/**
		 * 画面上の座標からボード上の座標に変換する。
		 * @return
		 */
		public BoardPoint getScreenToPoint(final float screenX, final float screenY) {

			float cellSize = getCellSize();
			int x =  (int)(screenX / cellSize);
			int y =  (int)(screenY / cellSize);

			return  (0 <= x && x < 8 && 0 <= y && y < 8)?new BoardPoint(x,y):null;
		}

		@Override
		public void onDraw(Canvas canvas) {
			super.onDraw(canvas);

			Paint pBlack = new Paint(Paint.ANTI_ALIAS_FLAG);
			pBlack.setColor(Color.rgb(0, 0, 0));
			Paint pWhite = new Paint(Paint.ANTI_ALIAS_FLAG);
			pWhite.setColor(Color.rgb(255, 255, 255));

			float cellSize = getCellSize();
			// draw lines
			for (int i = 0; i < 9; i++) {
				canvas.drawLine(i * cellSize, 0, i * cellSize, 8 * cellSize,
						pBlack);
				canvas.drawLine(0, i * cellSize, 8 * cellSize, i * cellSize,
						pBlack);
			}

			// draw stones
			for (int y = 0; y < 8; y++) {
				for (int x = 0; x < 8; x++) {
					final Stone stone = this.board.stoneAt(x, y);
					if (stone == Stone.White) {
						canvas.drawCircle((x + 0.5f) * cellSize, (y + 0.5f)
								* cellSize, cellSize * 0.40f, pBlack);
						canvas.drawCircle((x + 0.5f) * cellSize, (y + 0.5f)
								* cellSize, cellSize * 0.36f, pWhite);
					} else if (stone == Stone.Black) {

						canvas.drawCircle((x + 0.5f) * cellSize, (y + 0.5f)
								* cellSize, cellSize * 0.40f, pBlack);
					}
				}
			}
		}

		private Handler handler = new Handler();

		public void onGameStateChanged() {
			handler.post(new Runnable() {
				public void run() {
					invalidate();
				}
			});
		}
	}

}

android

ちなみにSwing版

swing

 

つくってみて

実は、Android版をほとんど作り終えてから、Swing版に移植したのですが移植にかかった時間は20分ほどでした。AndoridのCanvasクラスとSwingのGraphics(Graphics2D)クラスのAPIがかなり似ていたので、コピペ&微修正であっさりと動作しました。

Androidは、Swing(AWT)のコード資産の流用も比較的容易な、良いプラットフォームだと思いました。


このサイトについて

八角研究所
株式会社八角研究所のWEBサイトですよー。 いろんなものを創り出すことのできる環境をコツコツ構築中。 いったい、いつになったらできるのか。 この技術情報サイトもそのための活動の一環のつもり。

執筆者紹介

ツナ缶

ツナ缶

八角研究所の社員。飽きっぽいです。明日は違うことをやっている。

TrackBack URL :