CodeGym /Java Blogu /Rastgele /CodeGym'deki oyunlar bölümü: Yararlı teori
John Squirrels
Seviye
San Francisco

CodeGym'deki oyunlar bölümü: Yararlı teori

grupta yayınlandı
CodeGym'deki "Oyunlar" bölümünde , popüler bilgisayar oyunları yazmayı içeren heyecan verici projeler bulacaksınız. Popüler oyunlar 2048, Mayın Tarlası, Yılan ve diğer oyunların kendi versiyonunu oluşturmak ister misiniz? Basit. Oyun yazmayı adım adım ilerleyen bir sürece dönüştürdük. CodeGym'deki "Oyunlar" bölümü: Yararlı teori - 1Bir oyun geliştiricisi olarak yeteneklerinizi test etmek için ileri düzey bir programcı olmanız gerekmez, ancak belirli bir Java bilgisi seti gereklidir. Burada oyun yazarken işinize yarayacak bilgiler bulacaksınız .

1. Miras

CodeGym oyun motoruyla çalışmak, kalıtımın kullanılmasını içerir. Ama ya bunun ne olduğunu bilmiyorsan? Bir yandan şu konuyu anlamanız gerekiyor: 11. Seviyede inceleniyor. Öte yandan, motor çok basit olacak şekilde özel olarak tasarlandı, böylece kalıtımla ilgili yüzeysel bilgilerden kurtulabilirsiniz. Peki miras nedir? Çok basit bir şekilde ifade etmek gerekirse, kalıtım iki sınıf arasındaki bir ilişkidir. Biri ebeveyn, diğeri çocuk (torun) olur. Ayrıca, üst sınıf, soyundan geldiğini bile bilmeyebilir. Diğer bir deyişle, torun sahibi olmakla belirli bir avantaj sağlamaz. Ancak miras, toruna birçok avantaj sağlar. Ve en önemlisi, ana sınıfın tüm değişkenlerinin ve yöntemlerinin, ana sınıfın kodu soyundan gelen sınıfa kopyalanmış gibi, soyunda görünmesidir. Bu tamamen doğru bir tanım değildir, ancak kalıtımın basitleştirilmiş bir şekilde anlaşılması için yeterli olacaktır. Örnek 1: En basit kalıtım.

public class Parent {

}
Child sınıfı , extends anahtar sözcüğünü kullanarak Parent sınıfını devralır .

public class Child extends Parent {

}
Örnek 2: Üst sınıfın değişkenlerini kullanmak.

public class Parent {

   public int age;
   public String name;
}
Child sınıfı , Parent sınıfının age ve name değişkenlerini, Parent sınıfında bildirilmiş gibi kullanabilir .

public class Child extends Parent {

   public void printInfo() {

     System.out.println(name+" "+age);
   }
}
Örnek 3: Üst sınıfın yöntemlerini kullanmak.

public class Parent {

   public int age;
   public String name;

   public getName() {
      return name;
  }
}
Child sınıfı , Parent sınıfının değişkenlerini ve yöntemlerini sanki Child sınıfında bildirilmiş gibi kullanabilir . Bu örnekte, getName() yöntemini kullanıyoruz .

public class Child extends Parent {

   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}
Child sınıfı derleyiciye şöyle görünür:

public class Child extends Parent{

   public int age;  // Inherited variable
   public String name;  // Inherited variable

   public getName() {  // Inherited method.
      return name;
  }
   public void printInfo() {

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

2. Geçersiz kılma yöntemleri

Bazen, Child sınıfımızın tüm değişkenleri ve yöntemleriyle birlikte bazı çok yararlı Parent sınıfını miras almasını sağladığımız durumlar vardır, ancak bazı yöntemler tam olarak istediğimiz gibi çalışmaz. Ya da hiç istediğimiz gibi değil. Bu durumda ne yapabiliriz? Beğenmediğimiz yöntemi geçersiz kılabiliriz. Bunu yapmak çok kolay: Child sınıfımızda, Parent sınıfındaki yöntemle aynı imzaya sahip bir yöntemi ilan ediyoruz ve sonra içine kendi kodumuzu yazıyoruz. Örnek 1: Bir yöntemi geçersiz kılma.

public class Parent {

   public String name;

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

   public getName() {
      return name;
  }
}
printInfo() yöntemi "Luke, Hayır!!!" görüntüleyecektir.

public class Child extends Parent{

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

   public void printInfo() {
      setName("Luke");
      System.out.println(getName());
   }
}
Child sınıfı derleyiciye şöyle görünür:

public Child extends Parent {

   public String name;  // Inherited variable

   public void setName(String nameNew)  // Overridden method instead of the inherited method {

       name = nameNew + ", No!!!";
   }
   public getName() {  // Inherited method.

      return name;
   }
   public void printInfo() {

     setName("Luke");
     System.out.println( getName());
   }
}
Örnek 2: Bazı kalıtım büyüsü (ve yöntem geçersiz kılma).

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";
  }
}
Bu örnekte, printInfo(Parent sınıfından) yöntemi Child sınıfında geçersiz kılınmazsa, bu yöntem bir Child nesnesinde çağrıldığında, getName()Parent sınıfının yöntemi yerine yöntemi çağrılacaktır getName().

Parent parent = new Parent ();
parent.printnInfo();
Bu kod ekranda "Luke" gösterir.

Child child = new Child ();
child.printnInfo();
Bu kod ekranda "Luke, ben senin babanım" ifadesini gösterir.
Child sınıfı derleyiciye şöyle görünür:

public class Child extends Parent {

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

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

3. Listeler

Henüz listelerle (Liste) tanışmadıysanız, işte size kısa bir genel bakış. Tüm bilgileri CodeGym kursunun 6-7. Seviyelerinde bulabilirsiniz . Listelerin dizilerle pek çok ortak noktası vardır:
  • belirli bir türde çok sayıda veri depolayabilirsiniz;
  • öğeleri indekslerine göre almanıza izin veriyorlar;
  • eleman indeksleri 0'dan başlar.
Listelerin faydaları: Dizilerin aksine, listeler dinamik olarak boyut değiştirebilir. Bir liste oluşturulduğunda boyutu 0'dır. Listeye öğeler eklendikçe boyutu artar. İşte bir liste oluşturmaya bir örnek:

ArrayList<String> myList = new ArrayList<String>(); // Create a new ArrayList
Köşeli parantez içindeki değer, listenin saklayabileceği veri türünü gösterir. Listeyle çalışmak için bazı yöntemler şunlardır:
kod Kodun ne yaptığına dair kısa açıklama
ArrayList<String> list = new ArrayList<String>(); Yeni dize listesi oluştur
list.add("name"); Listenin sonuna bir öğe ekleyin
list.add(0, "name"); Listenin başına bir öğe ekleyin
String name = list.get(5); Bir öğeyi dizinine göre al
list.set(5, "new name"); Bir öğeyi dizinine göre değiştirme
int count = list.size(); Listedeki öğelerin sayısını alın
list.remove(4); Listeden bir öğeyi silin
Aşağıdaki makalelerden listeler hakkında daha fazla bilgi edinebilirsiniz:
  1. ArrayList sınıfı
  2. Resimlerdeki ArrayList
  3. Bir ArrayList'ten bir öğeyi silme

4. Diziler

matris nedir? Matris, verilerle doldurulabilen dikdörtgen bir tablodan başka bir şey değildir. Başka bir deyişle, iki boyutlu bir dizidir. Muhtemelen bildiğiniz gibi, Java'daki diziler nesnelerdir. Standart bir tek boyutlu intdizi şöyle görünür:

int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
Bunu şu şekilde görselleştirebiliriz:
0 1 2 3 4 5 6 7
12 32 43 54 15 36 67 28
Üst satır, hücrelerin adreslerini gösterir. Başka bir deyişle, 67 sayısını elde etmek için, 6 indeksli dizi elemanına erişmeniz gerekir:

int number = array[6];
Her şey çok basit. İki boyutlu dizi, tek boyutlu dizilerin dizisidir. Bunu ilk kez duyuyorsanız, durun ve kafanızda hayal edin. İki boyutlu bir dizi şöyle görünür:
0 Tek boyutlu dizi Tek boyutlu dizi
1 Tek boyutlu dizi
2 Tek boyutlu dizi
3 Tek boyutlu dizi
4 Tek boyutlu dizi
5 Tek boyutlu dizi
6 Tek boyutlu dizi
7 Tek boyutlu dizi
Kodda:

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
47 değerini elde etmek için [4][2]'deki matris öğesine başvurmanız gerekir.

int number = matrix[4][2];
Matris koordinatlarının klasik dikdörtgen koordinat sisteminden (Kartezyen koordinat sistemi) farklı olduğunu fark etmişsinizdir. Matrise girdiğinizde önce y koordinatını sonra x koordinatını belirtirsiniz. Matematikte, önce x koordinatını, yani (x, y) belirtmek adettendir. Şunu merak ediyor olabilirsiniz: "Peki, neden matris temsilinizi döndürmüyorsunuz ve sonra (x, y)'yi kullanarak öğelere her zamanki gibi erişmiyorsunuz? Bunu yapmak matrisin içeriğini değiştirmez". Evet, hiçbir şey değişmeyecekti. Ancak programlama dünyasında, kabul edilen uygulama matrislere "önce y, sonra x" ile erişmektir. Bunu doğru yol olarak kabul etmelisiniz. Şimdi matrisi motorumuza yansıtmaktan bahsedelim (Gamesınıf). Bildiğiniz gibi, motorun oyun alanının hücrelerini belirli koordinatlarda değiştiren birçok yöntemi vardır. Örneğin, setCellValue(int x, int y, String value)yöntem. Değer parametresine eşit koordinatlara (x, y) sahip belirli bir hücre ayarlar. Klasik koordinat sisteminde olduğu gibi bu yöntemin de önce x'i aldığını fark etmişsinizdir. Motorun diğer yöntemleri de benzer şekilde çalışır. Oyun geliştirirken, ekranda bir matrisin durumunu yeniden oluşturmak genellikle gerekli olacaktır. Bunu nasıl yaparız? İlk olarak, bir döngüdeki tüm matris öğelerini yinelemeniz gerekir. İkinci olarak, REVERSED koordinatlarını kullanarak her biri için görüntüleme yöntemini çağırın. Örneğin:

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]));
        }
    }
}
Doğal olarak, tersine çevirme her iki yönde de çalışır. Yönteme (i, j) iletebilir setCellValueve aynı anda matristen [j][i] öğesini alabilirsiniz. Koordinatları tersine çevirmek biraz zor görünebilir, ancak bunu hatırlamanız gerekir. Ve her zaman, herhangi bir sorunla karşılaşırsanız, bir parça kağıt ve bir kalem alıp matrisi çizmeli ve matrisi içeren işlemleri yeniden oluşturmalısınız.

5. Rastgele sayılar

