フィフティーン、またはフィフティーンは、世界中で人気のあるシンプルなロジックゲームの素晴らしい例です。 パズルを解くには、小さい方から大きい方へ順番に正方形を数字で並べる必要があります。 簡単ではありませんが、面白いです。
本日のチュートリアルでは、EclipseでJava 8で15を開発する方法を示します。 UIを開発するには、Swing APIを使用します。
「Habr」の読者には、「Habr」プロモーションコードを使用してSkillboxコースに登録すると10,000ルーブルの割引があります。
Skillboxの推奨事項:オンライン教育コース「Profession Java-developer」 。
ゲームデザイン
この段階で、プロパティを定義する必要があります。
- サイズ-競技場のサイズ。
- nbTiles-フィールド内のスポットの数。 nbTiles =サイズ*サイズ-1;
- Tilesはタグであり、整数の1次元配列です。 各タグは、範囲[0、nbTiles]の一意の値を受け取ります。 ゼロは空の正方形を示します。
- blankPos-空の正方形の位置。
ゲームロジック
新しいゲーム位置を初期化するために使用されるリセット方法を定義する必要があります。 そこで、タグ配列の各要素に値を設定します。 それでは、配列の最後の位置にblankPosを配置します。
タグの配列をシャッフルするには、shuffleメソッドも必要です。 シャッフルプロセスに空のタグを含めて、元の位置のままにすることはありません。
パズルの可能な開始位置の半分しか解決策がないため、結果のミキシング結果を確認して、現在のレイアウトが一般的に解決されていることを確認する必要があります。 これを行うには、isSolvableメソッドを定義します。
特定のタグの前に高い値のタグが付いている場合、これは反転と見なされます。 空のタグが配置されている場合、パズルを解くには反転の数が偶数である必要があります。 したがって、反転の数をカウントし、その数が偶数の場合はtrueを返します。
その後、isSolvedメソッドを定義して、Game Of 15のアライメントが解決されたかどうかを確認することが重要です。 最初に、空のタグの場所を調べます。 初期位置にある場合、現在のアライメントは新しいものであり、以前に決定されていません。 次に、タイルを逆の順序で繰り返し処理し、タグの値が対応するインデックス+1と異なる場合、falseを返します。 そうでなければ、パズルはすでに解決されているため、メソッドの最後にtrueを返す時間です。
定義する別のメソッドはnewGameです。 ゲームの新しいインスタンスを作成する必要があります。 これを行うには、プレイフィールドをリセットしてからシャッフルし、プレイ位置が解決可能になるまで続けます。
キータグロジックを使用したサンプルコードを次に示します。
private void newGame() { do { reset();
最後に、アレイ内のスポットの動きをプログラムする必要があります。 このコードは、カーソルの移動に応答するコールバックを介して後で呼び出されます。 このゲームは、複数のタイルの移動を同時にサポートします。 したがって、画面上の押された位置をタグに変換した後、空のタグの位置を取得し、動きの方向を探してその動きのいくつかを同時にサポートします。
サンプルコードを次に示します。
Swing APIでUIを開発します
インターフェースを実行する時が来ました。 まず、Jpanelクラスを使用します。 次に、フィールドにスポットを描画します-それぞれのサイズを計算するために、ゲームのコンストラクターパラメーターで指定されたデータを使用します。
gridSize = (dim - 2 * margin); tileSize = gridSize / size;
マージンは、ゲームコンストラクターで指定されるパラメーターでもあります。
次に、グリッドとスポットを画面に描画するためにdrawGridメソッドを定義する必要があります。 タグの配列を分析し、座標をユーザーインターフェイスの座標に変換します。 次に、中央に対応する番号を持つ各タグを描画します。
private void drawGrid(Graphics2D g) { for (int i = 0; i < tiles.length; i++) {
最後に、JPaneクラスの派生物であるpaintComponentメソッドを再定義します。 次にdrawGridメソッドを使用し、その後drawStartMessageメソッドを使用して、クリックしてゲームを開始するように促すメッセージを表示します。
private void drawStartMessage(Graphics2D g) { if (gameOver) { g.setFont(getFont().deriveFont(Font.BOLD, 18)); g.setColor(FOREGROUND_COLOR); String s = "Click to start new game"; g.drawString(s, (getWidth() - g.getFontMetrics().stringWidth(s)) / 2, getHeight() - margin); } } private void drawCenteredString(Graphics2D g, String s, int x, int y) {
UIでのユーザーアクションに応答します
ゲームがコースを取るためには、UIでユーザーアクションを処理する必要があります。 これを行うには、JpanelにMouseListener実装を追加し、既に上に示したスポットを移動するためのコードを追加します。
addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) {
GameOfFifteenクラスのコンストラクターにコードを配置します。 最後に、newGameメソッドを呼び出して新しいゲームを開始します。
完全なゲームコード
ゲームの動作を確認する前の最後のステップは、すべてのコード要素を一緒に収集することです。 結果は次のとおりです。
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities;
最後に、プレイ!
ゲームを開始し、動作を確認する時が来ました。 フィールドは次のようになります。

パズルを解こうとしています。 すべてがうまくいけば、これが得られます:

以上です。 もっと期待しましたか? :)
Skillboxの推奨事項: