JavaRush /Java Blog /Random-JA /JavaRush の「ゲーム」セクション: 役立つ理論

JavaRush の「ゲーム」セクション: 役立つ理論

Random-JA グループに公開済み
JavaRush の「ゲーム」セクション には、人気のあるコンピューター ゲームを作成するためのエキサイティングなプロジェクトが見つかります。人気の「2048」、「サッパー」、「スネーク」などのゲームの独自バージョンを作成してみませんか? それは簡単です。私たちはゲーム作成を段階的なプロセスに変えました。章ゲーム開発者として挑戦するには、高度なプログラマーである必要はありませんが、一定の Java 知識は依然として必要です。ここで見つかりますここには、ゲームを作成するときに役立つ情報が

1. 継承

JavaRush ゲーム エンジンの操作には、継承の使用が含まれます。しかし、それが何なのかわからない場合はどうすればよいでしょうか? 一方で、このトピックを理解する必要があります。このトピックはレベル 11で学習されます。一方、エンジンは意図的に非常にシンプルになるように設計されているため、継承に関する表面的な知識だけで問題なく対処できます。では、継承とは何でしょうか?非常に簡単に言うと、継承は 2 つのクラス間の関係です。そのうちの 1 つが親になり、2 つ目が子 (後継クラス) になります。この場合、親クラスは、子孫クラスがあることさえ知らない可能性があります。それらの。継承クラスの存在から特に恩恵を受けることはありません。しかし、継承は子孫クラスに多くの利点をもたらします。そして主なものは、あたかも親クラスのコードが子クラスにコピーされたかのように、親クラスのすべての変数とメソッドが子クラスに表示されることです。これは完全に真実ではありませんが、継承を簡単に理解するにはこれで十分です。継承をより深く理解するために、いくつかの例を示します。 例 1:最も単純な継承。
public class Родитель {

}
Childクラスは、extendsキーワードを使用してParentクラスから継承します。
public class Потомок extends Родитель {

}
例 2:親クラス変数の使用。
public class Родитель {

   public int age;
   public String name;
}
Childクラスは、Parentクラスのage変数とname変数を、その中で宣言されているかのように使用できます。
public class Потомок extends Родитель {

   public void printInfo() {

     System.out.println(name+" "+age);
   }
}
例 3:親クラスのメソッドの使用。
public class Родитель {

   public int age;
   public String name;

   public getName() {
      return name;
   }
}
Childクラスは、Parentクラスの変数とメソッドを、その中で宣言されているかのように使用できます。この例では、 getName () メソッドを使用しています。
public class Потомок extends Родитель {

   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}
コンパイラの観点から 見た子孫クラスは次のようになります。
public class Потомок extends Родитель {

   public int age; //  унаследованная переменная
   public String name; //  унаследованная переменная

   public getName() { //  унаследованный метод.
      return name;
  }
   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}

2. メソッドのオーバーライド

場合によっては、すべての変数とメソッドとともに、非常に便利な親クラスから子孫クラスを継承したにもかかわらず、一部のメソッドが希望どおりに動作しないという状況があります。あるいは、私たちが望んでいない方法ではまったくそうではありません。この状況ではどうすればよいでしょうか? 気に入らないメソッドをオーバーライドできます。これは非常に簡単に行われます。子孫クラスで、親クラスのメソッドと同じシグネチャ (ヘッダー) を持つメソッドを宣言し、その中にコードを記述するだけです。 例 1:メソッドのオーバーライド。
public class Родитель {

   public String name;

   public void setName (String nameNew) {
       name = nameNew;
  }

   public getName() {
      return name;
  }
}
printInfo() メソッドは「Luke、No!!!」というフレーズを出力します。
public class Потомок extends Родитель {

   public void setName (String nameNew) {
       name = nameNew + ",No!!!";
  }

   public void printInfo() {

      setName("Luke");
      System.out.println( getName());
   }
}
コンパイラの観点から 見た子孫クラスは次のようになります。
public Потомок extends Родитель {

   public String name; //  унаследованная переменная

   public void setName (String nameNew) { //  Переопределенный метод взамен унаследованного

       name = nameNew + ", No!!!";
   }
   public getName() { //  унаследованный метод.

      return name;
   }
   public void printInfo() {

     setName("Luke");
     System.out.println(getName());
   }
}
例 2:継承 (およびメソッドのオーバーライド) のちょっとした魔法。
public class Родитель {

   public getName() {
      return "Luke";
  }
   public void printInfo() {

     System.out.println(getName());
   }
}
public class Потомок extends Родитель {

   public getName() {
      return "I'm your father, Luke";
  }
}
この例では、 (Parent クラスの) メソッドがprintInfoDescendant クラスでオーバーライドされていない場合、このメソッドが Descendant クラスのオブジェクトに対して呼び出されるとき、Parent クラス getName()ではなく、そのメソッドが呼び出されます。getName()
Родитель parent = new Родитель ();
parent.printnInfo();
このコードは、画面に「Luke」という文字を表示します。
Потомок child = new Потомок ();
child.printnInfo();
このコードは、 「私はあなたの父親です、ルークです」という碑文を表示します。。
コンパイラの観点から 見た子孫クラスは次のようになります。
public class Потомок extends Родитель {

   public getName() {
      return "I'm your father, Luke";
   }
   public void printInfo() {

     System.out.println(getName());
   }
}

3. リスト

Lists をまだ知らない方は、ここで簡単な入門書をご覧ください。JavaRush コースのレベル 6 ~ 7に関する完全な情報を見つけることができます。 リストには配列と多くの共通点があります。
  • 特定の種類のデータを大量に保存できる。
  • インデックス/番号によって要素を取得できます。
  • 要素のインデックスは 0 から始まります。
リストの利点: 配列とは異なり、リストはサイズを動的に変更できます。作成直後のリストのサイズは 0 です。リストに要素を追加すると、リストのサイズが増加します。リストの作成例:
ArrayList<String> myList = new ArrayList<String>(); // создание нового списка типа ArrayList
山かっこ内の値は、リストに保存できるデータのタイプです。リストを操作するためのいくつかのメソッドを次に示します。
コード コードの動作の簡単な説明
ArrayList<String> list = new ArrayList<String>(); 文字列の新しいリストを作成する
list.add("name"); リストの最後に要素を追加します
list.add(0, "name"); リストの先頭に要素を追加します
String name = list.get(5); インデックスで要素を取得する
list.set(5, "new name"); インデックスで要素を変更する
int count = list.size(); リスト内の要素の数を取得する
list.remove(4); リストから項目を削除する
リストの詳細については、次の記事を参照してください。
  1. ArrayList クラス
  2. 写真の作業配列リスト
  3. ArrayList からの要素の削除

4. 配列

マトリックスとは何ですか? マトリックスは、データを入力できる長方形のテーブルにすぎません。言い換えれば、それは二次元配列です。おそらくご存知のとおり、Java の配列はオブジェクトです。標準的な 1 次元配列型はint次のようになります。
int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
これを視覚的に想像してみましょう。
0 1 2 3 4 5 6 7
12 32 43 54 15 36 67 28
一番上の行はセルアドレスを示します。つまり、数値 67 を取得するには、インデックス 6 の配列要素にアクセスする必要があります。
int number = array[6];
ここではすべてが非常にシンプルです。2 次元配列は 1 次元配列の配列です。このことについて初めて聞いた場合は、立ち止まって頭の中で想像してください。2 次元配列は次のようになります。
0 1次元配列 1次元配列
1 1次元配列
2 1次元配列
3 1次元配列
4 1次元配列
5 1次元配列
6 1次元配列
7 1次元配列
コード内:
int [][] matrix = {
{65, 99, 87, 90, 156, 75, 98, 78}, {76, 15, 76, 91, 66, 90, 15, 77}, {65, 96, 17, 25, 36, 75, 54, 78}, {59, 45, 68, 14, 57, 1, 9, 63}, {81, 74, 47, 52, 42, 785, 56, 96}, {66, 74, 58, 16, 98, 140, 55, 77}, {120, 99, 13, 90, 78, 98, 14, 78}, {20, 18, 74, 91, 96, 104, 105, 77} }
0 0 1 2 3 4 5 6 7
65 99 87 90 156 75 98 78
1 0 1 2 3 4 5 6 7
76 15 76 91 66 90 15 77
2 0 1 2 3 4 5 6 7
65 96 17 25 36 75 54 78
3 0 1 2 3 4 5 6 7
59 45 68 14 57 1 9 63
4 0 1 2 3 4 5 6 7
81 74 47 52 42 785 56 96
5 0 1 2 3 4 5 6 7
66 74 58 16 98 140 55 77
6 0 1 2 3 4 5 6 7
120 99 13 90 78 98 14 78
7 0 1 2 3 4 5 6 7
20 18 74 91 96 104 105 77
値 47 を取得するには、[4][2] の行列要素にアクセスする必要があります。
int number = matrix[4][2];
お気づきかと思いますが、行列座標は古典的な直交座標系 (デカルト座標系) とは異なります。行列にアクセスするときは、最初に y を指定し、次に x を指定しますが、数学では最初に x(x, y) を指定するのが一般的です。「想像の中で行列を逆にして、(x, y) を介して通常の方法で要素にアクセスしてみてはどうでしょうか?」と自問するかもしれません。これによってマトリックスの内容が変更されることはありません。」はい、何も変わりません。しかし、プログラミングの世界では、「最初に y、次に x」という形式で行列を参照するのが通例です。これは当然のことと考えなければなりません。次に、行列をエンジン (クラスGame) に投影する方法について話しましょう。ご存知のとおり、エンジンには、指定された座標で競技場のセルを変更するメソッドが多数あります。たとえば、setCellValue(int x, int y, String value)。座標 (x, y) を持つ特定のセルを値 に設定しますvalue。お気づきのとおり、このメソッドは、古典的な座標系と同様に、最初に正確に x を取得します。残りのエンジン メソッドも同様に機能します。ゲームを開発する場合、画面上でマトリクスの状態を再現する必要が生じることがよくあります。これを行う方法?まず、ループ内で行列のすべての要素を反復処理する必要があります。次に、それぞれに対して、INVERTED 座標で表示するメソッドを呼び出します。例:
private void drawScene() {
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            setCellValue(j, i, String.valueOf(matrix[i][j]));
        }
    }
}
当然のことながら、反転は 2 つの方向に機能します。メソッド内setCellValue渡すことができますが、同時に行列から要素 [j][i] を取得します。逆変換は少し難しく感じるかもしれませんが、覚えておいてください。そして、何か問題が発生した場合は、必ずペンで紙を取り、マトリックスを描き、それにどのようなプロセスが起こっているかを再現する価値があります。

5. 乱数

乱数ジェネレーターを使用するにはどうすればよいですか? クラスはGameメソッドを定義しますgetRandomNumber(int)。内部ではRandomjava.util パッケージのクラスを使用しますが、乱数ジェネレーターを使用する原理は変わりません。議論としてgetRandomNumber(int)整数を受け取ります。この数値は、ジェネレーターが返すことができる上限になります。下限は 0 です。 重要! ジェネレーターは決して上限数値を返しません。たとえば、getRandomNumber(3)ランダムに呼び出された場合は 0、1、2 を返すことができます。ご覧のとおり、3 を返すことはできません。ジェネレーターのこの使用法は非常に簡単ですが、多くの場合に非常に効果的です。 いくつかの制限内で乱数を取得する必要があります。3 桁の数字 (100..999) が必要であると想像してください。ご存知のとおり、返される最小値は 0 なので、それに 100 を加える必要がありますが、この場合、上限を超えないように注意する必要があります。最大ランダム値として 999 を取得するには、getRandomNumber(int)引数 1000 を指定してメソッドを呼び出す必要があります。ただし、その後に 100 を追加することを覚えています。これは、上限を 100 下げる必要があることを意味します。つまり、 3 桁のランダムな数値は次のようになります。
int number = 100 + getRandomNumber(900);
ただし、このような手順を簡素化するために、エンジンはgetRandomNumber(int, int)最初の引数として返す最小値を取るメソッドを提供します。このメソッドを使用すると、前の例を次のように書き直すことができます。
int number = getRandomNumber(100, 1000);
乱数を使用して、ランダムな配列要素を取得できます。
String [] names = {"Andrey", "Валентин", "Сергей"};
String randomName = names[getRandomNumber(names.length)]
一定の確率で特定のイベントを引き起こす。 人の朝は考えられるシナリオに従って始まります。寝坊 – 50%。時間通りに起きた - 40%。予定より 1 時間早く起きました – 10%。人間の朝エミュレータを作成していると想像してください。一定の確率でイベントを発生させる必要があります。これを行うには、やはり乱数発生器を使用する必要があります。実装は異なる場合がありますが、最も単純な実装は次のアルゴリズムに従う必要があります。
  1. 数値を生成する必要がある制限を設定します。
  2. 乱数を生成します。
  3. 結果の数値を処理します。
したがって、この場合、制限は 10 になります。メソッドを呼び出してgetRandomNumber(10)、何が返されるかを分析してみましょう。10 桁 (0 ~ 9) を同じ確率 (10%) で返すことができます。次に、考えられるすべての結果を組み合わせて、考えられるイベントと一致させる必要があります。想像力次第でたくさんの組み合わせが考えられますが、最もわかりやすいのは次のような音です。「乱数が [0..4] の範囲内にある場合 - 数値が [5..8] の範囲内にある場合はイベントを「寝坊」と呼びます。 ] - 時間通りに「起きます」、数字が 9 の場合のみ、「予定より 1 時間早く起きました」。すべては非常に単純です。[0..4] 内には 5 つの数値があり、それぞれが 10% の確率で返され、合計は 50% になります。[5..8] 内には 4 つの数字があり、10% の確率で現れる数字は 9 だけです。コードでは、この賢い設計全体がさらに単純に見えます。
int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
    System.out.println("Проспал ");
} else if (randomNumber < 9) {
    System.out.println("Встал вовремя ");
} else {
    System.out.println("Встал на час раньше положенного ");
}
一般に、乱数を使用するには多くのオプションがあります。それはすべてあなたの想像力にのみ依存します。ただし、何らかの結果を繰り返し取得する必要がある場合に最も効果的に使用されます。すると、この結果は前の結果とは異なるものになります。もちろん、ある程度の確率で。それだけです!「ゲーム」セクションについてさらに詳しく知りたい場合は、次の役立つドキュメントを参照してください。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION