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.
Untuk 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>();
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:
- kelas ArrayList
- ArrayList yang berfungsi dalam gambar
- 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
int
terlihat 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.
setCellValue
Anda 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
Game
mendefinisikan suatu metode
getRandomNumber(int)
. Di bawah tenda, ia menggunakan kelas
Random
dari 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:
- kami menetapkan batas di mana angka tersebut perlu dihasilkan;
- menghasilkan nomor acak;
- 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:
GO TO FULL VERSION