JavaRush /Blog Java /Random-MS /Bahagian "Permainan" pada JavaRush: Teori berguna

Bahagian "Permainan" pada JavaRush: Teori berguna

Diterbitkan dalam kumpulan
Dalam bahagian "Permainan" JavaRush anda akan menemui projek menarik untuk menulis permainan komputer yang popular. Adakah anda ingin mencipta versi anda sendiri bagi permainan popular "2048", "Sapper", "Snake" dan lain-lain? Mudah sahaja. Kami telah mengubah penulisan permainan menjadi proses langkah demi langkah. BabUntuk mencuba diri anda sebagai pembangun permainan, anda tidak perlu menjadi pengaturcara lanjutan, tetapi set pengetahuan Java tertentu masih diperlukan. Di sini anda akan mendapat maklumat yang berguna semasa menulis permainan .

1. Warisan

Bekerja dengan enjin permainan JavaRush melibatkan penggunaan warisan. Tetapi bagaimana jika anda tidak tahu apa itu? Di satu pihak, anda perlu memahami topik ini: ia dipelajari pada tahap 11 . Sebaliknya, enjin itu sengaja direka untuk menjadi sangat mudah, supaya anda boleh bertahan dengan pengetahuan yang cetek tentang warisan. Jadi, apakah warisan? Secara ringkasnya, warisan ialah hubungan antara dua kelas. Salah seorang daripada mereka menjadi ibu bapa, dan yang kedua menjadi anak (kelas pengganti). Dalam kes ini, kelas induk mungkin tidak tahu bahawa ia mempunyai kelas keturunan. Itu. ia tidak menerima apa-apa faedah tertentu daripada kehadiran kelas pewaris. Tetapi warisan memberikan banyak kelebihan kepada kelas keturunan. Dan yang utama ialah semua pembolehubah dan kaedah kelas induk muncul dalam kelas anak, seolah-olah kod kelas induk telah disalin ke dalam kelas anak. Ini tidak sepenuhnya benar, tetapi untuk pemahaman yang dipermudahkan tentang warisan, ia akan dilakukan. Berikut ialah beberapa contoh untuk lebih memahami pewarisan. Contoh 1: pewarisan yang paling mudah.
public class Родитель {

}
Kelas Anak mewarisi daripada kelas Induk menggunakan kata kunci lanjutan .
public class Потомок extends Родитель {

}
Contoh 2: Menggunakan pembolehubah kelas induk.
public class Родитель {

   public int age;
   public String name;
}
Kelas Kanak-kanak boleh menggunakan pembolehubah umur dan nama kelas Induk seolah-olah ia diisytiharkan di dalamnya.
public class Потомок extends Родитель {

   public void printInfo() {

     System.out.println(name+" "+age);
   }
}
Contoh 3: Menggunakan kaedah kelas induk.
public class Родитель {

   public int age;
   public String name;

   public getName() {
      return name;
   }
}
Kelas Anak boleh menggunakan pembolehubah dan kaedah kelas Induk seolah-olah ia diisytiharkan di dalamnya. Dalam contoh ini kita menggunakan kaedah getName ().
public class Потомок extends Родитель {

   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}
Inilah rupa kelas Descendant dari sudut pandangan pengkompil:
public class Потомок extends Родитель {

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

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

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

2. Kaedah mengatasi

Kadangkala terdapat situasi yang kami mewarisi kelas Descendant kami daripada beberapa kelas Induk yang sangat berguna, bersama-sama dengan semua pembolehubah dan kaedah, tetapi beberapa kaedah tidak berfungsi dengan tepat seperti yang kami mahu. Atau tidak sama sekali dengan cara yang kita tidak mahu. Apa yang perlu dilakukan dalam keadaan ini? Kita boleh mengatasi kaedah yang kita tidak suka. Ini dilakukan dengan sangat mudah: dalam kelas Descendant kami, kami hanya mengisytiharkan kaedah dengan tandatangan (pengepala) yang sama dengan kaedah kelas Induk dan tulis kod kami di dalamnya. Contoh 1: Kaedah mengatasi.
public class Родитель {

   public String name;

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

   public getName() {
      return name;
  }
}
Kaedah printInfo() akan mencetak frasa "Luke, No!!!"
public class Потомок extends Родитель {

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

   public void printInfo() {

      setName("Luke");
      System.out.println( getName());
   }
}
Inilah rupa kelas Descendant dari sudut pandangan pengkompil:
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());
   }
}
Contoh 2: sedikit sihir pewarisan (dan kaedah mengatasi).
public class Родитель {

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

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

   public getName() {
      return "I'm your father, Luke";
  }
}
Dalam contoh ini: jika kaedah printInfo(dari kelas Induk) tidak ditindih dalam kelas Keturunan, apabila kaedah ini dipanggil pada objek kelas Keturunan, kaedahnya akan dipanggil getName(), dan bukan getName()kelas Induk.
Родитель parent = new Родитель ();
parent.printnInfo();
Kod ini memaparkan tulisan "Lukas" pada skrin .
Потомок child = new Потомок ();
child.printnInfo();
Kod ini memaparkan tulisan "Saya bapa awak, Luke;" .
Inilah rupa kelas Descendant dari sudut pandangan pengkompil:
public class Потомок extends Родитель {

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

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

3. Senarai

Jika anda masih belum diperkenalkan dengan Senarai, berikut ialah buku asas ringkas. Anda boleh mendapatkan maklumat lengkap tentang tahap 6-7 kursus JavaRush . Senarai mempunyai banyak persamaan dengan tatasusunan:
  • boleh menyimpan banyak data dari jenis tertentu;
  • membolehkan anda mendapatkan semula elemen mengikut indeks/nombornya;
  • indeks elemen bermula pada 0.
Kelebihan senarai: Tidak seperti tatasusunan, senarai boleh menukar saiz secara dinamik. Sejurus selepas penciptaan, senarai mempunyai saiz 0. Apabila anda menambah elemen pada senarai, saiznya bertambah. Contoh membuat senarai:
ArrayList<String> myList = new ArrayList<String>(); // создание нового списка типа ArrayList
Nilai dalam kurungan sudut ialah jenis data yang boleh disimpan oleh senarai. Berikut ialah beberapa kaedah untuk bekerja dengan senarai:
Kod Penerangan ringkas tentang perkara yang dilakukan oleh kod
ArrayList<String> list = new ArrayList<String>(); Mencipta senarai rentetan baharu
list.add("name"); Tambahkan elemen pada penghujung senarai
list.add(0, "name"); Tambahkan elemen pada permulaan senarai
String name = list.get(5); Dapatkan elemen mengikut indeksnya
list.set(5, "new name"); Tukar elemen mengikut indeksnya
int count = list.size(); Dapatkan bilangan elemen dalam senarai
list.remove(4); Alih keluar item daripada senarai
Anda boleh mengetahui lebih lanjut tentang senarai daripada artikel ini:
  1. Kelas ArrayList
  2. Working ArrayList dalam gambar
  3. Mengalih keluar elemen daripada ArrayList

4. Tatasusunan

Apakah matriks? Matriks tidak lebih daripada jadual segi empat tepat yang boleh diisi dengan data. Dalam erti kata lain, ia adalah tatasusunan dua dimensi. Seperti yang anda ketahui, tatasusunan dalam Java adalah objek. Jenis tatasusunan satu dimensi standard intkelihatan seperti ini:
int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
Mari bayangkan ini secara visual:
0 1 2 3 4 5 6 7
12 32 43 54 15 36 67 28
Baris atas menunjukkan alamat sel. Iaitu, untuk mendapatkan nombor 67, anda perlu mengakses elemen tatasusunan dengan indeks 6:
int number = array[6];
Semuanya sangat mudah di sini. Tatasusunan dua dimensi ialah tatasusunan tatasusunan satu dimensi. Jika ini kali pertama anda mendengar tentang perkara ini, berhenti dan bayangkan dalam kepala anda. Tatasusunan dua dimensi kelihatan seperti ini:
0 Tatasusunan satu dimensi Tatasusunan satu dimensi
1 Tatasusunan satu dimensi
2 Tatasusunan satu dimensi
3 Tatasusunan satu dimensi
4 Tatasusunan satu dimensi
5 Tatasusunan satu dimensi
6 Tatasusunan satu dimensi
7 Tatasusunan satu dimensi
Dalam kod:
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
Untuk mendapatkan nilai 47, anda perlu mengakses elemen matriks di [4][2].
int number = matrix[4][2];
Jika anda perasan, koordinat matriks adalah berbeza daripada sistem koordinat segi empat tepat klasik (sistem koordinat Cartesian). Apabila mengakses matriks, anda nyatakan y dahulu dan kemudian x , manakala dalam matematik adalah biasa untuk menentukan x(x, y) dahulu. Anda mungkin bertanya kepada diri sendiri, "Mengapa tidak membalikkan matriks dalam imaginasi anda dan mengakses elemen dengan cara biasa melalui (x, y)? Ini tidak akan mengubah kandungan matriks.” Ya, tiada apa yang akan berubah. Tetapi dalam dunia pengaturcaraan, adalah kebiasaan untuk merujuk kepada matriks dalam bentuk "y pertama, kemudian x." Ini mesti diambil mudah. Sekarang mari kita bincangkan tentang menayangkan matriks ke enjin kita (kelas Game). Seperti yang anda ketahui, enjin mempunyai banyak kaedah yang mengubah sel-sel medan permainan pada koordinat yang diberikan. Sebagai contoh, setCellValue(int x, int y, String value). Ia menetapkan sel tertentu dengan koordinat (x, y) kepada nilai value. Seperti yang anda perhatikan, kaedah ini mula-mula mengambil tepat x, seperti dalam sistem koordinat klasik. Selebihnya kaedah enjin berfungsi dengan cara yang sama. Apabila membangunkan permainan, selalunya terdapat keperluan untuk menghasilkan semula keadaan matriks pada skrin. Bagaimana untuk melakukan ini? Pertama, dalam satu gelung anda perlu mengulangi semua elemen matriks. Kedua, bagi setiap daripada mereka, panggil kaedah untuk dipaparkan dengan koordinat TERBALIK. Contoh:
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]));
        }
    }
}
Sememangnya, penyongsangan berfungsi dalam dua arah. setCellValueAnda boleh menghantar (i, j) kepada kaedah , tetapi pada masa yang sama mengambil elemen [j][i] daripada matriks. Penyongsangan mungkin kelihatan agak sukar, tetapi ia adalah sesuatu yang perlu diingat. Dan selalu, jika sebarang masalah timbul, ia patut mengambil sekeping kertas dengan pen, melukis matriks dan menghasilkan semula proses yang berlaku kepadanya.

5. Nombor rawak

Bagaimana untuk bekerja dengan penjana nombor rawak? Kelas Gamementakrifkan kaedah getRandomNumber(int). Di bawah tudung, ia menggunakan kelas Randomdaripada pakej java.util, tetapi ini tidak mengubah prinsip bekerja dengan penjana nombor rawak. getRandomNumber(int)Mengambil integer sebagai hujah . Nombor ini akan menjadi sempadan atas yang boleh dipulangkan oleh penjana. Had bawah ialah 0. Penting! Penjana TIDAK akan mengembalikan nombor sempadan atas. Sebagai contoh, jika dipanggil getRandomNumber(3)secara rawak ia boleh mengembalikan 0, 1, 2. Seperti yang anda lihat, ia tidak boleh mengembalikan 3. Penggunaan penjana ini agak mudah, tetapi sangat berkesan dalam banyak kes. Anda perlu mendapatkan nombor rawak dalam beberapa had: Bayangkan anda memerlukan beberapa nombor tiga digit (100..999). Seperti yang anda sedia maklum, nombor minimum yang dikembalikan ialah 0. Jadi, anda perlu menambah 100 padanya. Tetapi dalam kes ini, anda perlu berhati-hati untuk tidak melebihi had atas. Untuk mendapatkan 999 sebagai nilai rawak maksimum, anda harus memanggil kaedah getRandomNumber(int)dengan hujah 1000. Tetapi kita ingat tentang penambahan 100 berikutnya: ini bermakna bahawa sempadan atas harus diturunkan sebanyak 100. Iaitu, kod untuk mendapatkan a nombor tiga digit rawak akan kelihatan seperti ini:
int number = 100 + getRandomNumber(900);
Tetapi untuk memudahkan prosedur sedemikian, enjin menyediakan kaedah getRandomNumber(int, int)yang mengambil nombor minimum untuk kembali sebagai hujah pertama. Menggunakan kaedah ini, contoh sebelumnya boleh ditulis semula:
int number = getRandomNumber(100, 1000);
Nombor rawak boleh digunakan untuk mendapatkan elemen tatasusunan rawak:
String [] names = {"Andrey", "Валентин", "Сергей"};
String randomName = names[getRandomNumber(names.length)]
Mencetuskan peristiwa tertentu dengan kebarangkalian tertentu. Pagi seseorang bermula mengikut senario yang mungkin: Terlalu tidur - 50%; Bangun tepat pada masanya - 40%; Bangun sejam lebih awal daripada jangkaan – 10%. Bayangkan anda sedang menulis emulator pagi manusia. Anda perlu mencetuskan peristiwa dengan kebarangkalian tertentu. Untuk melakukan ini, sekali lagi, anda perlu menggunakan penjana nombor rawak. Pelaksanaan mungkin berbeza, tetapi yang paling mudah harus mengikut algoritma berikut:
  1. kami menetapkan had di mana bilangan itu perlu dijana;
  2. menjana nombor rawak;
  3. Kami memproses nombor yang terhasil.
Jadi, dalam kes ini, hadnya ialah 10. Mari kita panggil kaedah getRandomNumber(10)dan analisa apa yang ia boleh kembalikan kepada kita. Ia boleh mengembalikan 10 digit (dari 0 hingga 9) dan setiap satu dengan kebarangkalian yang sama - 10%. Sekarang kita perlu menggabungkan semua hasil yang mungkin dan memadankannya dengan kemungkinan acara kita. Terdapat banyak kombinasi, bergantung pada imaginasi anda, tetapi bunyi yang paling jelas: "Jika nombor rawak terletak dalam [0..4] - panggil acara "Terlebih Tidur", jika nombor itu berada dalam [5..8 ] - "Bangun" tepat pada masanya," dan hanya jika nombornya ialah 9, maka "Saya bangun sejam lebih awal daripada jangkaan." Segala-galanya sangat mudah: dalam [0..4] terdapat 5 nombor, setiap satunya boleh kembali dengan kebarangkalian 10%, yang kesemuanya ialah 50%; dalam [5..8] terdapat 4 nombor, dan 9 adalah satu-satunya nombor yang muncul dengan kebarangkalian 10%. Dalam kod, keseluruhan reka bentuk pintar ini kelihatan lebih mudah:
int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
    System.out.println("Проспал ");
} else if (randomNumber < 9) {
    System.out.println("Встал вовремя ");
} else {
    System.out.println("Встал на час раньше положенного ");
}
Secara umum, terdapat banyak pilihan untuk menggunakan nombor rawak. Semuanya hanya bergantung pada imaginasi anda. Tetapi mereka paling berkesan digunakan jika anda perlu mendapatkan beberapa hasil berulang kali. Kemudian keputusan ini akan berbeza daripada yang sebelumnya. Dengan beberapa kebarangkalian, sudah tentu. Itu sahaja! Jika anda ingin mengetahui lebih lanjut tentang bahagian Permainan, berikut ialah beberapa dokumentasi berguna yang boleh membantu:
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION