CodeGym /Java блог /Случаен /Раздел за игри в CodeGym: Полезна теория
John Squirrels
Ниво
San Francisco

Раздел за игри в CodeGym: Полезна теория

Публикувано в групата
В раздела „Игри“ на CodeGym ще намерите вълнуващи проекти, които включват писане на популярни компютърни игри. Искате ли да създадете своя собствена version на популярните игри 2048, Minesweeper, Snake и други игри? Просто е. Превърнахме писането на игри в процес стъпка по стъпка. Раздел "Игри" в CodeGym: Полезна теория - 1За да тествате способностите си като разработчик на игри, не е нужно да сте напреднал програмист, но са необходими специфични познания по Java. Тук ще намерите информация, която ще бъде полезна при писането на игри .

1. Наследство

Работата с двигателя на играта CodeGym включва използване на наследяване. Но Howво, ако не знаете Howво е това? От една страна, трябва да разберете тази тема: тя се изучава на ниво 11. От друга страна, двигателят е специално проектиран да бъде много прост, така че можете да се измъкнете с повърхностни познания за наследството. И така, Howво е наследство? Казано много просто, наследяването е връзка между два класа. Единият от тях става родител, а другият става дете (потомък). Освен това родителският клас може дори да не знае, че има потомци. С други думи, не печели няHowво особено предимство, като има потомци. Но наследяването дава на потомъка много предимства. И най-важното е, че всички променливи и методи на родителския клас се появяват в потомъка, сякаш codeът на родителския клас е копиран в наследствения клас. Това не е съвсем точно описание, но ще бъде достатъчно за опростено разбиране на наследството. Пример 1: Най-простото наследяване.

public class Parent {

}
Класът Child наследява класа Parent с помощта на ключовата дума extends .

public class Child extends Parent {

}
Пример 2: Използване на променливите на родителския клас.

public class Parent {

   public int age;
   public String name;
}
Класът Child може да използва променливите за възраст и име на класа Parent, сякаш са декларирани в класа Parent .

public class Child extends Parent {

   public void printInfo() {

     System.out.println(name+" "+age);
   }
}
Пример 3: Използване на методите на родителския клас.

public class Parent {

   public int age;
   public String name;

   public getName() {
      return name;
  }
}
Класът Child може да използва променливите и методите на класа Parent , сякаш са декларирани в класа Child. В този пример използваме метода getName() .

public class Child extends Parent {

   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}
Ето How изглежда класът Child за компилатора:

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. Основни методи

Понякога има ситуации, в които караме нашия клас Child да наследи някой много полезен клас Parent, заедно с всички негови променливи и методи, но някои от методите не работят точно Howто искаме. Или изобщо не Howто искаме. Какво можем да направим в тази ситуация? Можем да отменим метода, който не ни харесва. Това се прави много лесно: в нашия клас Child ние просто декларираме метод със същата сигнатура като метода в класа Parent и след това пишем собствен code в него. Пример 1: Замяна на метод.

public class Parent {

   public String name;

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

   public getName() {
      return name;
  }
}
Методът printInfo() ще покаже „Лука, не!!!“

public class Child extends Parent{

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

   public void printInfo() {
      setName("Luke");
      System.out.println(getName());
   }
}
Ето How изглежда класът Child за компилатора:

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());
   }
}
Пример 2: НяHowва магия за наследяване (и отмяна на метод).

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";
  }
}
В този пример, ако printInfoметодът (от класа Parent) не е заменен в класа Child, когато този метод се извика на обект Child, неговият getName()метод ще бъде извикан instead of getName()метода на класа Parent.

Parent parent = new Parent ();
parent.printnInfo();
Този code показва "Лука" на екрана.

Child child = new Child ();
child.printnInfo();
Този code показва на екрана „Лука, аз съм твоят баща“ .
Ето How изглежда класът Child за компилатора:

public class Child extends Parent {

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

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

3. Списъци

Ако все още не сте срещали списъци (List), ето кратък преглед. Можете да намерите пълна информация в нива 6-7 на курса CodeGym . Списъците имат много общо с масивите:
  • можете да съхранявате много данни от определен тип;
  • те ви позволяват да получавате елементи по техния индекс;
  • Индексите на елементите започват от 0.
Предимства на списъците: За разлика от масивите списъците могат да променят размера си динамично. Когато се създаде списък, размерът му е 0. Докато добавяте елементи към списък, размерът му се увеличава. Ето пример за създаване на списък:

ArrayList<String> myList = new ArrayList<String>(); // Create a new ArrayList
Стойността в ъгловите скоби показва типа данни, които списъкът може да съхранява. Ето някои методи за работа със списъка:
Код Кратко описание на това Howво прави codeът
ArrayList<String> list = new ArrayList<String>(); Създайте нов списък с низове
list.add("name"); Добавете елемент в края на списъка
list.add(0, "name"); Добавете елемент в началото на списъка
String name = list.get(5); Вземете елемент по неговия индекс
list.set(5, "new name"); Промяна на елемент по неговия индекс
int count = list.size(); Вземете броя на елементите в списъка
list.remove(4); Изтриване на елемент от списъка
Можете да научите повече за списъците от следните статии:
  1. Клас ArrayList
  2. ArrayList в снимки
  3. Изтриване на елемент от ArrayList

4. Масиви

Какво е матрица? Матрицата не е нищо повече от правоъгълна table, която може да бъде попълнена с данни. С други думи, това е двуизмерен масив. Както вероятно знаете, масивите в Java са обекти. Стандартен едномерен intмасив изглежда така:

int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
Можем да го визуализираме така:
0 1 2 3 4 5 6 7
12 32 43 54 15 36 67 28
Най-горният ред показва addressите на клетките. С други думи, за да получите числото 67, трябва да получите достъп до елемента на масива с индекс 6:

int number = array[6];
Всичко е много просто. Двумерният масив е масив от едномерни масиви. Ако чувате за това за първи път, спрете и си го представете в главата си. Двуизмерният масив изглежда така:
0 Едномерен масив Едномерен масив
1 Едномерен масив
2 Едномерен масив
3 Едномерен масив
4 Едномерен масив
5 Едномерен масив
6 Едномерен масив
7 Едномерен масив
В 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
За да получите стойност 47, трябва да се обърнете към матричния елемент в [4][2].

int number = matrix[4][2];
Може би сте забелязали, че матричните координати са различни от класическата правоъгълна координатна система (декартова координатна система). Когато получите достъп до матрицата, първо посочвате координатата y и след това координатата x. В математиката е обичайно първо да се указва координатата x, т.е. (x, y). Може би се чудите: „Е, защо не завъртите вашето представяне на матрицата и след това да получите достъп до елементите по обичайния начин, като използвате (x, y)? Това няма да промени съдържанието на матрицата“. Да, нищо нямаше да се промени. Но в света на програмирането приетата практика е да се осъществява достъп до матрици "първо по y, след това по x". Трябва да приемете това като правилния начин. Сега нека поговорим за проектирането на матрицата към нашия двигател (Gameклас). Както знаете, двигателят има много методи, които променят клетките на игралното поле при определени координати. Например setCellValue(int x, int y, String value)методът. Той задава конкретна клетка с координати (x, y), равни на параметъра стойност. Може би сте забелязали, че този метод първо взема x, точно Howто в класическата координатна система. Другите методи на двигателя работят по подобен начин. При разработването на игри често ще е необходимо да се възпроизведе състоянието на матрица на екрана. Как да направим това? Първо, трябва да преминете през всички матрични елементи в цикъл. Второ, извикайте метода за показване за всеки от тях, като използвате REVERSED координати. Например:

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]));
        }
    }
}
Естествено, обръщането работи и в двете посоки. Можете да предадете (i, j) на setCellValueметода и едновременно с това да вземете елемент [j][i] от матрицата. Обръщането на координатите може да изглежда малко трудно, но трябва да го запомните. И винаги, ако срещнете няHowъв проблем, трябва да вземете лист хартия и химикал, да начертаете матрицата и да възпроизведете процесите, включващи матрицата.

5. Случайни числа

Как работите с генератор на произволни числа? Класът Gameопределя getRandomNumber(int)метода. Под капака той използва Randomкласа от пакета java.util, но начинът, по който работите с генератора на произволни числа, не се променя. getRandomNumber(int)приема цяло число като аргумент. Това число ще бъде горната граница на това, което генераторът може да върне. Долната граница е 0. важно! Генераторът НИКОГА няма да върне числото на горната граница. Например, ако извикате getRandomNumber(3), той произволно ще върне 0, 1 or 2. Както можете да видите, не може да върне 3. Използването на генератора по този начин е доста просто, но много ефективно в много случаи. Да предположим, че трябва да получите произволно число в няHowъв диапазон: Представете си, че имате нужда от трицифрено число в диапазона [100..999]. Както вече знаете, минималният върнат брой е 0. Така че ще трябва да добавите 100. Но в този случай трябва да внимавате да не превишите горната граница. За да получите 999 като максимална произволна стойност, извикайтеgetRandomNumber(int)метод с аргумента 1000. Но сега си спомняме, че добавяме 100 към резултата: това означава, че горната граница трябва да бъде намалена със 100. С други думи, codeът за получаване на нашето случайно трицифрено число ще изглежда така :

int number = 100 + getRandomNumber(900);
Но за да опрости тази proceduresа, двигателят предоставя метод, getRandomNumber(int, int)чийто първи параметър е минималният брой за връщане. Използвайки този метод, предишният пример може да бъде пренаписан, Howто следва:

int number = getRandomNumber(100, 1000);
Случайни числа могат да се използват за получаване на произволен елемент от масив:

String [] names = {"Sarah", "Val", "Sergey"};
String randomName = names[getRandomNumber(names.length)]
Генериране на определени събития с известна вероятност. За хората сутрините започват с няколко възможни сценария: Проспали – 50% шанс; Събуди се навреме – 40% шанс; Събудих се един час по-рано – шанс 10%. Представете си, че пишете генератор на сутрешни резултати. Трябва да генерирате събития с определена вероятност. За да направите това, отново трябва да използвате генератор на произволни числа. Възможни са различни реализации, но най-простата трябва да се основава на следния алгоритъм:
  1. задайте ограниченията, използвани за генериране на число;
  2. генериране на случайно число;
  3. обработете полученото число.
В този случай максимумът ще бъде 10. Обадете се наgetRandomNumber(10)метод и анализираме, че можем да го върнем. Може да върне 10 числа (от 0 до 9), всяко с еднаква вероятност — 10%. Сега трябва да комбинираме всички възможни резултати и да ги съпоставим с нашите възможни събития. Вашето въображение може да измисли много възможни комбинации, но ето най-очевидната: „Ако произволното число е в диапазона [0..4], имаме събитието „Проспали“; ако числото е в диапазона [5 ..8], имаме събитието „Събудих се навреме"; и ако числото е 9, тогава имаме събитието „Събудих се един час по-рано". Всичко е много просто. Има 5 числа в диапазона [0 ..4], всяко от които може да бъде върнато с вероятност от 10%, за общо 50%; има 4 числа в диапазона [5..8], добре, а 9 е само едно число, което се появява с вероятност от 10%.

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");
}
Като цяло има много начини за използване на произволни числа. Вие сте ограничени само от вашето въображение. Но те се използват най-ефективно, ако трябва многократно да получите няHowъв резултат. Тогава новият резултат ще бъде различен от предишния. С известна вероятност, разбира се. Това е всичко за сега! Ако искате да научите повече за раздела „Игри“, ето полезна documentация, която може да ви помогне:
Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION