Dans
la section « Jeux » de JavaRush, vous trouverez des projets passionnants pour l'écriture de jeux informatiques populaires. Voulez-vous créer votre propre version des jeux populaires « 2048 », « Sapper », « Snake » et d'autres jeux ? C'est simple. Nous avons transformé l'écriture de jeux en un processus étape par étape.
Pour vous essayer en tant que développeur de jeux, vous n'avez pas besoin d'être un programmeur avancé, mais un certain ensemble de connaissances Java est toujours requis. Vous trouverez ici
des informations qui vous seront utiles lors de l'écriture de jeux .
1. Héritage
Travailler avec le moteur de jeu JavaRush implique l'utilisation de l'héritage. Mais que faire si vous ne savez pas ce que c'est ? D'une part, il faut comprendre ce sujet : il est étudié au
niveau 11 . En revanche, le moteur a été délibérément conçu pour être très simple, afin que vous puissiez vous débrouiller avec une connaissance superficielle de l'héritage. Alors, qu’est-ce que l’héritage ? Pour le dire très simplement, l’héritage est la relation entre deux classes. L'un d'eux devient le parent et le second devient l'enfant (classe successeur). Dans ce cas, la classe parent peut même ne pas savoir qu’elle possède des classes descendantes. Ceux. il ne tire aucun avantage particulier de la présence de classes héritières. Mais l’héritage offre de nombreux avantages à une classe descendante. Et le principal est que toutes les variables et méthodes de la classe parent apparaissent dans la classe enfant, comme si le code de la classe parent était copié dans la classe enfant. Ce n’est pas tout à fait vrai, mais cela fera l’affaire pour une compréhension simplifiée de l’héritage. Voici quelques exemples pour mieux comprendre l’héritage.
Exemple 1 : l'héritage le plus simple.
public class Родитель {
}
|
La classe Child hérite de la classe Parent en utilisant le mot clé extends . |
public class Потомок extends Родитель {
}
|
Exemple 2 : Utilisation de variables de classe parent.
public class Родитель {
public int age;
public String name;
}
|
La classe Child peut utiliser les variables age et name de la classe Parent comme si elles y étaient déclarées. |
public class Потомок extends Родитель {
public void printInfo() {
System.out.println(name+" "+age);
}
}
|
Exemple 3 : Utilisation des méthodes de la classe parent.
public class Родитель {
public int age;
public String name;
public getName() {
return name;
}
}
|
La classe Child peut utiliser les variables et méthodes de la classe Parent comme si elles y étaient déclarées. Dans cet exemple, nous utilisons la méthode getName (). |
public class Потомок extends Родитель {
public void printInfo() {
System.out.println(getName()+" "+age);
}
}
|
Voici à quoi ressemble la classe
Descendant du point de vue du compilateur :
public class Потомок extends Родитель {
public int age;
public String name;
public getName() {
return name;
}
public void printInfo() {
System.out.println(getName()+" "+age);
}
}
2. Remplacement de méthode
Parfois, il arrive que nous ayons hérité de notre classe Descendant d'une classe Parent très utile, ainsi que de toutes les variables et méthodes, mais certaines méthodes ne fonctionnent pas exactement comme nous le souhaitons. Ou pas du tout comme nous ne le souhaitons pas. que-faire dans cette situation? Nous pouvons remplacer une méthode que nous n’aimons pas. Cela se fait très simplement : dans notre classe Descendant, nous déclarons simplement une méthode avec la même signature (en-tête) que la méthode de la classe Parent et y écrivons notre code.
Exemple 1 : remplacement de méthode.
public class Родитель {
public String name;
public void setName (String nameNew) {
name = nameNew;
}
public getName() {
return name;
}
}
|
La méthode printInfo() imprimera la phrase "Luke, No !!!" |
public class Потомок extends Родитель {
public void setName (String nameNew) {
name = nameNew + ",No!!!";
}
public void printInfo() {
setName("Luke");
System.out.println( getName());
}
}
|
Voici à quoi ressemble la classe
Descendant du point de vue du compilateur :
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());
}
}
Exemple 2 : un peu de magie de l'héritage (et du remplacement de méthode).
public class Родитель {
public getName() {
return "Luke";
}
public void printInfo() {
System.out.println(getName());
}
}
|
public class Потомок extends Родитель {
public getName() {
return "I'm your father, Luke";
}
}
|
Dans cet exemple : si une méthode
printInfo
(de la classe Parent) n'est pas surchargée dans la classe Descendant, lorsque cette méthode est appelée sur un objet de la classe Descendant, c'est sa méthode qui sera appelée
getName()
, et non
getName()
la classe Parent.
Родитель parent = new Родитель ();
parent.printnInfo();
|
Ce code affiche l'inscription "Luke" sur l'écran . |
Потомок child = new Потомок ();
child.printnInfo();
|
Ce code affiche l'inscription « Je suis ton père, Luke » ; . |
Voici à quoi ressemble la classe
Descendant du point de vue du compilateur :
public class Потомок extends Родитель {
public getName() {
return "I'm your father, Luke";
}
public void printInfo() {
System.out.println(getName());
}
}
3. Listes
Si vous n'avez pas encore découvert les listes, voici une brève introduction. Vous pouvez trouver des informations complètes sur
les niveaux 6-7 du cours JavaRush .
Les listes ont beaucoup en commun avec les tableaux :
- peut stocker beaucoup de données d'un certain type ;
- vous permettent de récupérer des éléments par leur index/numéro ;
- les indices des éléments commencent à 0.
Avantages des listes : contrairement aux tableaux, les listes peuvent changer de taille de manière dynamique. Immédiatement après sa création, la liste a une taille de 0. À mesure que vous ajoutez des éléments à la liste, sa taille augmente. Exemple de création d'une liste :
ArrayList<String> myList = new ArrayList<String>();
La valeur entre crochets est le type de données que la liste peut stocker. Voici quelques méthodes pour travailler avec une liste :
Code |
Brève description de ce que fait le code |
ArrayList<String> list = new ArrayList<String>(); |
Création d'une nouvelle liste de chaînes |
list.add("name"); |
Ajouter un élément à la fin de la liste |
list.add(0, "name"); |
Ajouter un élément au début de la liste |
String name = list.get(5); |
Récupère un élément par son index |
list.set(5, "new name"); |
Changer l'élément par son index |
int count = list.size(); |
Obtenir le nombre d'éléments dans une liste |
list.remove(4); |
Supprimer un élément d'une liste |
Vous pouvez en savoir plus sur les listes dans ces articles :
- Classe ArrayList
- ArrayList de travail en images
- Supprimer un élément d'une ArrayList
4. Tableaux
Qu'est-ce qu'une matrice ? Une matrice n'est rien de plus qu'un tableau rectangulaire pouvant être rempli de données. En d’autres termes, il s’agit d’un tableau à deux dimensions. Comme vous le savez probablement, les tableaux en Java sont des objets. Un type de tableau unidimensionnel standard
int
ressemble à ceci :
int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
Imaginons cela visuellement :
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
32 |
43 |
54 |
15 |
36 |
67 |
28 |
La ligne supérieure indique les adresses des cellules. Autrement dit, pour obtenir le nombre 67, vous devez accéder à l'élément du tableau avec l'index 6 :
int number = array[6];
Tout est très simple ici. Un tableau à deux dimensions est un tableau de tableaux à une dimension. Si c’est la première fois que vous entendez parler de cela, arrêtez-vous et imaginez-le dans votre tête. Un tableau à deux dimensions ressemble à ceci :
0 |
Tableau unidimensionnel |
Tableau unidimensionnel |
1 |
Tableau unidimensionnel |
2 |
Tableau unidimensionnel |
3 |
Tableau unidimensionnel |
4 |
Tableau unidimensionnel |
5 |
Tableau unidimensionnel |
6 |
Tableau unidimensionnel |
7 |
Tableau unidimensionnel |
Dans le 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 |
Pour obtenir la valeur 47, vous devez accéder à l'élément matriciel en [4][2].
int number = matrix[4][2];
Si vous remarquez, les coordonnées matricielles sont différentes du système de coordonnées rectangulaires classique (système de coordonnées cartésiennes).
Lorsque vous accédez à une matrice, vous spécifiez d'abord y puis x , alors qu'en mathématiques, il est courant de spécifier x(x, y) en premier. Vous vous demandez peut-être : « Pourquoi ne pas inverser la matrice dans votre imagination et accéder aux éléments de la manière habituelle via (x, y) ? Cela ne changera pas le contenu de la matrice. Oui, rien ne changera. Mais dans le monde de la programmation, il est d’usage de faire référence aux matrices sous la forme « d’abord y, puis x ». Cela doit être pris pour acquis. Parlons maintenant de la projection de la matrice sur notre moteur (classe
Game
). Comme vous le savez, le moteur dispose de nombreuses méthodes qui modifient les cellules du terrain de jeu à des coordonnées données. Par exemple, le
setCellValue(int x, int y, String value)
. Il définit une certaine cellule avec les coordonnées (x, y) à la valeur
value
. Comme vous l'avez remarqué, cette méthode prend d'abord exactement x, comme dans le système de coordonnées classique. Les autres méthodes du moteur fonctionnent de la même manière. Lors du développement de jeux, il sera souvent nécessaire de reproduire l’état de la matrice à l’écran. Comment faire cela ? Tout d’abord, dans une boucle, vous devez parcourir tous les éléments de la matrice. Deuxièmement, pour chacun d’eux, appelez une méthode à afficher avec des coordonnées INVERSÉES. Exemple:
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]));
}
}
}
Naturellement, l’inversion fonctionne dans deux directions.
setCellValue
Vous pouvez passer (i, j) à la méthode , mais en même temps prendre l'élément [j][i] de la matrice. L'inversion peut paraître un peu difficile, mais c'est quelque chose à garder à l'esprit. Et toujours, si des problèmes surviennent, cela vaut la peine de prendre un morceau de papier avec un stylo, de dessiner une matrice et de reproduire les processus qui s'y déroulent.
5. Nombres aléatoires
Comment travailler avec un générateur de nombres aléatoires ? La classe
Game
définit une méthode
getRandomNumber(int)
. Sous le capot, il utilise une classe
Random
du package java.util, mais cela ne change rien au principe de travail avec un générateur de nombres aléatoires.
getRandomNumber(int)
Prend un entier comme argument . Ce nombre sera la limite supérieure que le générateur peut renvoyer. La limite inférieure est 0.
Important! Le générateur ne renverra JAMAIS un nombre limite supérieur. Par exemple, s’il est appelé
getRandomNumber(3)
de manière aléatoire, il peut renvoyer 0, 1, 2. Comme vous pouvez le voir, il ne peut pas renvoyer 3. Cette utilisation d’un générateur est assez simple, mais très efficace dans de nombreux cas.
Vous devez obtenir un nombre aléatoire dans certaines limites : Imaginez que vous ayez besoin d'un nombre à trois chiffres (100..999). Comme vous le savez déjà, le nombre minimum renvoyé est 0. Vous devrez donc y ajouter 100. Mais dans ce cas, vous devez faire attention à ne pas dépasser la limite supérieure. Pour obtenir 999 comme valeur aléatoire maximale, vous devez appeler la méthode
getRandomNumber(int)
avec un argument de 1000. Mais nous nous souvenons de l'ajout ultérieur de 100 : cela signifie que la limite supérieure doit être abaissée de 100. C'est-à-dire le code pour obtenir un Un nombre aléatoire à trois chiffres ressemblerait à ceci :
int number = 100 + getRandomNumber(900);
Mais pour simplifier une telle procédure, le moteur fournit une méthode
getRandomNumber(int, int)
qui prend le nombre minimum à renvoyer comme premier argument. En utilisant cette méthode, l'exemple précédent peut être réécrit :
int number = getRandomNumber(100, 1000);
Des nombres aléatoires peuvent être utilisés pour obtenir un élément de tableau aléatoire :
String [] names = {"Andrey", "Валентин", "Сергей"};
String randomName = names[getRandomNumber(names.length)]
Déclencher certains événements avec une certaine probabilité. La matinée d’une personne commence selon des scénarios possibles : Dormir trop longtemps – 50 % ; Je me suis levé à l'heure – 40 % ; Je me suis levé une heure plus tôt que prévu – 10 %. Imaginez que vous écrivez un émulateur matinal humain. Vous devez déclencher des événements avec une certaine probabilité. Pour ce faire, vous devez encore une fois utiliser un générateur de nombres aléatoires. Les implémentations peuvent être différentes, mais la plus simple doit suivre l'algorithme suivant :
- nous fixons les limites dans lesquelles nous devons générer le nombre ;
- générer un nombre aléatoire ;
- Nous traitons le nombre résultant.
Donc, dans ce cas, la limite sera de 10. Appelons la méthode
getRandomNumber(10)
et analysons ce qu'elle peut nous retourner. Il peut renvoyer 10 chiffres (de 0 à 9) et chacun avec la même probabilité - 10 %. Nous devons maintenant combiner tous les résultats possibles et les faire correspondre à nos événements possibles. Il peut y avoir de nombreuses combinaisons, selon votre imagination, mais la plus évidente sonne : "Si un nombre aléatoire se situe entre [0..4] - appelez l'événement "Sursommeil", si le nombre est compris entre [5..8". ] - "Réveillez-vous" à l'heure ", et seulement si le chiffre est 9, alors" Je me suis levé une heure plus tôt que prévu. Tout est très simple : à l'intérieur de [0..4] il y a 5 nombres, dont chacun peut revenir avec une probabilité de 10 %, ce qui au total sera de 50 % ; dans [5..8], il y a 4 nombres, et 9 est le seul nombre qui apparaît avec une probabilité de 10 %. Dans le code, toute cette conception intelligente semble encore plus simple :
int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
System.out.println("Проспал ");
} else if (randomNumber < 9) {
System.out.println("Встал вовремя ");
} else {
System.out.println("Встал на час раньше положенного ");
}
En général, il existe de nombreuses options pour utiliser des nombres aléatoires. Tout dépend uniquement de votre imagination. Mais ils sont utilisés plus efficacement si vous avez besoin d'obtenir un résultat à plusieurs reprises. Ce résultat sera alors différent du précédent. Avec une certaine probabilité, bien sûr. C'est tout! Si vous souhaitez en savoir plus sur la section Jeux, voici une documentation utile qui peut vous aider :
GO TO FULL VERSION