JavaRush /Java Blog /Random EN /Games Section on JavaRush: Useful Theory

Games Section on JavaRush: Useful Theory

Published in the Random EN group
In the "Games" section of CodeGym you will find exciting projects for writing popular computer games. Do you want to create your own version of the popular 2048, Minesweeper, Snake and other games? It's simple. We've turned game writing into a step-by-step process. ChapterTo try yourself as a game developer, you do not have to be an advanced programmer, but a certain set of Java knowledge is still required. Here you will find information that will be useful when writing games .

1. Inheritance

Working with the CodeGym game engine involves the use of inheritance. But what if you don't know what it is? On the one hand, you need to understand this topic: it is studied at level 11. On the other hand, the engine was specifically designed to be very simple, so you can get by with a superficial knowledge of inheritance. So what is inheritance? To put it very simply, inheritance is a relationship between two classes. One of them becomes a parent, and the second becomes a child (class-heir). In this case, the parent class may not even know that it has descendant classes. Those. it doesn't get much benefit from having derived classes. But inheritance gives many advantages to a descendant class. And the main one is that all the variables and methods of the parent class appear in the child class, as if the code of the parent class was copied into the child class. This is not entirely true, but for a simplified understanding of inheritance, it will do. Here are some examples to better understand inheritance. Example 1:the simplest inheritance.
public class Родитель {

}
The Child class is inherited from the Parent class using the extends keyword .
public class Потомок extends Родитель {

}
Example 2: using parent class variables.
public class Родитель {

   public int age;
   public String name;
}
The Child class can use the age and name variables of the Parent class as if they were declared in it.
public class Потомок extends Родитель {

   public void printInfo() {

     System.out.println(name+" "+age);
   }
}
Example 3: using parent class methods.
public class Родитель {

   public int age;
   public String name;

   public getName() {
      return name;
   }
}
The Child class can use the variables and methods of the Parent class as if they were declared in it. In this example, we are using the getName () method.
public class Потомок extends Родитель {

   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}
Here's what the Child class looks like from the compiler's point of view:
public class Потомок extends Родитель {

   public int age; //  унаследованная переменная
   public String name; //  унаследованная переменная

   public getName() { //  унаследованный метод.
      return name;
  }
   public void printInfo() {

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

2. Overriding Methods

Sometimes there are situations when we inherited our Child class from some Parent class that is very useful to us, along with all the variables and methods, but some methods do not work quite the way we want. Or not at all the way we want. What to do in this situation? We can override the method we didn't like. This is done very simply: in our Child class, we simply declare a method with the same signature (header) as the Parent class method and write our code in it. Example 1: overriding a method.
public class Родитель {

   public String name;

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

   public getName() {
      return name;
  }
}
The printInfo() method will print the phrase "Luke, No!!!" to the screen.
public class Потомок extends Родитель {

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

   public void printInfo() {

      setName("Luke");
      System.out.println( getName());
   }
}
Here's what the Child class looks like from the compiler's point of view:
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());
   }
}
Example 2: A bit of inheritance (and method overriding) magic.
public class Родитель {

   public getName() {
      return "Luke";
  }
   public void printInfo() {

     System.out.println(getName());
   }
}
public class Потомок extends Родитель {

   public getName() {
      return "I'm your father, Luke";
  }
}
In this example: if the method is not overridden in the Child class printInfo(from the Parent class), when this method is called on an object of the Child class, its method will be called getName(), and not getName()the Parent class.
Родитель parent = new Родитель ();
parent.printnInfo();
This code is displayed on the screen the inscription "Luke" .
Потомок child = new Потомок ();
child.printnInfo();
This code displays the inscription "I'm your father, Luke;" .
Here's what the Child class looks like from the compiler's point of view:
public class Потомок extends Родитель {

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

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

3. Lists

If you're not familiar with Lists yet, here's a brief introduction. Full details can be found at levels 6-7 of the CodeGym course . Lists have a lot in common with arrays:
  • can store a lot of data of a certain type;
  • allow to get elements by their index/number;
  • element indexes start at 0.
Advantages of lists: Unlike arrays, lists can dynamically change size. Immediately after creation, the list has a size of 0. As elements are added to the list, its size increases. List creation example:
ArrayList<String> myList = new ArrayList<String>(); // создание нового списка типа ArrayList
The value in angle brackets is the type of data that the list can store. Here are some methods for working with a list:
Code Brief description of code actions
ArrayList<String> list = new ArrayList<String>(); Creating a new list of strings
list.add("name"); Add an element to the end of the list
list.add(0, "name"); Add an element to the beginning of the list
String name = list.get(5); Get an element by its index
list.set(5, "new name"); Change element by its index
int count = list.size(); Get the number of elements in a list
list.remove(4); Remove item from list
You can learn more about lists in these articles:
  1. ArrayList class
  2. ArrayList work in pictures
  3. Removing an element from an ArrayList

4. Arrays

What is a matrix? A matrix is ​​nothing more than a rectangular table that can be filled with data. In other words, it's a two-dimensional array. As you probably know, arrays in Java are objects. A standard one-dimensional array of type intlooks like this:
int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
Let's visualize it:
0 1 2 3 4 5 6 7
12 32 43 54 15 36 67 28
The top row indicates cell addresses. That is, to get the number 67, you need to refer to the array element with index 6:
int number = array[6];
Everything is very simple here. A two-dimensional array is an array of one-dimensional arrays. If you're hearing about it for the first time, stop and imagine it in your head. A two-dimensional array looks like this:
0 one dimensional array one dimensional array
1 one dimensional array
2 one dimensional array
3 one dimensional array
4 one dimensional array
5 one dimensional array
6 one dimensional array
7 one dimensional array
In 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
To get the value 47, you need to refer to the matrix element at address [4][2].
int number = matrix[4][2];
If you notice, the matrix coordinates are different from the classical rectangular coordinate system (Cartesian coordinate system). When referring to a matrix, you first specify y and then x , while in mathematics it is customary to specify x (x, y) first. You may be wondering, “Why not flip the matrix in your imagination and access the elements in the usual way through (x, y)? The contents of the matrix will not change from this.” Yes, nothing will change. But in the world of programming, it is customary to refer to matrices in the form "first y, then x." This must be taken for granted. Now let's talk about projecting a matrix onto our engine (class Game). As you know, the engine has many methods that change the cells of the playing field at given coordinates. For example, the methodsetCellValue(int x, int y, String value). It sets a certain cell with coordinates (x, y) to value. As you noticed, this method first takes exactly x, as in the classical coordinate system. Other methods of the engine work in a similar way. When developing games, it will often be necessary to reproduce the state of the matrix on the screen. How to do it? First, in the loop, you need to iterate over all the elements of the matrix. Second, for each of them, call the method to display with INVERTED coordinates. Example:
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, inversion works in two directions. setCellValueYou can pass (i, j) to the method , but at the same time take the element [j][i] from the matrix. Inversion may seem a bit difficult, but it's something to keep in mind. And always, if there are any problems, you should take a piece of paper with a pen, draw a matrix and reproduce what processes are happening with it.

5. Random numbers

How to work with random number generator? The class Gamehas a method defined getRandomNumber(int). Under the hood, it uses a class Randomfrom the java.util package, but the principle of working with a random number generator does not change from this. getRandomNumber(int)It takes an integer as an argument . This number will be the upper bound that the generator can return. The lower bound is 0. Important! A generator will NEVER return an upper bound number. For example, if you call getRandomNumber(3)it randomly, it can return 0, 1, 2. As you can see, it cannot return 3. This use of a generator is quite simple, but very effective in many cases. You need to get a random number within some limits: Imagine that you need some three-digit number (100..999). As you already know, the minimum return value is 0. This means that you will need to add 100 to it. But in this case, you need to take care not to step over the upper limit. To get 999 as the maximum random value, call the methodgetRandomNumber(int)with the argument 1000. But we remember about the subsequent addition of 100: this means that the upper limit should also be lowered by 100. That is, the code for obtaining a random three-digit number will look like this:
int number = 100 + getRandomNumber(900);
But to simplify such a procedure, the engine provides a method getRandomNumber(int, int)that takes the minimum number to return as the first argument. Using this method, the previous example can be rewritten:
int number = getRandomNumber(100, 1000);
Random numbers can be used to get a random array element:
String [] names = {"Andrey", "Валентин", "Сергей"};
String randomName = names[getRandomNumber(names.length)]
Trigger certain events with a certain probability. A person's morning begins according to possible scenarios: Overslept - 50%; Got up on time - 40%; Got up an hour earlier than expected - 10%. Imagine that you are writing a human morning emulator. You need to trigger events with a certain probability. To do this, again, you need to use a random number generator. Implementations may be different, but the simplest should occur according to the following algorithm:
  1. set the limits in which you need to generate a number;
  2. generate a random number;
  3. process the resulting number.
So, in this case, the limit will be 10. Let's call the methodgetRandomNumber(10)and analyze what he can return to us. It can return 10 digits (from 0 to 9) and each with the same probability - 10%. Now we need to combine all possible outcomes and match them with our possible events. There can be a lot of combinations, depending on your imagination, but the most obvious one sounds: “If the random number lies within [0..4] - call the “Sleep” event, if the number is within [5..8] - “Woke up on time”, and only if the number is 9, then “I got up an hour earlier than expected”. Everything is very simple: within [0..4] there are 5 numbers, each of which can return with a probability of 10%, which in total will be 50%; within [5..8] there are 4 numbers, and 9 is the only number that appears with a probability of 10%. In code, this whole clever construction looks even simpler:
int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
    System.out.println("Проспал ");
} else if (randomNumber < 9) {
    System.out.println("Встал вовремя ");
} else {
    System.out.println("Встал на час раньше положенного ");
}
In general, there can be a lot of options for using random numbers. It all depends on your imagination. But it is most effective to use them if you need to repeatedly get some kind of result. Then this result will be different from the previous one. With some probability, of course. That's all! If you'd like to learn more about the Games section, here's some helpful documentation to help you:
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION