JavaRush /Java Blog /Random-ID /Bagian "Permainan" di JavaRush: Teori yang berguna

Bagian "Permainan" di JavaRush: Teori yang berguna

Dipublikasikan di grup Random-ID
Di bagian “Game” JavaRush Anda akan menemukan proyek menarik untuk menulis game komputer populer. Apakah Anda ingin membuat versi Anda sendiri dari game populer “2048”, “Sapper”, “Snake” dan lainnya? Itu mudah. Kami telah mengubah penulisan game menjadi proses langkah demi langkah. BabUntuk mencoba diri Anda sendiri sebagai pengembang game, Anda tidak harus menjadi pemrogram tingkat lanjut, namun pengetahuan Java tertentu tetap diperlukan. Di sini Anda akan menemukan informasi yang berguna saat menulis permainan .

1. Warisan

Bekerja dengan mesin game JavaRush melibatkan penggunaan warisan. Tapi bagaimana jika Anda tidak tahu apa itu? Di satu sisi, Anda perlu memahami topik ini: topik ini dipelajari di level 11 . Di sisi lain, mesinnya sengaja didesain sangat sederhana, sehingga Anda bisa bertahan dengan pengetahuan yang dangkal tentang warisan. Jadi, apa itu warisan? Sederhananya, pewarisan adalah hubungan antara dua kelas. Salah satunya menjadi orang tua, dan yang kedua menjadi anak (kelas penerus). Dalam hal ini, kelas induk mungkin tidak mengetahui bahwa ia memiliki kelas turunan. Itu. ia tidak menerima manfaat khusus apa pun dari kehadiran kelas pewaris. Namun pewarisan memberikan banyak keuntungan bagi kelas keturunan. Dan yang paling penting adalah semua variabel dan metode kelas induk muncul di kelas anak, seolah-olah kode kelas induk disalin ke kelas anak. Ini tidak sepenuhnya benar, tetapi untuk pemahaman yang lebih sederhana tentang warisan, hal ini bisa dilakukan. Berikut adalah beberapa contoh untuk lebih memahami warisan. Contoh 1: warisan paling sederhana.
public class Родитель {

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

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

   public int age;
   public String name;
}
Kelas Anak dapat menggunakan variabel umur dan nama kelas Induk seolah-olah mereka dideklarasikan di dalamnya.
public class Потомок extends Родитель {

   public void printInfo() {

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

   public int age;
   public String name;

   public getName() {
      return name;
   }
}
Kelas Anak dapat menggunakan variabel dan metode kelas Induk seolah-olah mereka dideklarasikan di dalamnya. Dalam contoh ini kita menggunakan metode getName ().
public class Потомок extends Родитель {

   public void printInfo() {

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

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

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

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

2. Penggantian metode

Terkadang ada situasi di mana kita mewarisi kelas Descendant dari beberapa kelas Induk yang sangat berguna, bersama dengan semua variabel dan metodenya, namun beberapa metode tidak bekerja persis seperti yang kita inginkan. Atau sama sekali tidak sesuai dengan keinginan kita. Apa yang harus dilakukan dalam situasi ini? Kita dapat mengganti metode yang tidak kita sukai. Hal ini dilakukan dengan sangat sederhana: di kelas Descendant, kita cukup mendeklarasikan metode dengan tanda tangan (header) yang sama dengan metode kelas Induk dan menulis kode kita di dalamnya. Contoh 1: Penggantian metode.
public class Родитель {

   public String name;

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

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

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

   public void printInfo() {

      setName("Luke");
      System.out.println( getName());
   }
}
Inilah tampilan kelas Descendant dari sudut pandang kompiler:
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 keajaiban warisan (dan penggantian metode).
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 suatu metode printInfo(dari kelas Induk) tidak ditimpa di kelas Descendant, ketika metode ini dipanggil pada objek kelas Descendant, metodenya akan dipanggil getName(), dan bukan getName()kelas Induk.
Родитель parent = new Родитель ();
parent.printnInfo();
Kode ini menampilkan tulisan "Luke" di layar .
Потомок child = new Потомок ();
child.printnInfo();
Kode ini menampilkan tulisan "Aku ayahmu, Luke;" .
Inilah tampilan kelas Descendant dari sudut pandang kompiler:
public class Потомок extends Родитель {

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

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

3. Daftar

Jika Anda belum mengenal Daftar, inilah penjelasan singkatnya. Anda dapat menemukan informasi lengkap di level 6-7 kursus JavaRush . Daftar memiliki banyak kesamaan dengan array:
  • dapat menyimpan banyak data jenis tertentu;
  • memungkinkan Anda mengambil elemen berdasarkan indeks/nomornya;
  • indeks elemen dimulai dari 0.
Keuntungan dari daftar: Tidak seperti array, daftar dapat mengubah ukuran secara dinamis. Segera setelah pembuatan, daftar memiliki ukuran 0. Saat Anda menambahkan elemen ke daftar, ukurannya bertambah. Contoh membuat daftar:
ArrayList<String> myList = new ArrayList<String>(); // создание нового списка типа ArrayList
Nilai dalam kurung sudut adalah tipe data yang dapat disimpan dalam daftar. Berikut beberapa metode untuk bekerja dengan daftar:
Kode Deskripsi singkat tentang fungsi kode
ArrayList<String> list = new ArrayList<String>(); Membuat daftar string baru
list.add("name"); Tambahkan elemen ke akhir daftar
list.add(0, "name"); Tambahkan elemen ke awal daftar
String name = list.get(5); Dapatkan elemen berdasarkan indeksnya
list.set(5, "new name"); Ubah elemen berdasarkan indeksnya
int count = list.size(); Dapatkan jumlah elemen dalam daftar
list.remove(4); Hapus item dari daftar
Anda dapat mempelajari lebih lanjut tentang daftar dari artikel berikut:
  1. kelas ArrayList
  2. ArrayList yang berfungsi dalam gambar
  3. Menghapus elemen dari ArrayList

4. Array

Apa itu matriks? Matriks tidak lebih dari sebuah tabel persegi panjang yang dapat diisi dengan data. Dengan kata lain, ini adalah array dua dimensi. Seperti yang mungkin Anda ketahui, array di Java adalah objek. Tipe array satu dimensi standar intterlihat seperti ini:
int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
Mari kita bayangkan secara visual:
0 1 2 3 4 5 6 7
12 32 43 54 15 36 67 28
Baris paling atas menunjukkan alamat sel. Artinya, untuk mendapatkan angka 67, Anda perlu mengakses elemen array dengan indeks 6:
int number = array[6];
Semuanya sangat sederhana di sini. Array dua dimensi adalah array yang terdiri dari array satu dimensi. Jika ini pertama kalinya Anda mendengar hal ini, berhentilah dan bayangkan di kepala Anda. Array dua dimensi terlihat seperti ini:
0 Array satu dimensi Array satu dimensi
1 Array satu dimensi
2 Array satu dimensi
3 Array satu dimensi
4 Array satu dimensi
5 Array satu dimensi
6 Array satu dimensi
7 Array satu dimensi
Dalam kode:
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 diperhatikan, koordinat matriksnya berbeda dengan sistem koordinat persegi panjang klasik (sistem koordinat kartesius). Saat mengakses matriks, Anda menentukan y terlebih dahulu lalu x , sedangkan dalam matematika biasanya menentukan x(x, y) terlebih dahulu. Anda mungkin bertanya pada diri sendiri, “Mengapa tidak membalik matriks dalam imajinasi Anda dan mengakses elemen dengan cara biasa melalui (x, y)? Ini tidak akan mengubah isi matriks.” Ya, tidak ada yang akan berubah. Namun dalam dunia pemrograman, matriks biasanya disebut dalam bentuk “y pertama, lalu x”. Hal ini harus diterima begitu saja. Sekarang mari kita bicara tentang memproyeksikan matriks ke mesin kita (class Game). Seperti yang Anda ketahui, mesin memiliki banyak metode yang mengubah sel-sel lapangan permainan pada koordinat tertentu. Misalnya, setCellValue(int x, int y, String value). Ini menetapkan sel tertentu dengan koordinat (x, y) ke nilai value. Seperti yang Anda perhatikan, metode ini pertama-tama mengambil x, seperti pada sistem koordinat klasik. Metode mesin lainnya bekerja dengan cara yang sama. Saat mengembangkan game, sering kali ada kebutuhan untuk mereproduksi keadaan matriks di layar. Bagaimana cara melakukannya? Pertama, dalam satu lingkaran Anda perlu melakukan iterasi melalui semua elemen matriks. Kedua, untuk masing-masingnya, panggil metode untuk menampilkan 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]));
        }
    }
}
Secara alami, inversi bekerja dalam dua arah. setCellValueAnda dapat meneruskan (i, j) ke metode ini , tetapi pada saat yang sama mengambil elemen [j][i] dari matriks. Pembalikannya mungkin tampak sedikit sulit, tetapi ini adalah sesuatu yang perlu diingat. Dan selalu, jika ada masalah yang muncul, ada baiknya mengambil selembar kertas dengan pena, menggambar matriks dan mereproduksi proses apa yang terjadi padanya.

5. Angka acak

Bagaimana cara bekerja dengan generator nomor acak? Kelas Gamemendefinisikan suatu metode getRandomNumber(int). Di bawah tenda, ia menggunakan kelas Randomdari paket java.util, tetapi ini tidak mengubah prinsip kerja dengan generator angka acak. getRandomNumber(int)Mengambil bilangan bulat sebagai argumen . Angka ini akan menjadi batas atas yang dapat dikembalikan oleh generator. Batas bawahnya adalah 0. Penting! Generator TIDAK AKAN PERNAH mengembalikan nomor batas atas. Misalnya, jika dipanggil getRandomNumber(3)secara acak, ia dapat mengembalikan 0, 1, 2. Seperti yang Anda lihat, ia tidak dapat mengembalikan 3. Penggunaan generator ini cukup sederhana, namun sangat efektif dalam banyak kasus. Anda perlu mendapatkan nomor acak dalam batasan tertentu: Bayangkan Anda memerlukan nomor tiga digit (100..999). Seperti yang sudah Anda ketahui, angka minimum yang dikembalikan adalah 0. Jadi, Anda perlu menambahkannya ke 100. Namun dalam hal ini, Anda harus berhati-hati agar tidak melebihi batas atas. Untuk mendapatkan 999 sebagai nilai acak maksimum, Anda harus memanggil metode getRandomNumber(int)dengan argumen 1000. Namun kita ingat tentang penambahan 100 berikutnya: ini berarti batas atas harus diturunkan sebesar 100. Artinya, kode untuk mendapatkan a nomor tiga digit acak akan terlihat seperti ini:
int number = 100 + getRandomNumber(900);
Namun untuk menyederhanakan prosedur tersebut, mesin menyediakan metode getRandomNumber(int, int)yang mengambil angka minimum untuk dikembalikan sebagai argumen pertama. Dengan menggunakan metode ini, contoh sebelumnya dapat ditulis ulang:
int number = getRandomNumber(100, 1000);
Nomor acak dapat digunakan untuk mendapatkan elemen array acak:
String [] names = {"Andrey", "Валентин", "Сергей"};
String randomName = names[getRandomNumber(names.length)]
Memicu kejadian tertentu dengan probabilitas tertentu. Pagi hari seseorang dimulai berdasarkan skenario yang mungkin terjadi: Ketiduran – 50%; Bangun tepat waktu – 40%; Bangun satu jam lebih awal dari yang diharapkan – 10%. Bayangkan Anda sedang menulis emulator pagi manusia. Anda perlu memicu peristiwa dengan probabilitas tertentu. Untuk melakukan ini, sekali lagi, Anda perlu menggunakan generator nomor acak. Implementasinya mungkin berbeda, tetapi yang paling sederhana harus mengikuti algoritma berikut:
  1. kami menetapkan batas di mana angka tersebut perlu dihasilkan;
  2. menghasilkan nomor acak;
  3. Kami memproses nomor yang dihasilkan.
Jadi, dalam kasus ini, batasnya adalah 10. Mari kita panggil metodenya getRandomNumber(10)dan analisis apa yang bisa dikembalikannya kepada kita. Itu dapat mengembalikan 10 digit (dari 0 hingga 9) dan masing-masing dengan probabilitas yang sama - 10%. Sekarang kita perlu menggabungkan semua kemungkinan hasil dan mencocokkannya dengan kejadian yang mungkin terjadi. Ada banyak kombinasi, tergantung pada imajinasi Anda, tetapi yang paling jelas terdengar: “Jika angka acak berada dalam [0..4] - sebut peristiwa “Ketiduran”, jika angka tersebut berada dalam [5..8 ] - “Bangun” tepat waktu,” dan hanya jika angkanya 9, maka “Saya bangun satu jam lebih awal dari yang diharapkan.” Semuanya sangat sederhana: dalam [0..4] ada 5 angka, yang masing-masing dapat kembali dengan probabilitas 10%, yang totalnya adalah 50%; dalam [5..8] ada 4 angka, dan 9 adalah satu-satunya angka yang muncul dengan probabilitas 10%. Dalam kode, seluruh desain pintar ini terlihat lebih sederhana:
int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
    System.out.println("Проспал ");
} else if (randomNumber < 9) {
    System.out.println("Встал вовремя ");
} else {
    System.out.println("Встал на час раньше положенного ");
}
Secara umum, ada banyak pilihan untuk menggunakan nomor acak. Itu semua tergantung pada imajinasi Anda. Tapi mereka paling efektif digunakan ketika Anda ingin mendapatkan hasil tertentu berulang kali. Maka hasil ini akan berbeda dengan yang sebelumnya. Tentu saja dengan kemungkinan tertentu. Itu saja! Jika Anda ingin mempelajari lebih lanjut tentang bagian Permainan, berikut beberapa dokumentasi berguna yang dapat membantu:
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION