1. Dziedziczenie

Aby pracować z silnikiem gry CodeGym, musisz użyć dziedziczenia . Ale co, jeśli nie wiesz, co to jest? Z jednej strony musisz zrozumieć i przestudiować ten temat. Z drugiej strony silnik został specjalnie zaprojektowany tak, aby był bardzo prosty, więc możesz sobie poradzić z powierzchowną znajomością dziedziczenia.

Czym zatem jest dziedziczenie? Mówiąc prościej, dziedziczenie to związek między dwiema klasami. Jedna z nich pełni rolę klasy nadrzędnej, a druga staje się klasą potomną (potomną). Co więcej, klasa nadrzędna może nawet nie wiedzieć, że ma klasy potomne. Innymi słowy, rodzic nie czerpie większych korzyści z posiadania klas potomnych.

Ale dziedziczenie daje wiele korzyści klasie potomnej. Najważniejszym z nich jest to, że wszystkie zmienne i metody klasy nadrzędnej pojawiają się w klasie podrzędnej, tak jakby kod klasy nadrzędnej został skopiowany bezpośrednio do klasy podrzędnej. To nie jest całkowicie dokładne, ale wystarczy do podstawowego zrozumienia dziedziczenia.

Oto kilka przykładów, które pomogą Ci lepiej zrozumieć dziedziczenie.

Przykład 1 — oto najprostszy przykład

public class Parent
{
}
Klasa Childdziedziczy Parentklasę za pomocą słowa extendskluczowego.
public class Child extends Parent
{
}

Przykład 2 — wykorzystanie zmiennych klasy nadrzędnej

public class Parent
{
  public int age;
  public String name;
}
Klasa Childmoże używać pól agei nameklasy Parenttak, jakby były zadeklarowane w Childsamej klasie.
public class Child extends Parent
{
  public void printInfo()
  {
    System.out.println(name + " " + age);
  }
}

Przykład 3 — wykorzystanie metod klasy nadrzędnej

public class Parent
{
   public int age;
   public String name;
   public getName() {
      return name;
   }
}
Klasa Childmoże używać zmiennych i metod klasy nadrzędnej tak, jakby były one zadeklarowane w Childklasie. W tym przykładzie używamy getName()metody.
public class Child extends Parent
{
   public void printInfo()
   {
      System.out.println(getName() + " " + age);
   }
}

Pomijając pewne szczegóły, możemy powiedzieć, że z perspektywy kompilatora Javy po prostu skopiowaliśmy kod klasy nadrzędnej do kodu klasy podrzędnej:

public class Child extends Parent
{
   public int age;        // An inherited variable
   public String name;    // An inherited variable
   public getName() {     // An inherited method
      return name;
   }

   public void printInfo()
   {
      System.out.println(getName() + " " + age);
   }
}
Oto jak Childklasa wygląda z punktu widzenia kompilatora


2. Nadpisywanie metod

Czasami zdarzają się sytuacje, w których sprawiamy, że nasza Childklasa dziedziczy bardzo użyteczną Parentklasę, powodując, że dziecko dziedziczy wszystkie zmienne i metody rodzica. Ale niektóre z tych metod mogą nie działać tak, jak byśmy tego chcieli, lub w ogóle nie tak, jakbyśmy tego chcieli.

Co robisz w tym przypadku? Możemy zastąpić metodę, której implementacja nam się nie podoba . Jest to prosta rzecz do zrobienia: w naszej Childklasie po prostu deklarujemy metodę z takim samym podpisem jak metoda w Parentklasie, a następnie piszemy w niej własny kod.

Przykład 1 — przesłanianie metody

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

   public getName() {
      return name;
   }
}
Metoda printInfo()wyświetli następującą frazę:
Luke, No!!!
public class Child extends Parent
{
   public void setName(String nameNew) {
      name = nameNew + ", No!!!";
   }

   public void printInfo()
   {
      setName("Luke");
      System.out.println(getName());
   }
}

Upraszczając nieco sytuację, dziedziczenie powoduje skopiowanie kodu klasy nadrzędnej do klasy podrzędnej. Ale jeśli klasa potomna jest już metodą, która istnieje w klasie przodka, to ta metoda nie jest kopiowana z klasy przodka. Tutaj mówimy, że metoda w klasie potomnej zastępuje metodę w klasie nadrzędnej. Spójrz na poniższy przykład. Może to pomoże trochę rozjaśnić sprawę:

Oto jak wygląda klasa Child z punktu widzenia kompilatora:
public class Child extends Parent
{
   public String name;    // An inherited variable

   public void setName(String nameNew)  // The overridden method replaces the inherited one
   {
      name = nameNew + ", No!!!";
   }

   public getName()    // An inherited method
   {
      return name;
   }

   public void printInfo()
   {
      setName("Luke");
      System.out.println(getName());
   }
}

Przykład 2 - trochę magii dziedziczenia (i nadpisywania metod)

public class Parent
{
   public getName() {
      return "Luke";
   }

   public void printInfo()
   {
      System.out.println( getName() );
   }
}
public class Child extends Parent
{
   public getName() {
      return "Luke, I am your father";
   }
}

Jeśli printInfo()metoda jest wywoływana na Parenttypie, to z kolei wywołuje getName()metodę klasy Parent.

Jeśli printInfo()metoda jest wywoływana na Childobiekcie, to z kolei wywołuje getName()metodę klasy Child.

Innymi słowy, printInfo()metoda jest zadeklarowana tylko w Parentklasie, ale wywołuje getName()metodę klasy Child, jeśli printInfo()metoda jest wywoływana na Childobiekcie.

Przykład:

Parent parent = new Parent();
parent.printnInfo();
Ten kod wyświetla następujący tekst na ekranie:
Luke
Child child = new Child();
child.printnInfo();
Ten kod wyświetla następujący tekst na ekranie:
Luke, I am your father

A wszystko dlatego, że z punktu widzenia kompilatora (w bardzo uproszczonej wersji) kod klasy Childwygląda tak:

public class Child extends Parent
{
   public getName() {
      return "Luke, I am your father";
   }

   public void printInfo()
   {
      System.out.println(getName());
   }
}
Oto jak Childklasa wygląda z punktu widzenia kompilatora


3. Listy

Oto krótkie przypomnienie o listach ( List). Listy mają wiele wspólnego z tablicami:

  • Mogą przechowywać wiele danych określonego typu.
  • Pozwalają uzyskać elementy według ich indeksu.
  • Indeksy pierwiastków zaczynają się od 0.

Zalety list:

W przeciwieństwie do tablic, listy mogą dynamicznie zmieniać rozmiar. Natychmiast po utworzeniu rozmiar listy wynosi 0. W miarę dodawania elementów do listy zwiększa się jej rozmiar. Przykład tworzenia listy:

ArrayList<String> myList = new ArrayList<String>();
Tworzenie nowegoArrayList

Wartość wskazana w nawiasach ostrych to typ danych, który może przechowywać lista.

Oto kilka metod pracy z listą:

Kod Krótki opis
ArrayList<String> list = new ArrayList<String>();
Tworzenie nowej listy ciągów znaków
list.add("name");
Dodaj element na końcu listy
list.add(0, "name");
Dodaj element na początek listy
String name = list.get(5);
Pobierz element według jego indeksu
list.set(5, "new name");
Zmień element według jego indeksu
int count = list.size();
Pobierz liczbę elementów na liście
list.remove(4);
Usuń element z listy

Więcej informacji na temat list można znaleźć w następujących artykułach:



4. Losowe liczby

Silnik gry CodeGym ma dwie metody, których można użyć do generowania liczb losowych. Te metody to:

int getRandomNumber(int max)
int getRandomNumber(int min, int max)

Pierwsza metoda — getRandomNumber(int max)— zwraca liczbę losową z zakresu 0, 1, 2, ... max-1. Pod maską używa Randomklasy z java.utilpakietu, ale to nie zmienia sposobu korzystania z liczby losowej.

getRandomNumber(int)przyjmuje liczbę całkowitą jako argument. Ta liczba będzie górną granicą liczb, które może zwrócić generator liczb losowych. Dolna granica to 0. Uwaga! Generator liczb losowych NIGDY nie zwróci wartości górnej granicy. Na przykład, jeśli wywołasz getRandomNumber(3), losowo zwróci 0, 1 lub 2. Jak widać, nie zwróci 3. Korzystanie z generatora liczb losowych w ten sposób jest raczej proste, ale jest odpowiednie w wielu przypadkach.

Druga metoda — getRandomNumber(int min, int max)— zwraca losową liczbę całkowitą z zakresu [min, max-1]. Nigdy nie zwróci liczby mniejszej niż mini nigdy nie zwróci liczby większej niż max-1.

Jak te metody można wykorzystać w praktyce?

1. Kości

Załóżmy, że chcesz zasymulować rzut kostką i otrzymać losową liczbę z zakresu 1-6. Jak byś to zrobił? Można to zrobić za pomocą takiego kodu:

int dice = getRandomNumber(1, 7);

Ta metoda zwróci losową liczbę całkowitą z zakresu 1-6.

2. Praktyka strzelecka

Załóżmy, że chcesz symulować strzelanie do celu, a celność strzału obejmuje losowy składnik, który zmienia się w zakresie od -10do +10włącznie. Można to zrobić za pomocą takiego kodu:

int dx = getRandomNumber(-10, 11);

Ta metoda zwróci losową liczbę całkowitą z zakresu -10do +10.

Istnieje wiele sposobów wykorzystania liczb losowych w grach. Ogranicza Cię tylko Twoja wyobraźnia. Pisz własne gry, dopracowuj je i ciesz się procesem.

Każdy może grać w gry, ale tylko programiści mogą je tworzyć.