こんにちは、運営者のハックです!
Javaコース上級ミニゲーム開発編Day12の今回は作成したミニゲームの内容をさらにブラシュアップさせたので、その内容を紹介します。
ミニゲームの内容をブラシュアップさせよう
前回でミニゲーム課題の要件は達成しましたが、今回からはさらにミニゲームの内容をブラシュアップして、ゲームとして面白くなるような追加機能やミニゲームを快適にプレイできるように機能を追加していきます。
今回は主にゲームプレイに面白さがプラスされるように機能を追加しました。
採掘した鉱石の種類と点数が表示されるようにメッセージを変更しよう
現在は、どの鉱石を破壊してもメッセージは「ブロックを壊した!現在のスコアは〇〇点です!」と表示されるだけでした。このメッセージを鉱石の種類と点数も表示されるように修正しました。
実際のコードと実行結果
//OreMiningCommandクラス
public void onBlockBreak(BlockBreakEvent e) {
…
Material blockType = e.getBlock().getType();
String oreName;
int point = switch (blockType) {
case COPPER_ORE -> { oreName = "銅鉱石"; yield 5; }
case COAL_ORE -> { oreName = "石炭鉱石"; yield 10; }
case IRON_ORE -> { oreName = "鉄鉱石"; yield 15; }
case GOLD_ORE -> { oreName = "金鉱石"; yield 20; }
case LAPIS_ORE -> { oreName = "ラピスラズリ鉱石"; yield 25; }
case REDSTONE_ORE -> { oreName = "レッドストーン鉱石"; yield 50; }
case EMERALD_ORE -> { oreName = "エメラルド鉱石"; yield 150; }
case DIAMOND_ORE -> { oreName = "ダイヤモンド鉱石"; yield 500; }
default -> { oreName = "その他"; yield -1; }
};
if (point != -1) {
p.setScore(p.getScore() + point);
player.sendMessage(oreName + "を採掘した!" + oreName + "は" +
point + "点!" +"現在のスコアは" + p.getScore() + "点です!");
}
「yield」って何にゃあ?初めて見るのにゃ。
Javaのswitch式におけるyieldは、特定の値を返すために使用されます。これは従来のswitch文のbreakに似ていますが、値を返す点が異なります。yieldを使用することで、switch式の各ケースから直接値を返し、その値を変数に割り当てることができます。
このyieldの機能はJava 14以降で正式な機能となっています。
鉱石の種類と点数をメッセージに含めることができました。
連続で同じ鉱石ブロックを破壊するとボーナス点を獲得するように実装
デイトラ課題で難易度を上げるアイデアとして出ていた「鉱石の取得数により追加スコアを付与する」というアイデアを参考にして、「同じ鉱石ブロックを5回及び10回連続で破壊するとボーナスポイントを付与する」状態を実装しました。
実際のコードと実行結果
//OreMiningCommandクラス
public void onBlockBreak(BlockBreakEvent e) {
…
int basePoint = switch (blockType) {
… };
//その他ブロックの破壊時、それ以上なにもしない。
if (basePoint == -1) return;
//プレイヤーが連続して同じ種類の鉱石を破壊しているかをチェックし、カウントします。
if (blockType == p.getLastOreType()) {
p.setConsecutiveOreCount(p.getConsecutiveOreCount() + 1);
} else {
p.setConsecutiveOreCount(1);
p.setLastOreType(blockType);
}
int bonus = 0;
switch (p.getConsecutiveOreCount()) {
case 5 -> {
bonus = 50;
player.sendMessage("ボーナスポイント!" + oreName + "を5回連続で破壊しました。
+50点!");
}
case 10 -> {
bonus = 100;
player.sendMessage("大ボーナスポイント!" + oreName + "を10回連続で破壊しました。
+100点!");
}
}
int totalPoints = basePoint + bonus;
p.setScore(p.getScore() + totalPoints);
player.sendMessage(oreName + "を採掘した!" + oreName + "は" +
basePoint + "点!" + "現在のスコアは" + p.getScore() + "点です!");
});
//ExecutingPlayerクラス
public class ExecutingPlayer {
…
private Material lastOreType;
private int consecutiveOreCount;
public ExecutingPlayer(String playerName){
this.playerName = playerName;
this.lastOreType = null;
this.consecutiveOreCount = 0;
}
//PlayerScore クラス
public class PlayerScore {
…
private Material lastOreType;
private int consecutiveOreCount;
public PlayerScore(String playerName, int score){
this.playerName = playerName;
this.score = score;
this.consecutiveOreCount = 0;
this.lastOreType = null;
}
ボーナスポイント実装でさらにゲームらしくなったのにゃ!
高得点の鉱石を探すか、簡単に見つかる鉱石の狙ってボーナスポイントを稼ぐか、プレイングスタイルが変わってくるのにゃ。
個人的なポイントは「if (blockType == p.getLastOreType()){p.setConsecutiveOreCount(p.getConsecutiveOreCount() + 1);
} else {
p.setConsecutiveOreCount(1);p.setLastOreType(blockType);}」の箇所です。
このブロックで、もし最後に破壊した鉱石と同じ種類であれば連続破壊数を1増やし、異なる種類の鉱石を破壊した場合は、連続破壊数を1にリセットし破壊した鉱石の種類を記録するように実装しました。
同じ鉱石ブロックを5回及び10回破壊するとボーナスポイントが加算されるように実装できました。
実装するにあたり、以下の点が満たされていることを確認しました。
- 「その他ブロック」が連続で破壊されてもボーナス点が加算されないこと
- ゲーム実行時以外ではボーナス点を含む点数が加算されないこと
- 連続で同じ鉱石ブロックを破壊しても、違う種類の鉱石ブロックを破壊した場合、ボーナスカウントがリセットされていること
不具合が生じた場合、その都度コードを修正して確認しています。
まとめ 正解がないため手探り状態で実装しています
今回は「鉱石の種類に応じて種類と点数をメッセージに追加する」「連続で同じ鉱石ブロックを破壊するとボーナス点が追加される」ように実装し、ゲームとしての面白さを追加しました。
結果だけ表示すると、あたかも簡単に実装できているように見えますが、実際は手探り状態でコードを作成しています。
IntelliJの機能を使ってエラーを解消し、追加した機能にバグや不具合がないか確認するため色々な想定でテストし、可能であればリファクタリングして…想像よりも時間がかかっています。
単純で簡単なゲームですらこんなに時間がかかるのに、我々が普段遊ぶSwitchやプレステーション等のゲームソフトは一体どれだけの労力と時間を費やしているのでしょうか。制作現場の方々が改めて凄いのだと感じます。
コメント