【Java:的当てゲーム】ユーザー操作で各種画面へ遷移させる

2018年8月16日

前回で、タイトル画面の表示までをTitleMode.javaにて実装しました。

前の記事 的当てゲーム制作Top 次の記事

今回はタイトル画面からいろんな画面へユーザー操作で遷移出来るようにしてみます。

選択肢をユーザーがクリックした時に画面遷移させる

TitleMode.javaに以下のようなメソッドを追加し、オーバーライドすることで、マウスクリックを検出できます。

	//マウスクリック時の処理
	@Override
	public void mouseClicked(MouseEvent e) {
	}

DrawLabelクラスのcontainsメソッドを利用すると、その文字の範囲にクリック座標が含まれるか判定できます。

判定結果が真ならその選択肢に適合する画面へ飛ばす処理を実装します。

ゲーム説明だけはタイトル画面内でゲーム説明を表示する処理で実装してみます。フラグが立つと、タイトル画面の上に黒い半透明な矩形を描画し、ゲーム説明文を描画します。フラグが立っている時はクリック時に説明書の表示をキャンセルできるようにプログラムします。

mouseClickedメソッドの実装結果はこんな感じになりました。


	//画面状態フラグ
	boolean isDescription=false;

	//描画処理
	public void draw(Graphics g) {
		drawTitle(g);
		if ( isDescription ) {
			drawDescription(g);
		}
	}

	//説明の描画
	void drawDescription(Graphics g) {
		g.setColor(Color.BLACK);
		GraphicsUtil.setAlpha(g, 0.95f);
		g.fillRect(0,0,AppManager.getW(),AppManager.getH());
		g.setColor(Color.WHITE);
		GraphicsUtil.setDefaultAlpha(g);
		g.drawString("説明書", 50, 150);
		g.drawString("約30秒間で的を破壊して高得点を目指すゲームです。", 50, 200);
		g.drawString("的をマウスの左ボタンでクリックすると破壊できます。", 50, 240);
		g.drawString("的は中央に近づくほど高得点で、0~100点となります。", 50, 280);
		g.drawString("コンボ数は連続で的を破壊できると増えていきます。", 50, 320);
		g.drawString("コンボ数は破壊した的の得点×コンボ数となります。", 50, 360);
		g.drawString("ランクはG~Sまでの8段階あります。", 50, 400);
		g.drawString("フィールド上にある壁をクリックしても得点は上がりません。", 50, 440);
	}


	//マウスクリック時の処理
	@Override
	public void mouseClicked(MouseEvent e) {
		Point p = e.getPoint();
		if ( !isDescription && start.contains(p)) {
			//ゲーム画面へ遷移
			AppManager.selectSE();
			AppManager.change(ViewType.GAME);
		} else if ( !isDescription && ranking.contains(p) ) {
			//ランキング画面へ遷移
			AppManager.selectSE();
			AppManager.change(ViewType.RANKING);
		} else if ( !isDescription && description.contains(p) ) {
			//ゲーム説明を表示
			AppManager.selectSE();
			isDescription = true;
		} else if ( !isDescription && end.contains(p) ) {
			//ゲーム終了
			AppManager.end();
		} else if ( isDescription ) {
			//説明表示を終了
			isDescription = false;
		}
	}
実行結果

選択肢にマウスカーソルを合わせたとき色変更、カーソル変更させる

選択肢にマウスカーソルが近づくと、選択文字の色を変更し、マウスカーソルの形を手の形に変更してみます。

これを実装するにはマウスの移動を検出する必要があります。マウスの移動検出はmouseMovedメソッドをオーバーライドして実装します。

マウスカーソルの形を変更するにはsetCursorメソッドを利用します。(※このメソッドはawtのメソッドです。)

例えば手のカーソルにしたい場合は以下のようなプログラムで実現できます。

setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

それでは実際にマウスカーソルの座標によって手の形に変更したりする処理を記述してみましょう。

	@Override
	public void mouseMoved(MouseEvent e) {
		Point p = e.getPoint();
		//選択肢にマウスカーソルを持ってきた場合はカーソルを変更する
		if ( start.contains(p) || end.contains(p) || ranking.contains(p) || description.contains(p) ) {
			setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		} else {
			setCursor(Cursor.getDefaultCursor());
		}
	}

次に文字の色を変更する処理ですが、これはmouseMovedメソッドでマウス座標を保持しておき、ゲームループ内のGraphicsメソッドに色変更する処理を入れて対応します。まぁどっちもゲームループ内でやってもいいんですけどね。それにGTKManagerにはどこからでもマウス座標を取得できるメソッドも用意していますしそれを利用するのもありです。

さて本稿でTitleMode.javaの作成は完了となりました。TitleModeクラスの実装結果はこんな感じになりました。

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;

import com.nompor.gtk.GameView;
import com.nompor.gtk.draw.DrawLabel;
import com.nompor.gtk.draw.GraphicsUtil;

public class TitleMode extends GameView {

	//タイトル画面の文字列オブジェクト
	DrawLabel title;
	DrawLabel start;
	DrawLabel ranking;
	DrawLabel description;
	DrawLabel end;

	//マウスカーソルの位置
	Point p = new Point();

	//フォントオブジェクトの構築
	Font titleFont = new Font(Font.MONOSPACED,Font.BOLD, 60);
	Font defaultFont = new Font(Font.MONOSPACED,Font.PLAIN, 25);

	int cx;

	//画面状態フラグ
	boolean isDescription=false;

	//ウィンドウにこのオブジェクトが設置されたら最初に呼び出しされる
	public void start() {

		//ウィンドウの中心座標の取得
		cx = AppManager.getW()/2;

		//文字列オブジェクトを構築する
		Graphics g = getGraphics();
		title = new DrawLabel(g, "的当てゲーム", titleFont, cx, 100);
		start = new DrawLabel(g, "ゲーム開始", defaultFont, cx, 350);
		ranking = new DrawLabel(g, "ランキング", defaultFont, cx, 400);
		description = new DrawLabel(g, "説明書", defaultFont, cx, 450);
		end = new DrawLabel(g, "終了", defaultFont, cx, 500);
	}

	//描画処理
	public void draw(Graphics g) {
		drawTitle(g);
		if ( isDescription ) {
			drawDescription(g);
		}
	}

	//タイトルの描画
	void drawTitle(Graphics g) {
		//アンチエイリアシングの有効化
		GraphicsUtil.setTextAntialiasing(g, true);

		//背景描画
		g.drawImage(AppManager.getBackImage(), 0, 0, null);

		//的描画(飾り)
		GraphicsUtil.drawCenteringImage(g, AppManager.getTargetImage(), cx, 200);

		//タイトル文字列描画
		g.setColor(Color.WHITE);
		g.setFont(titleFont);
		title.draw(g);

		//選択肢描画
		g.setFont(defaultFont);
		g.setColor(start.contains(p) ? Color.ORANGE : Color.WHITE);
		start.draw(g);
		g.setColor(ranking.contains(p) ? Color.ORANGE : Color.WHITE);
		ranking.draw(g);
		g.setColor(description.contains(p) ? Color.ORANGE : Color.WHITE);
		description.draw(g);
		g.setColor(end.contains(p) ? Color.ORANGE : Color.WHITE);
		end.draw(g);

	}

	//説明の描画
	void drawDescription(Graphics g) {
		g.setColor(Color.BLACK);
		GraphicsUtil.setAlpha(g, 0.95f);
		g.fillRect(0,0,AppManager.getW(),AppManager.getH());
		g.setColor(Color.WHITE);
		GraphicsUtil.setDefaultAlpha(g);
		g.drawString("説明書", 50, 150);
		g.drawString("約30秒間で的を破壊して高得点を目指すゲームです。", 50, 200);
		g.drawString("的をマウスの左ボタンでクリックすると破壊できます。", 50, 240);
		g.drawString("的は中央に近づくほど高得点で、0~100点となります。", 50, 280);
		g.drawString("コンボ数は連続で的を破壊できると増えていきます。", 50, 320);
		g.drawString("コンボ数は破壊した的の得点×コンボ数となります。", 50, 360);
		g.drawString("ランクはG~Sまでの8段階あります。", 50, 400);
		g.drawString("フィールド上にある壁をクリックしても得点は上がりません。", 50, 440);
	}

	//マウスクリック時の処理
	public void mouseClicked(MouseEvent e) {
		Point p = e.getPoint();
		if ( !isDescription && start.contains(p)) {
			//ゲーム画面へ遷移
			setCursor(Cursor.getDefaultCursor());
			AppManager.selectSE();
			AppManager.change(ViewType.GAME);
		} else if ( !isDescription && ranking.contains(p) ) {
			//ランキング画面へ遷移
			setCursor(Cursor.getDefaultCursor());
			AppManager.selectSE();
			AppManager.change(ViewType.RANKING);
		} else if ( !isDescription && description.contains(p) ) {
			//ゲーム説明を表示
			setCursor(Cursor.getDefaultCursor());
			AppManager.selectSE();
			isDescription = true;
		} else if ( !isDescription && end.contains(p) ) {
			//ゲーム終了
			AppManager.end();
		} else if ( isDescription ) {
			//説明表示を終了
			isDescription = false;
		}
	}

	//マウスカーソルの位置を記憶
	public void mouseMoved(MouseEvent e) {
		p = e.getPoint();
		//選択肢にマウスカーソルを持ってきた場合はカーソルを変更する
		if ( start.contains(p) || end.contains(p) || ranking.contains(p) || description.contains(p) ) {
			setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		} else {
			setCursor(Cursor.getDefaultCursor());
		}
	}
}
実行結果

Java

Posted by nompor