【Java:的当てゲーム】ゲームの結果と終了の実装

2018年8月16日

前回は、ブロックの配置処理を実装し、ゲーム内容の実装が完了するところまでやりました。

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

今回はリザルトの表示を実装し、そのあとタイトル画面へ遷移する処理を実装したいと思います。

リザルトの表示

リザルト画面の表示はすべての的がなくなり、かつ30秒経過した後に行いたいので、タイマーに新たに判定処理を追加します。

ただし30秒立ったらすぐに表示するのではなく、2秒程インターバルを開けて表示処理をします。

まずはタイマーで終了フラグを立てるプログラムを実装します。

GameMode.java
	Timer timer = new Timer();
	TimerTask task = new TimerTask() {

		@Override
		public void run() {
			if ( prepareCountDown > 0 ) {
				//ゲーム開始前
				prepareCountDown--;
				if ( prepareCountDown == 0 ) {
					AppManager.startSE();
				} else {
					AppManager.countSE();
				}
			} else if ( gameCountDown > 0 ) {

				//ゲーム中は一秒に1,2個の的を出現させる
				isGameStart = true;
				gameCountDown--;
				if ( initTargetList.size() > 0 ) {
					viewTargetList.add(initTargetList.remove(initTargetList.size() - 1));
				}
				if ( initTargetList.size() > 0 && gameCountDown % 2 == 0 ) {
					viewTargetList.add(initTargetList.remove(initTargetList.size() - 1));
				}
			} else if ( endDelayCount > 0 && initTargetList.size() <= 0 && viewTargetList.size() <= 0 ) {
				//全てのオブジェクトがなくなってから2秒間のインターバルを開ける
				endDelayCount--;
			} else if ( endDelayCount <= 0 ) {
				//2秒インターバルが0になったらリザルトアニメーションの開始
				isGameResult = true;

				//タイマーの終了
				timer.cancel();
			}
		}
	};

これで30秒経過後、画面内に的が残っていない場合に2秒間のインターバルを開けisGameResultがtrueになる処理ができました。

あとは、描画処理でこのフラグがtrueならリザルトの表示処理を実装すればできそうです。

表示処理はdrawメソッドに下記のようなプログラムを実装しました。

リザルトの計算は適当に的破壊数と最大コンボ数を得点に加算して結果にするような感じにします。80000点以上で最高のSランクが出るように単純なif文で判定しておきました。

せっかくなのでちょっとしたアニメーションも実装しておきます。

	//リザルトアニメーション
	FillRect fillRect = new FillRect(Color.BLACK, 0, 50, 800, 550);
	AnimationObject resultStringAnimationObject = new AnimationObject();
	SequenceAnimation resultAnimation;

	//初期化コンストラクタ
	public GameMode() {
		//結果のアニメーションオブジェクト群。完全透明で初期化
		fillRect.setOpacity(0f);
		resultStringAnimationObject.setOpacity(0f);
		FadeAnimation fadeAnimation = new FadeAnimation(fillRect, 0.02f);
		FadeAnimation fadeAnimation2 = new FadeAnimation(resultStringAnimationObject, 0.05f);
		fadeAnimation.setEndFramePoint(25);
		fadeAnimation2.setEndFramePoint(25);
		resultAnimation = new SequenceAnimation(fadeAnimation, fadeAnimation2);
	}
	public void draw(Graphics g) {
		if ( isGameResult ) {
			//ゲーム結果の描画処理

			//ブロックの描画
			for ( Block b : blockList ) {
				b.draw(g);
			}
			fillRect.draw(g);
			resultAnimation.update();

			GraphicsUtil.setAlpha(g, resultStringAnimationObject.getOpacity());

			g.setColor(Color.WHITE);
			g.setFont(statusFont);
			int result = (score + (breakNum * 100) + (maxCombo * 150));
			g.drawString("得点 : "+score, 150, 200);
			g.drawString("破壊数 : "+breakNum+" × 100 = "+(breakNum * 100), 150, 270);
			g.drawString("最大コンボ数 : "+maxCombo+" × 150 = "+(maxCombo * 150), 150, 340);
			g.drawString("合計 : "+(result)+" 点", 150, 410);
			String rank = "G";
			Color c = Color.LIGHT_GRAY;
			if ( result >= 80000 ) {
				rank = "S";
				c = Color.YELLOW;
			} else if ( result >= 70000 ) {
				rank = "A";
				c = Color.MAGENTA;
			} else if ( result >= 60000 ) {
				rank = "B";
				c = Color.RED;
			} else if ( result >= 50000 ) {
				rank = "C";
				c = Color.ORANGE;
			} else if ( result >= 40000 ) {
				rank = "D";
				c = Color.LIGHT_GRAY;
			} else if ( result >= 20000 ) {
				rank = "E";
				c = Color.LIGHT_GRAY;
			} else if ( result >= 10000 ) {
				rank = "F";
				c = Color.LIGHT_GRAY;
			}
			g.drawString("あなたの評価は ", 150, 480);
			g.setColor(c);
			g.setFont(new Font(Font.MONOSPACED, Font.BOLD, 60));
			g.drawString(rank, 400, 480);
			g.setColor(Color.WHITE);
			g.setFont(statusFont);
			g.drawString(" ランクです。", 445, 480);
			GraphicsUtil.setDefaultAlpha(g);
			//アニメーションが終了したら終了フラグを立てる
			if ( resultAnimation.isEnd() ) {
				isGameEnd = true;
			}
		}
	}

ここで初めて出てきたクラスであるFillRect、AnimationObject、SequenceAnimationはアニメーションさせるためのクラスです。

FillRectクラスは引数により表された、矩形を描画します。アニメーション結果の格納もでき、それを反映した描画処理を実行できます。暗転処理に利用します。

AnimationObjectクラスはアニメーション結果を格納できるクラスです。これは文字列のフェードインに利用します。

SequenceAnimationは引数のアニメーションを順番に実行するだけの単純な処理を実装できます。

今回は画面を25フレーム分暗転アニメーションさせ、その後25フレームで文字列のフェードインを実装しています。

プログラムは長くなってしまいましたが、一つ一つの処理は単純です。

最後に終了フラグであるisGameEndがtrueになったら、マウスクリックでタイトル画面に戻るようにしておきましょう。

	public void mouseClicked(MouseEvent e) {

		if ( isGameEnd ) {

			switch ( e.getButton() ) {
				case MouseEvent.BUTTON1:
					AppManager.change(ViewType.TITLE);
					break;
			}
		}
	}
実行結果

Java

Posted by nompor