
Apprendre les modèles de conception de jeux avec Unreal Engine
Description
Introduction au livre
Apprenez les modèles de conception pratiques en C++ pour Unreal Engine 5 auprès d'experts.
Les modèles de conception nous aident à écrire du code plus rapidement et plus facile à maintenir.
Ce livre explique différents modèles de conception et vous montre comment les appliquer aux projets Unreal Engine 5.
En acquérant une compréhension plus approfondie des modèles de conception et du fonctionnement du moteur, vous pourrez surmonter les limitations que vous avez ressenties dans votre pratique du développement sous Unreal.
En commençant par les fondamentaux de la programmation Unreal C++ et des Blueprints, vous acquerrez une solide compréhension des concepts et des avantages que vous devez connaître pour appliquer des modèles à votre code.
Tout d'abord, dans la première partie, nous examinerons les modèles intégrés au cœur d'Unreal Engine 5, tels que les doubles tampons, les poids légers, le partitionnement de l'espace, les composants, les méthodes de mise à jour et les arbres de comportement.
Dans la partie 2, nous verrons comment remplacer les « ticks », les modèles d'interface et d'observateur d'événements, et même UML pour le découplage des références, et nous écrirons un exemple de gameplay en C++.
La partie 3 se concentre sur l'utilisation des modèles de conception pour l'optimisation des performances avant la publication, couvrant les modèles comportementaux tels que les modèles singleton, de commande et d'état, les modèles de modèles pour structurer le code, les bacs à sable de sous-classes, l'implémentation d'objets de type et enfin les indicateurs de modification, la localité des données et la mise en commun des objets.
Les modèles de conception nous aident à écrire du code plus rapidement et plus facile à maintenir.
Ce livre explique différents modèles de conception et vous montre comment les appliquer aux projets Unreal Engine 5.
En acquérant une compréhension plus approfondie des modèles de conception et du fonctionnement du moteur, vous pourrez surmonter les limitations que vous avez ressenties dans votre pratique du développement sous Unreal.
En commençant par les fondamentaux de la programmation Unreal C++ et des Blueprints, vous acquerrez une solide compréhension des concepts et des avantages que vous devez connaître pour appliquer des modèles à votre code.
Tout d'abord, dans la première partie, nous examinerons les modèles intégrés au cœur d'Unreal Engine 5, tels que les doubles tampons, les poids légers, le partitionnement de l'espace, les composants, les méthodes de mise à jour et les arbres de comportement.
Dans la partie 2, nous verrons comment remplacer les « ticks », les modèles d'interface et d'observateur d'événements, et même UML pour le découplage des références, et nous écrirons un exemple de gameplay en C++.
La partie 3 se concentre sur l'utilisation des modèles de conception pour l'optimisation des performances avant la publication, couvrant les modèles comportementaux tels que les modèles singleton, de commande et d'état, les modèles de modèles pour structurer le code, les bacs à sable de sous-classes, l'implémentation d'objets de type et enfin les indicateurs de modification, la localité des données et la mise en commun des objets.
- Vous pouvez consulter un aperçu du contenu du livre.
Aperçu
indice
À propos de l'auteur ix
Introduction du traducteur x
Présentation du réviseur technique xi
Préface du traducteur xii
Avis du lecteur bêta xv
Préface de recommandation xvi
Remerciements xviii
À propos de ce livre xix
PARTIE I Apprendre d'Unreal Engine 5
CHAPITRE 1 Comprendre Unreal Engine 5 et Layers 3
1.1 Exigences techniques 4
1.2 Présentation d'Unreal Engine 5 4
1.3 Installation d'Unreal Engine 5 et préparation de l'environnement de développement 6
1.4 Couche « floue » : Combler le fossé entre C++ et Blueprints 9
1.4.1 Spécificateurs de propriété 10 / 1.4.2 Spécificateurs de fonction 11 / 1.4.3 Utilité de l'héritage 12
1.5 Conversion de Blueprints vers C++ 13
__1.5.1 Exemple pratique 16
1.6 Résumé 19
1.7 Exercice 19
__1.7.1 Réponse correcte : 20
CHAPITRE 2 « Bonjour, motif » 21
2.1 Exigences techniques 21
2.2 Principe SOLID 23
2.2.1 Responsabilité unique 23 / 2.2.2 Système ouvert-fermé 24 / 2.2.3 Substitution Liskov 26
__2.2.4 Séparation des interfaces 27 / 2.2.5 Inversion des dépendances 30
2.3 Explorer des solutions aux problèmes courants 31
__2.3.1 Problème de la boîte mobile 32 / 2.3.2 Problème de la boîte rotative 40
__2.3.3 Problème de chaîne de coulée en cascade 43
2.4 Compromis 48
2.5 Résumé 49
CHAPITRE 3 Modèles UE5 en pratique : double tamponnage, poids légers et partitionnement spatial 51
3.1 Exigences techniques 52
3.2 Double tampon 52
3.3 Poids mouche 56
3.4 Division spatiale 58
__3.4.1 Introduction aux partitions mondiales 61
3.4.2 Comprendre le moment où les objets sont chargés 64
__3.4.3 Comment s'assurer que les acteurs requis sont chargés 67
__3.4.4 Activation des partitions du monde aux niveaux existants 69
3.5 Résumé 69
CHAPITRE 4 Modèles intégrés d'UE5 : composants, méthodes de mise à jour et arbres de comportement 71
4.1 Exigences techniques 72
4.2 Comprendre et créer des composants 72
4.3 Application de la méthode de mise à jour au prototypage du gameplay 79
4.4 Utilisation des arbres de comportement 81
__4.4.1 Création d'un contrôleur d'IA 84
__4.4.2 Création de ressources Blackboard 85
__4.4.3 Construction d'un arbre de comportement 86
4.5 Résumé 101
PARTIE II Conception modulaire anonyme
CHAPITRE 5 Élimination des tiques 105
5.1 Exigences techniques 106
5.2 Avant de commencer 106
Le monde 106 revient à 5,3 ticks
5.4 Horloge arrêtée 110
5.5 Systèmes événementiels 115
5.6 Résumé 119
CHAPITRE 6 Communication propre : Modèles d’interface et d’observateur d’événements 121
6.1 Exigences techniques 121
6.2 Communication d'interface inter-classes dans UE5 122
__6.2.1 Interface Blueprint 122
6.2.3 Différences entre les événements et les fonctions d'interface 126
6.2.4 Interfaces en C++ 129
__6.2.5 Exemple d'implémentation de la communication d'interface 130
6.3 Implémentation de la communication des délégués d'événements dans UE5 132
__6.3.1 Délégués d'événements dans les plans 132
__6.3.2 Délégués d'événements en C++ 136
6.3.3 Création d'outils utiles pour les délégués 138
6.4 Résumé 142
CHAPITRE 7 Systèmes complètement séparés 143
7.1 Exigences techniques 144
7.2 Planification d'une hiérarchie d'exemple à l'aide d'UML 144
7.2.1 Types de relations entre classes 144
__7.2.2 Diagramme de séquence 146
7.3 Séparation des connexions de référence 147
7.3.1 Modularisation et séparation 147
7.3.2 Construction d'infrastructures 151
7.3.3 Application de la méthode des plans séparés à un exemple 152
7.3.4 Avantages de la séparation 163
7.4 Résumé 164
PARTIE III Travailler avec Unreal
CHAPITRE 8 Modèles de conception de bâtiments : Singletons, commandes et état 167
8.1 Exigences techniques 167
8.2 Mise en œuvre du modèle Singleton : comprendre pourquoi il s’agit de la boîte de Pandore 168
8.3 Mise en œuvre de modèles de commande pour divers cas d'utilisation 170
8.3.1 Modèle de commande pour la fonction Annuler dans l'utilitaire d'édition 172
8.3.2 Modèles de commandes pour le gameplay en C++ 177
8.4 Création d'une structure de machine à états multicouches 180
8.4.1 Comprendre les machines à états d'animation 181
8.4.2 Implémentation de l'énumération/commutation 183
8.4.3 État statique et état instancié 185
8.4.4 Machines à états concurrents 187
__8.4.5 Machine à états hiérarchique 189
__8.4.6 Automates à pile 190
8.5 Résumé 191
CHAPITRE 9 Structuration du code à l'aide de modèles comportementaux : modèles, environnements d'exécution isolés et objets de type 193
9.1 Exigences techniques 194
9.2 Examen des modèles de gabarits 194
__9.2.1 Création d'un modèle (classe parente) 196
__9.2.2 Création d'une classe enfant 198
__9.2.3 Modèle Pistolet 200
__9.2.4 Modèle de fusil de chasse 205
9.3 Comprendre le modèle de bac à sable des sous-classes 207
__9.3.1 Création d'un bac à sable (classe parente) 208
__9.3.2 Création d'une classe enfant 211
__9.3.3 Pistolet de bac à sable 211
__9.3.4 Fusil à pompe Sandbox 213
9.4 Modèle d'objet de type 215
__9.4.1 Variantes 216 / 9.4.2 Tables de données 217 / 9.4.3 Ressources de données 218
9.5 Résumé 222
CHAPITRE 10 Optimisation par les modèles 223
10.1 Exigences techniques 224
10.2 Utilisation des indicateurs de modifications pour réduire les traitements inutiles 224
__10.2.1 Application du drapeau sale 225
10.3 L’impact de la localité des données sur l’efficacité du code 226
__10.3.1 Répartition chaud/froid 227
__10.3.2 Tableaux contigus 228
10.4 Mise en commun des objets : Gestion des ressources pour gagner du temps 229
__10.4.1 Mise en œuvre du regroupement d'objets 229
__10.4.2 Création d'un pool d'objets 231
10.5 Résumé 241
Recherche 244
Introduction du traducteur x
Présentation du réviseur technique xi
Préface du traducteur xii
Avis du lecteur bêta xv
Préface de recommandation xvi
Remerciements xviii
À propos de ce livre xix
PARTIE I Apprendre d'Unreal Engine 5
CHAPITRE 1 Comprendre Unreal Engine 5 et Layers 3
1.1 Exigences techniques 4
1.2 Présentation d'Unreal Engine 5 4
1.3 Installation d'Unreal Engine 5 et préparation de l'environnement de développement 6
1.4 Couche « floue » : Combler le fossé entre C++ et Blueprints 9
1.4.1 Spécificateurs de propriété 10 / 1.4.2 Spécificateurs de fonction 11 / 1.4.3 Utilité de l'héritage 12
1.5 Conversion de Blueprints vers C++ 13
__1.5.1 Exemple pratique 16
1.6 Résumé 19
1.7 Exercice 19
__1.7.1 Réponse correcte : 20
CHAPITRE 2 « Bonjour, motif » 21
2.1 Exigences techniques 21
2.2 Principe SOLID 23
2.2.1 Responsabilité unique 23 / 2.2.2 Système ouvert-fermé 24 / 2.2.3 Substitution Liskov 26
__2.2.4 Séparation des interfaces 27 / 2.2.5 Inversion des dépendances 30
2.3 Explorer des solutions aux problèmes courants 31
__2.3.1 Problème de la boîte mobile 32 / 2.3.2 Problème de la boîte rotative 40
__2.3.3 Problème de chaîne de coulée en cascade 43
2.4 Compromis 48
2.5 Résumé 49
CHAPITRE 3 Modèles UE5 en pratique : double tamponnage, poids légers et partitionnement spatial 51
3.1 Exigences techniques 52
3.2 Double tampon 52
3.3 Poids mouche 56
3.4 Division spatiale 58
__3.4.1 Introduction aux partitions mondiales 61
3.4.2 Comprendre le moment où les objets sont chargés 64
__3.4.3 Comment s'assurer que les acteurs requis sont chargés 67
__3.4.4 Activation des partitions du monde aux niveaux existants 69
3.5 Résumé 69
CHAPITRE 4 Modèles intégrés d'UE5 : composants, méthodes de mise à jour et arbres de comportement 71
4.1 Exigences techniques 72
4.2 Comprendre et créer des composants 72
4.3 Application de la méthode de mise à jour au prototypage du gameplay 79
4.4 Utilisation des arbres de comportement 81
__4.4.1 Création d'un contrôleur d'IA 84
__4.4.2 Création de ressources Blackboard 85
__4.4.3 Construction d'un arbre de comportement 86
4.5 Résumé 101
PARTIE II Conception modulaire anonyme
CHAPITRE 5 Élimination des tiques 105
5.1 Exigences techniques 106
5.2 Avant de commencer 106
Le monde 106 revient à 5,3 ticks
5.4 Horloge arrêtée 110
5.5 Systèmes événementiels 115
5.6 Résumé 119
CHAPITRE 6 Communication propre : Modèles d’interface et d’observateur d’événements 121
6.1 Exigences techniques 121
6.2 Communication d'interface inter-classes dans UE5 122
__6.2.1 Interface Blueprint 122
6.2.3 Différences entre les événements et les fonctions d'interface 126
6.2.4 Interfaces en C++ 129
__6.2.5 Exemple d'implémentation de la communication d'interface 130
6.3 Implémentation de la communication des délégués d'événements dans UE5 132
__6.3.1 Délégués d'événements dans les plans 132
__6.3.2 Délégués d'événements en C++ 136
6.3.3 Création d'outils utiles pour les délégués 138
6.4 Résumé 142
CHAPITRE 7 Systèmes complètement séparés 143
7.1 Exigences techniques 144
7.2 Planification d'une hiérarchie d'exemple à l'aide d'UML 144
7.2.1 Types de relations entre classes 144
__7.2.2 Diagramme de séquence 146
7.3 Séparation des connexions de référence 147
7.3.1 Modularisation et séparation 147
7.3.2 Construction d'infrastructures 151
7.3.3 Application de la méthode des plans séparés à un exemple 152
7.3.4 Avantages de la séparation 163
7.4 Résumé 164
PARTIE III Travailler avec Unreal
CHAPITRE 8 Modèles de conception de bâtiments : Singletons, commandes et état 167
8.1 Exigences techniques 167
8.2 Mise en œuvre du modèle Singleton : comprendre pourquoi il s’agit de la boîte de Pandore 168
8.3 Mise en œuvre de modèles de commande pour divers cas d'utilisation 170
8.3.1 Modèle de commande pour la fonction Annuler dans l'utilitaire d'édition 172
8.3.2 Modèles de commandes pour le gameplay en C++ 177
8.4 Création d'une structure de machine à états multicouches 180
8.4.1 Comprendre les machines à états d'animation 181
8.4.2 Implémentation de l'énumération/commutation 183
8.4.3 État statique et état instancié 185
8.4.4 Machines à états concurrents 187
__8.4.5 Machine à états hiérarchique 189
__8.4.6 Automates à pile 190
8.5 Résumé 191
CHAPITRE 9 Structuration du code à l'aide de modèles comportementaux : modèles, environnements d'exécution isolés et objets de type 193
9.1 Exigences techniques 194
9.2 Examen des modèles de gabarits 194
__9.2.1 Création d'un modèle (classe parente) 196
__9.2.2 Création d'une classe enfant 198
__9.2.3 Modèle Pistolet 200
__9.2.4 Modèle de fusil de chasse 205
9.3 Comprendre le modèle de bac à sable des sous-classes 207
__9.3.1 Création d'un bac à sable (classe parente) 208
__9.3.2 Création d'une classe enfant 211
__9.3.3 Pistolet de bac à sable 211
__9.3.4 Fusil à pompe Sandbox 213
9.4 Modèle d'objet de type 215
__9.4.1 Variantes 216 / 9.4.2 Tables de données 217 / 9.4.3 Ressources de données 218
9.5 Résumé 222
CHAPITRE 10 Optimisation par les modèles 223
10.1 Exigences techniques 224
10.2 Utilisation des indicateurs de modifications pour réduire les traitements inutiles 224
__10.2.1 Application du drapeau sale 225
10.3 L’impact de la localité des données sur l’efficacité du code 226
__10.3.1 Répartition chaud/froid 227
__10.3.2 Tableaux contigus 228
10.4 Mise en commun des objets : Gestion des ressources pour gagner du temps 229
__10.4.1 Mise en œuvre du regroupement d'objets 229
__10.4.2 Création d'un pool d'objets 231
10.5 Résumé 241
Recherche 244
Image détaillée

Dans le livre
Il est recommandé, comme bonne pratique, de n'instancier que des classes Blueprint dans le monde.
Cela facilite le débogage des classes et des références de liens.
Car l'éditeur intègre tous les outils visuels nécessaires au suivi de l'exécution.
Et lorsque les noms de classes changent ou que les répertoires sont déplacés, des liens dynamiques sont utilisés à la place des liens textuels afin d'éviter les plantages.
Pour que cette stratégie d'héritage fonctionne bien, il est utile de réfléchir au système d'un point de vue abstrait du gameplay.
Quelles classes influencent les mécanismes ? Exprimer ces classes en C++ est efficace et permet une conception hiérarchique.
À partir de là, nous héritons de la classe de plan à la fin de chaque branche.
--- p.12
Il est intéressant d'imaginer un peintre utilisant une photocopieuse.
L'artiste avait reçu pour instruction d'envoyer au moins deux exemplaires de chaque tableau qu'il créait ; il a donc astucieusement décidé d'utiliser une photocopieuse pour faire des copies de ses œuvres.
Pour gagner du temps lors du transfert de votre œuvre du chevalet au photocopieur, placez simplement votre toile directement sur le scanner.
Dessinez ensuite aussi vite que possible tout en appuyant simultanément sur le bouton de copie.
Il y a ensuite une course où l'artiste doit tracer des lignes plus vite que la tête de numérisation.
En cas de succès, le visuel et le texte seront identiques et aucun délai supplémentaire ne sera nécessaire.
Mais dans la plupart des cas, la tête de numérisation est en avance sur le peintre et ne dessine que jusqu'au point où elle le dépasse, laissant le reste comme une copie vierge.
C’est ce qu’on appelle le déchirement de trame (déchirement de trame p), et c’est ce problème que le modèle à double tampon tente de résoudre.
--- p.52
Il est facile de gérer les valeurs d'endurance.
Il vous suffit de définir une variable flottante pour suivre la valeur actuelle et une autre variable pour définir la valeur maximale dans l'éditeur.
Dans cette optique, la définition des spécificateurs de propriété dans le bloc UPROPERTY est l'élément le plus important.
La carte des dégâts peut également être gérée très simplement.
Ceci est dû au fait qu'Unreal Engine 5 possède un système d'interface de dégâts qui se propage à tous les AActors.
Pour attacher ce hook, vous devez gérer l'événement OnTakeAnyDamage comme indiqué dans l'extrait de code HealthComponent.h suivant :
Il vous suffit d'une fonction qui partage la même signature que .
--- p.76
Maintenant, si vous testez le système en appuyant sur lecture dans la fenêtre d'affichage, vous devriez pouvoir sélectionner le personnage vert et le déplacer près du personnage rouge.
Lorsque le personnage vert s'arrête, vous devez trouver la cible la plus proche, changer de direction et générer une chaîne de caractères « Shoot ».
Cela continuera jusqu'à ce que la cible ne soit plus valide, auquel cas cela se poursuivra indéfiniment car cela n'infligera aucun dégât à l'unité ciblée.
De plus, il n'existe actuellement aucun moyen de sortir l'IA de la tâche BTT_ShootTarget ; par conséquent, une fois la cible trouvée, elle ne peut plus déplacer le personnage.
Pour infliger des dégâts à une unité ennemie, vous devez utiliser le composant Santé que vous avez créé précédemment pour remplacer le nœud Print String de l'événement BP_EliteUnit Attack Target par une logique permettant de vérifier le réticule puis d'appliquer les dégâts.
--- p.98
La prochaine information utile à transmettre au composant est un signal émis à chaque fois qu'un dommage est infligé.
Plusieurs options sont possibles pour la transmission des données.
Par exemple, si vous développez un jeu de type Call of Duty, vous devrez fournir au joueur une interface utilisateur qui indique la direction d'où proviennent les dégâts.
L'exemple ci-dessous fournit des informations sur le changement qui vient de se produire, la nouvelle valeur de santé et la valeur de santé maximale.
Cela vous permet de mettre à jour les barres de santé de l'interface utilisateur et, dans certains cas, de générer des chiffres de dégâts dans le monde.
Cela facilite le débogage des classes et des références de liens.
Car l'éditeur intègre tous les outils visuels nécessaires au suivi de l'exécution.
Et lorsque les noms de classes changent ou que les répertoires sont déplacés, des liens dynamiques sont utilisés à la place des liens textuels afin d'éviter les plantages.
Pour que cette stratégie d'héritage fonctionne bien, il est utile de réfléchir au système d'un point de vue abstrait du gameplay.
Quelles classes influencent les mécanismes ? Exprimer ces classes en C++ est efficace et permet une conception hiérarchique.
À partir de là, nous héritons de la classe de plan à la fin de chaque branche.
--- p.12
Il est intéressant d'imaginer un peintre utilisant une photocopieuse.
L'artiste avait reçu pour instruction d'envoyer au moins deux exemplaires de chaque tableau qu'il créait ; il a donc astucieusement décidé d'utiliser une photocopieuse pour faire des copies de ses œuvres.
Pour gagner du temps lors du transfert de votre œuvre du chevalet au photocopieur, placez simplement votre toile directement sur le scanner.
Dessinez ensuite aussi vite que possible tout en appuyant simultanément sur le bouton de copie.
Il y a ensuite une course où l'artiste doit tracer des lignes plus vite que la tête de numérisation.
En cas de succès, le visuel et le texte seront identiques et aucun délai supplémentaire ne sera nécessaire.
Mais dans la plupart des cas, la tête de numérisation est en avance sur le peintre et ne dessine que jusqu'au point où elle le dépasse, laissant le reste comme une copie vierge.
C’est ce qu’on appelle le déchirement de trame (déchirement de trame p), et c’est ce problème que le modèle à double tampon tente de résoudre.
--- p.52
Il est facile de gérer les valeurs d'endurance.
Il vous suffit de définir une variable flottante pour suivre la valeur actuelle et une autre variable pour définir la valeur maximale dans l'éditeur.
Dans cette optique, la définition des spécificateurs de propriété dans le bloc UPROPERTY est l'élément le plus important.
La carte des dégâts peut également être gérée très simplement.
Ceci est dû au fait qu'Unreal Engine 5 possède un système d'interface de dégâts qui se propage à tous les AActors.
Pour attacher ce hook, vous devez gérer l'événement OnTakeAnyDamage comme indiqué dans l'extrait de code HealthComponent.h suivant :
Il vous suffit d'une fonction qui partage la même signature que .
--- p.76
Maintenant, si vous testez le système en appuyant sur lecture dans la fenêtre d'affichage, vous devriez pouvoir sélectionner le personnage vert et le déplacer près du personnage rouge.
Lorsque le personnage vert s'arrête, vous devez trouver la cible la plus proche, changer de direction et générer une chaîne de caractères « Shoot ».
Cela continuera jusqu'à ce que la cible ne soit plus valide, auquel cas cela se poursuivra indéfiniment car cela n'infligera aucun dégât à l'unité ciblée.
De plus, il n'existe actuellement aucun moyen de sortir l'IA de la tâche BTT_ShootTarget ; par conséquent, une fois la cible trouvée, elle ne peut plus déplacer le personnage.
Pour infliger des dégâts à une unité ennemie, vous devez utiliser le composant Santé que vous avez créé précédemment pour remplacer le nœud Print String de l'événement BP_EliteUnit Attack Target par une logique permettant de vérifier le réticule puis d'appliquer les dégâts.
--- p.98
La prochaine information utile à transmettre au composant est un signal émis à chaque fois qu'un dommage est infligé.
Plusieurs options sont possibles pour la transmission des données.
Par exemple, si vous développez un jeu de type Call of Duty, vous devrez fournir au joueur une interface utilisateur qui indique la direction d'où proviennent les dégâts.
L'exemple ci-dessous fournit des informations sur le changement qui vient de se produire, la nouvelle valeur de santé et la valeur de santé maximale.
Cela vous permet de mettre à jour les barres de santé de l'interface utilisateur et, dans certains cas, de générer des chiffres de dégâts dans le monde.
--- p.245
Avis de l'éditeur
- Comprendre l'essence et l'utilité des modèles de conception
- Comprendre les calques et leur fonctionnement dans Unreal Engine 5
- Comprendre la relation entre le code C++ d'Unreal Engine 5 et les Blueprints
- Découvrez les modèles de conception présents dans les fonctionnalités existantes d'Unreal Engine 5.
- Analyse de l'objectif des modèles de conception appliqués à Unreal Engine 5
- Appliquer de manière créative des modèles de conception au code existant pour résoudre les problèmes courants.
- Comprendre les calques et leur fonctionnement dans Unreal Engine 5
- Comprendre la relation entre le code C++ d'Unreal Engine 5 et les Blueprints
- Découvrez les modèles de conception présents dans les fonctionnalités existantes d'Unreal Engine 5.
- Analyse de l'objectif des modèles de conception appliqués à Unreal Engine 5
- Appliquer de manière créative des modèles de conception au code existant pour résoudre les problèmes courants.
SPÉCIFICATIONS DES PRODUITS
- Date d'émission : 13 novembre 2025
- Format : Guide de reliure de livres brochés
- Nombre de pages, poids, dimensions : 264 pages | 188 × 245 × 16 mm
- ISBN13 : 9791194587538
Vous aimerez peut-être aussi
카테고리
Langue coréenne
Langue coréenne