Rastgele sayı üreteci ile nasıl çalışırsınız? Sınıf , yöntemi Gametanımlar getRandomNumber(int). Gizli olarak, Randomjava.util paketindeki sınıfı kullanır, ancak rasgele sayı üreteci ile çalışma şekliniz değişmez. getRandomNumber(int)argüman olarak bir tamsayı alır. Bu sayı, jeneratörün döndürebileceği üst sınır olacaktır. Alt sınır 0'dır. Önemli! Jeneratör ASLA üst limit numarasını döndürmez. Örneğin, çağırırsanız getRandomNumber(3)rastgele 0, 1 veya 2 döndürür. Gördüğünüz gibi 3 döndüremez. Jeneratörü bu şekilde kullanmak oldukça basit, ancak birçok durumda oldukça etkilidir. Bir aralıkta rastgele bir sayı almanız gerektiğini varsayalım: [100..999] aralığında üç basamaklı bir sayıya ihtiyacınız olduğunu hayal edin. Bildiğiniz gibi döndürülen minimum sayı 0'dır. Yani 100 eklemeniz gerekecek. Ancak bu durumda üst limiti aşmamaya özen göstermelisiniz. 999'u maksimum rasgele değer olarak almak için,getRandomNumber(int)1000 argümanlı metod. Ama şimdi sonuca 100 eklediğimizi hatırlıyoruz: bu, üst sınırın 100 azaltılması gerektiği anlamına geliyor. :

int number = 100 + getRandomNumber(900);
Ancak bu prosedürü basitleştirmek için motor, getRandomNumber(int, int)ilk parametresi döndürülecek minimum sayı olan yöntemi sağlar. Bu yöntemi kullanarak, önceki örnek aşağıdaki gibi yeniden yazılabilir:

int number = getRandomNumber(100, 1000);
Rastgele sayılar, rastgele bir dizi öğesi elde etmek için kullanılabilir:

String [] names = {"Sarah", "Val", "Sergey"};
String randomName = names[getRandomNumber(names.length)]
Bazı olasılıklarla belirli olayları oluşturmak. İnsanlar için sabahlar birkaç olası senaryo ile başlar: Fazla uyuyakalma – %50 şans; Zamanında uyanmak – %40 şans; Bir saat erken uyandım – %10 şans. Bir sabah sonuç üreteci yazdığınızı hayal edin. Belirli bir olasılıkla olaylar oluşturmanız gerekir. Bunu yapmak için yine bir rasgele sayı üreteci kullanmanız gerekir. Farklı uygulamalar mümkündür, ancak en basiti aşağıdaki algoritmaya dayanmalıdır:
  1. bir sayı oluşturmak için kullanılan sınırları belirleyin;
  2. rastgele bir sayı üret;
  3. elde edilen numarayı işleyin.
Bu durumda maksimum 10 olacaktır.getRandomNumber(10)yöntemi ve geri dönebileceğimizi analiz edin. Her biri aynı olasılıkla — %10 olan 10 sayı (0'dan 9'a kadar) döndürebilir. Şimdi tüm olası sonuçları birleştirmemiz ve bunları olası olaylarımızla eşleştirmemiz gerekiyor. Hayal gücünüz pek çok olası kombinasyon düşünebilir, ancak en bariz olanı şudur: "Rastgele sayı [0..4] aralığındaysa, "Overslept" olayımız olur; sayı [5] aralığındaysa ..8], "Zamanında uyandım" olayı var ve sayı 9 ise "Bir saat erken uyandım" olayımız var, hepsi çok basit, [0 aralığında 5 sayı var ..4], her biri %10 olasılıkla döndürülebilir, toplamda %50; [5..8] aralığında 4 sayı vardır ve 9, ile görünen yalnızca bir sayıdır. %10 ihtimal.

int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
    System.out.println("Overslept");
} else if (randomNumber < 9) {
    System.out.println("Woke up on time");
} else {
    System.out.println("Woke up an hour early");
}
Genel olarak, rasgele sayıları kullanmanın tonlarca yolu vardır. Sadece hayal gücünüzle sınırlısınız. Ancak, tekrar tekrar bir sonuç almanız gerekiyorsa, en etkili şekilde kullanılırlar. O zaman yeni sonuç öncekinden farklı olacaktır. Tabii bir ihtimal ile. Şimdilik bu kadar! "Oyunlar" bölümü hakkında daha fazla bilgi edinmek istiyorsanız, size yardımcı olabilecek bazı yararlı belgeler aşağıda verilmiştir:
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION