Sa
seksyong "Mga Laro" ng JavaRush makikita mo ang mga kapana-panabik na proyekto para sa pagsusulat ng mga sikat na laro sa computer. Gusto mo bang lumikha ng iyong sariling bersyon ng sikat na "2048", "Sapper", "Snake" at iba pang mga laro? Simple lang. Ginawa naming hakbang-hakbang na proseso ang pagsulat ng laro.
Upang subukan ang iyong sarili bilang isang developer ng laro, hindi mo kailangang maging isang advanced na programmer, ngunit kailangan pa rin ng isang tiyak na hanay ng kaalaman sa Java. Dito makikita mo
ang impormasyon na magiging kapaki-pakinabang kapag nagsusulat ng mga laro .
1. Pamana
Ang pagtatrabaho sa JavaRush game engine ay nagsasangkot ng paggamit ng mana. Ngunit paano kung hindi mo alam kung ano ito? Sa isang banda, kailangan mong maunawaan ang paksang ito: ito ay pinag-aaralan sa
antas 11 . Sa kabilang banda, ang makina ay sadyang idinisenyo upang maging napaka-simple, upang makayanan mo ang isang mababaw na kaalaman sa mana. Kaya, ano ang mana? Upang ilagay ito nang napakasimple, ang mana ay ang relasyon sa pagitan ng dalawang klase. Ang isa sa kanila ay nagiging magulang, at ang pangalawa ay nagiging anak (kapalit na klase). Sa kasong ito, maaaring hindi alam ng parent class na mayroon itong mga descendant class. Yung. hindi ito tumatanggap ng anumang partikular na benepisyo mula sa pagkakaroon ng mga klase ng tagapagmana. Ngunit ang pamana ay nagbibigay ng maraming pakinabang sa isang descendant class. At ang pangunahing isa ay ang lahat ng mga variable at pamamaraan ng parent class ay lilitaw sa child class, na parang ang code ng parent class ay kinopya sa child class. Ito ay hindi ganap na totoo, ngunit para sa isang pinasimpleng pag-unawa sa mana ay gagawin nito. Narito ang ilang mga halimbawa upang mas maunawaan ang mana.
Halimbawa 1: ang pinakasimpleng pamana.
public class Родитель {
}
|
Nagmana ang klase ng Bata mula sa klase ng Magulang gamit ang extends na keyword . |
public class Потомок extends Родитель {
}
|
Halimbawa 2: Paggamit ng mga variable ng parent class.
public class Родитель {
public int age;
public String name;
}
|
Maaaring gamitin ng klase ng Bata ang mga variable ng edad at pangalan ng klase ng Parent na parang idineklara ang mga ito dito. |
public class Потомок extends Родитель {
public void printInfo() {
System.out.println(name+" "+age);
}
}
|
Halimbawa 3: Paggamit ng mga pamamaraan ng parent class.
public class Родитель {
public int age;
public String name;
public getName() {
return name;
}
}
|
Maaaring gamitin ng klase ng Bata ang mga variable at pamamaraan ng klase ng Parent na parang idineklara ang mga ito dito. Sa halimbawang ito ginagamit namin ang getName () na paraan. |
public class Потомок extends Родитель {
public void printInfo() {
System.out.println(getName()+" "+age);
}
}
|
Ito ang hitsura ng klase ng
Descendant mula sa punto ng view ng compiler:
public class Потомок extends Родитель {
public int age;
public String name;
public getName() {
return name;
}
public void printInfo() {
System.out.println(getName()+" "+age);
}
}
2. Pamamaraan override
Minsan may mga sitwasyon na minana namin ang aming Descendant class mula sa ilang napaka-kapaki-pakinabang na klase ng Parent, kasama ang lahat ng mga variable at pamamaraan, ngunit ang ilang mga pamamaraan ay hindi gumagana nang eksakto sa paraang gusto namin. O hindi sa paraang hindi natin gusto. Ano ang gagawin sa ganitong sitwasyon? Maaari naming i-override ang isang paraan na hindi namin gusto. Ginagawa ito nang napakasimple: sa aming Descendant na klase ay nagdedeklara lang kami ng isang pamamaraan na may parehong lagda (header) bilang paraan ng klase ng Magulang at isulat ang aming code dito.
Halimbawa 1: Overriding ng pamamaraan.
public class Родитель {
public String name;
public void setName (String nameNew) {
name = nameNew;
}
public getName() {
return name;
}
}
|
Ang printInfo() na paraan ay magpi-print ng pariralang "Luke, Hindi!!!" |
public class Потомок extends Родитель {
public void setName (String nameNew) {
name = nameNew + ",No!!!";
}
public void printInfo() {
setName("Luke");
System.out.println( getName());
}
}
|
Ito ang hitsura ng klase ng
Descendant mula sa punto ng view ng compiler:
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());
}
}
Halimbawa 2: isang maliit na magic ng pamana (at overriding ng pamamaraan).
public class Родитель {
public getName() {
return "Luke";
}
public void printInfo() {
System.out.println(getName());
}
}
|
public class Потомок extends Родитель {
public getName() {
return "I'm your father, Luke";
}
}
|
Sa halimbawang ito: kung ang isang pamamaraan
printInfo
(mula sa klase ng Parent) ay hindi na-override sa klase ng Descendant, kapag ang pamamaraang ito ay tinawag sa isang object ng klase ng Descendant, ang pamamaraan nito ay tatawagin
getName()
, at hindi
getName()
ang klase ng Parent.
Родитель parent = new Родитель ();
parent.printnInfo();
|
Ipinapakita ng code na ito ang inskripsyon na "Luke" sa screen . |
Потомок child = new Потомок ();
child.printnInfo();
|
Ipinapakita ng code na ito ang inskripsiyon na "Ako ang iyong ama, Luke;" . |
Ito ang hitsura ng klase ng
Descendant mula sa punto ng view ng compiler:
public class Потомок extends Родитель {
public getName() {
return "I'm your father, Luke";
}
public void printInfo() {
System.out.println(getName());
}
}
3. Mga listahan
Kung hindi mo pa nakikilala ang Lists, narito ang isang mabilis na panimulang aklat. Makakahanap ka ng kumpletong impormasyon sa
mga antas 6-7 ng kursong JavaRush .
Ang mga listahan ay may maraming pagkakatulad sa mga array:
- maaaring mag-imbak ng maraming data ng isang tiyak na uri;
- nagpapahintulot sa iyo na kunin ang mga elemento sa pamamagitan ng kanilang index/numero;
- Ang mga indeks ng elemento ay nagsisimula sa 0.
Mga kalamangan ng mga listahan: Hindi tulad ng mga array, ang mga listahan ay maaaring magbago ng laki nang pabago-bago. Kaagad pagkatapos ng paggawa, ang listahan ay may sukat na 0. Habang nagdaragdag ka ng mga elemento sa listahan, tataas ang laki nito. Halimbawa ng paggawa ng listahan:
ArrayList<String> myList = new ArrayList<String>();
Ang halaga sa mga angle bracket ay ang uri ng data na maiimbak ng listahan. Narito ang ilang paraan para magtrabaho kasama ang isang listahan:
Code |
Maikling paglalarawan kung ano ang ginagawa ng code |
ArrayList<String> list = new ArrayList<String>(); |
Paglikha ng bagong listahan ng mga string |
list.add("name"); |
Magdagdag ng elemento sa dulo ng listahan |
list.add(0, "name"); |
Magdagdag ng elemento sa simula ng listahan |
String name = list.get(5); |
Kumuha ng elemento sa pamamagitan ng index nito |
list.set(5, "new name"); |
Baguhin ang elemento sa pamamagitan ng index nito |
int count = list.size(); |
Kunin ang bilang ng mga elemento sa isang listahan |
list.remove(4); |
Mag-alis ng item sa isang listahan |
Maaari kang matuto nang higit pa tungkol sa mga listahan mula sa mga artikulong ito:
- klase ng ArrayList
- Working ArrayList sa mga larawan
- Pag-alis ng isang elemento mula sa isang ArrayList
4. Mga array
Ano ang isang matrix? Ang isang matrix ay hindi hihigit sa isang hugis-parihaba na talahanayan na maaaring punan ng data. Sa madaling salita, ito ay isang two-dimensional array. Tulad ng malamang na alam mo, ang mga array sa Java ay mga bagay. Ang isang karaniwang isang-dimensional na uri ng array
int
ay ganito ang hitsura:
int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
Isipin natin ito nang biswal:
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
32 |
43 |
54 |
15 |
36 |
67 |
28 |
Ang tuktok na linya ay nagpapahiwatig ng mga address ng cell. Iyon ay, upang makuha ang numero 67, kailangan mong i-access ang elemento ng array na may index 6:
int number = array[6];
Napakasimple ng lahat dito. Ang dalawang-dimensional na array ay isang hanay ng mga one-dimensional na array. Kung ito ang iyong unang pagkakataon na marinig ang tungkol dito, huminto at isipin ito sa iyong ulo. Mukhang ganito ang isang two-dimensional array:
0 |
Isang-dimensional na hanay |
Isang-dimensional na hanay |
1 |
Isang-dimensional na hanay |
2 |
Isang-dimensional na hanay |
3 |
Isang-dimensional na hanay |
4 |
Isang-dimensional na hanay |
5 |
Isang-dimensional na hanay |
6 |
Isang-dimensional na hanay |
7 |
Isang-dimensional na hanay |
Sa code:
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 |
Upang makuha ang halaga 47, kailangan mong i-access ang elemento ng matrix sa [4][2].
int number = matrix[4][2];
Kung mapapansin mo, iba ang matrix coordinates sa classical rectangular coordinate system (Cartesian coordinate system).
Kapag nag-a-access sa isang matrix, tukuyin mo muna ang y at pagkatapos ay x , samantalang sa matematika karaniwan nang tukuyin muna ang x(x, y). Maaaring itanong mo sa iyong sarili, "Bakit hindi baligtarin ang matrix sa iyong imahinasyon at i-access ang mga elemento sa karaniwang paraan sa pamamagitan ng (x, y)? Hindi nito babaguhin ang mga nilalaman ng matrix. Oo, walang magbabago. Ngunit sa mundo ng programming, kaugalian na sumangguni sa mga matrice sa anyo na "una y, pagkatapos x." Ito ay dapat tanggapin para sa ipinagkaloob. Ngayon ay pag-usapan natin ang tungkol sa pag-project ng matrix sa ating makina (class
Game
). Tulad ng alam mo, ang makina ay may maraming mga pamamaraan na nagbabago sa mga cell ng playing field sa ibinigay na mga coordinate. Halimbawa, ang
setCellValue(int x, int y, String value)
. Nagtatakda ito ng isang tiyak na cell na may mga coordinate (x, y) sa halaga
value
. Tulad ng napansin mo, ang pamamaraang ito ay unang kumukuha ng eksaktong x, tulad ng sa classical coordinate system. Ang natitirang mga pamamaraan ng engine ay gumagana sa katulad na paraan. Kapag nagde-develop ng mga laro, madalas na kailangang kopyahin ang estado ng matrix sa screen. Paano ito gawin? Una, sa isang loop kailangan mong umulit sa lahat ng mga elemento ng matrix. Pangalawa, para sa bawat isa sa kanila, tumawag ng isang paraan upang ipakita gamit ang INVERTED coordinates. Halimbawa:
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]));
}
}
}
Naturally, ang pagbabaligtad ay gumagana sa dalawang direksyon.
setCellValue
Maaari mong ipasa ang (i, j) sa pamamaraan , ngunit sa parehong oras kunin ang elemento [j][i] mula sa matrix. Ang pagbabaligtad ay maaaring mukhang medyo mahirap, ngunit ito ay isang bagay na dapat tandaan. At palagi, kung mayroong anumang mga problema, sulit na kumuha ng isang piraso ng papel na may panulat, pagguhit ng isang matrix at muling paggawa kung anong mga proseso ang nangyayari dito.
5. Random na mga numero
Paano magtrabaho sa isang random na generator ng numero? Tinutukoy ng klase
Game
ang isang pamamaraan
getRandomNumber(int)
. Sa ilalim ng hood, ito ay gumagamit ng isang klase
Random
mula sa java.util package, ngunit hindi nito binabago ang prinsipyo ng pagtatrabaho sa isang random na generator ng numero.
getRandomNumber(int)
Kinukuha ang isang integer bilang isang argumento . Ang numerong ito ang magiging upper bound na maaaring ibalik ng generator. Ang mas mababang limitasyon ay 0.
Mahalaga! HINDI magbabalik ang generator ng upper bound number. Halimbawa, kung
getRandomNumber(3)
random na tawag ay maaari itong magbalik ng 0, 1, 2. Gaya ng nakikita mo, hindi ito makakabalik ng 3. Ang paggamit ng generator ay medyo simple, ngunit napaka-epektibo sa maraming mga kaso.
Kailangan mong makakuha ng random na numero sa loob ng ilang limitasyon: Isipin na kailangan mo ng ilang tatlong-digit na numero (100..999). Tulad ng alam mo na, ang pinakamababang numero na ibinalik ay 0. Kaya, kakailanganin mong magdagdag dito ng 100. Ngunit sa kasong ito, kailangan mong mag-ingat na huwag lumampas sa itaas na limitasyon. Upang makakuha ng 999 bilang pinakamataas na random na halaga, dapat mong tawagan ang pamamaraan
getRandomNumber(int)
na may argumento na 1000. Ngunit natatandaan namin ang tungkol sa kasunod na pagdaragdag ng 100: nangangahulugan ito na ang itaas na hangganan ay dapat ibaba ng 100. Iyon ay, ang code upang makakuha ng isang ang random na tatlong-digit na numero ay magiging ganito:
int number = 100 + getRandomNumber(900);
Ngunit upang gawing simple ang gayong pamamaraan, ang makina ay nagbibigay ng isang paraan
getRandomNumber(int, int)
na kumukuha ng pinakamababang numero upang maibalik bilang ang unang argumento. Gamit ang pamamaraang ito, ang nakaraang halimbawa ay maaaring muling isulat:
int number = getRandomNumber(100, 1000);
Maaaring gamitin ang mga random na numero upang makakuha ng isang random na elemento ng array:
String [] names = {"Andrey", "Валентин", "Сергей"};
String randomName = names[getRandomNumber(names.length)]
Pagti-trigger ng ilang mga kaganapan na may tiyak na posibilidad. Ang umaga ng isang tao ay nagsisimula ayon sa mga posibleng sitwasyon: Overslept - 50%; Bumangon sa oras - 40%; Bumangon ng isang oras nang mas maaga kaysa sa inaasahan - 10%. Isipin na nagsusulat ka ng isang human morning emulator. Kailangan mong mag-trigger ng mga kaganapan na may tiyak na posibilidad. Upang gawin ito, muli, kailangan mong gumamit ng isang random na generator ng numero. Maaaring magkaiba ang mga pagpapatupad, ngunit dapat sundin ng pinakasimpleng isa ang sumusunod na algorithm:
- itinakda namin ang mga limitasyon kung saan kailangang mabuo ang bilang;
- bumuo ng isang random na numero;
- Pinoproseso namin ang resultang numero.
Kaya, sa kasong ito, ang limitasyon ay magiging 10. Tawagan natin ang pamamaraan
getRandomNumber(10)
at suriin kung ano ang maibabalik nito sa atin. Maaari itong magbalik ng 10 digit (mula 0 hanggang 9) at bawat isa ay may parehong posibilidad - 10%. Ngayon kailangan nating pagsamahin ang lahat ng posibleng resulta at itugma ang mga ito sa ating mga posibleng kaganapan. Maaaring magkaroon ng maraming kumbinasyon, depende sa iyong imahinasyon, ngunit ang pinaka-halatang mga tunog: "Kung ang isang random na numero ay nasa loob ng [0..4] - tawagan ang kaganapan na "Overslept", kung ang numero ay nasa loob ng [5..8] ] - "Gumising" sa oras," at kung ang numero ay 9, pagkatapos ay "Bumangon ako ng isang oras nang mas maaga kaysa sa inaasahan." Ang lahat ay napaka-simple: sa loob ng [0..4] mayroong 5 numero, ang bawat isa ay maaaring bumalik na may posibilidad na 10%, na sa kabuuan ay magiging 50%; sa loob ng [5..8] mayroong 4 na numero, at 9 ang tanging numero na lumalabas na may posibilidad na 10%. Sa code, ang buong matalinong disenyo ay mukhang mas simple:
int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
System.out.println("Проспал ");
} else if (randomNumber < 9) {
System.out.println("Встал вовремя ");
} else {
System.out.println("Встал на час раньше положенного ");
}
Sa pangkalahatan, maaaring mayroong maraming mga opsyon para sa paggamit ng mga random na numero. Ang lahat ay nakasalalay lamang sa iyong imahinasyon. Ngunit ang mga ito ay pinaka-epektibong ginagamit kung kailangan mong makakuha ng ilang resulta nang paulit-ulit. Kung gayon ang resultang ito ay magiging iba sa nauna. May ilang posibilidad, siyempre. Iyon lang! Kung gusto mong matuto nang higit pa tungkol sa seksyong Mga Laro, narito ang ilang kapaki-pakinabang na dokumentasyon na makakatulong:
GO TO FULL VERSION