Application de la Saint-Valentin sur Libgdx

Chaque année, de nombreux articles sont consacrés à la Saint-Valentin. J'ai également décidé de m'impliquer dans ce sujet et de créer quelque chose d'original et d'insolite. L'idée était de créer une application Android simple avec des cœurs qui auraient leurs modèles physiques et interagiraient les uns avec les autres. J'ai ensuite ajouté du texte, des sons, des particules et quelques autres effets. L'application résultante fonctionnait et était assez originale! Dans cet article, je décrirai le processus de création, ainsi que les capacités et les pièges de la bibliothèque libgdx .


Coeurs de Saint Valentin .


Table des matières



Programmes et outils


Pour implémenter cette idée, j'ai utilisé les programmes et bibliothèques suivants:


  1. IntelliJ IDEA - un IDE pour les applications multiplateformes. Alternativement, vous pouvez utiliser Android Studio , Eclipse .
  2. libgdx - une bibliothèque Java multiplateforme (PC, Mac, Linux, Android) pour développer des jeux et d'autres applications graphiques. Cette bibliothèque est distribuée sous la licence Apache 2.0. Certains extraits de code ont été optimisés à l'aide de JNI (par exemple, Box2d).
  3. box2d-editor - un éditeur pour créer des modèles physiques utilisés dans le moteur physique box2d , qui est intégré à libgdx . Ici, il sera utilisé pour faire correspondre l'image du cœur avec son modèle physique.
  4. Générateur de polices bitmap Hiero - un programme pour convertir les polices vectorielles en raster (car dans libgdx seules les polices raster sont prises en charge).
  5. Éditeur de particules - un éditeur pour créer des systèmes de particules, développé par le créateur de libgdx . Il est utilisé pour les particules à effet "d'explosion" lors de la destruction du cœur.
  6. Paint.NET - un éditeur d'images, il a été utilisé pour éditer l'image du cœur et créer l'arrière-plan.

Tous ces programmes et composants sont distribués librement, et c'est un gros plus. J'ai choisi libgdx , parce que, premièrement, j'ai déjà une certaine expérience avec lui, et, deuxièmement, en utilisant libgdx vous n'avez pas besoin d'un émulateur Android lent, car il est multiplateforme et permet de tester des applications dans un environnement Java natif, puis de compiler les pour Android.


Bonjour tout le monde


Tout d'abord, je vais vous dire en quelques mots comment créer des projets libgdx. À l'aide de gdx-setup.jar , générez un modèle de projet (basé sur Gradle), qui spécifie les plateformes cibles. Actuellement, Desktop , Android , Ios , Html sont pris en charge. Pour être honnête, je n'ai pas essayé les deux derniers, car je n'ai pas d'appareil iOS, et il y a des problèmes avec le HTML que je n'ai pas encore résolus.


Projectsetup


Vous pouvez également sélectionner les extensions que vous utiliserez. Dans notre cas, il s'agit de la bibliothèque de physique Box2d.


Cependant, tout cela est décrit dans le wiki: Créer un projet libgdx .


Après la génération, trois dossiers sont créés:


  • noyau
  • bureau
  • android

Dans les deux derniers, DesktopLauncher et AndroidLauncher sont respectivement placés, qui ressemblent à ceci:


 public class DesktopLauncher { public static void main (String[] arg) { LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); config.width = 800; config.height = 480; new LwjglApplication(new ValentinesDayHeartsApp(), config); } } 

 public class AndroidLauncher extends AndroidApplication { @Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); initialize(new ValentinesDayHeartsApp(), config); } } 

Il n'y aura plus de code spécifiquement pour la plate-forme Android, ce qui est un grand avantage de la bibliothèque choisie. Il ne reste plus qu'à autoriser les vibrations et désactiver le mode veille (pour empêcher la réinitialisation de l'état de l'application) dans la configuration AndroidManifest.xml . Et définissez également l'orientation du paysage afin que le monde ne se retourne pas:


 <uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> 

et


 android:screenOrientation="landscape" 

Le code commun est stocké dans le dossier core . La classe principale appelée ValentinesDayHeartsApp implémente l'interface ApplicationListener (pour gérer les événements d'initialisation, le rendu, la finalisation et d'autres états) et l'interface InputProcessor (pour gérer les entrées utilisateur).


C'est tout, le squelette est prêt! Maintenant, notre application fonctionnera sur PC et Android.


Général


Le projet a une structure simple: dans la classe ValentinesDayHeatsApp , les méthodes create , render , dispose , touchDown sont remplacées. La méthode create initialise toutes les ressources (textures, polices, particules, sons) et crée le monde physique. Dans la méthode de rendu, le rendu de tous les objets du monde se produit:


 @Override public void render() { updatePhysics(); updateBackground(); updateSprites(); updateParticles(); refresh(); renderBackground(); renderHearts(); renderFonts(); renderParticles(); } 

Dans la méthode dispose , toutes les ressources sont libérées. Oui, oui, malgré le fait que Java dispose d'un ramasse-miettes automatique, les ressources non gérées (objets Box2d et quelques autres) doivent encore être libérées manuellement. La méthode touchDown est déclenchée par un toucher ou un clic de souris. Cela fonctionne comme ceci: si un point de contact croise un cœur, le cœur est supprimé. Sinon, un nouveau cœur est créé dans le point de contact. L'objet Heart a les propriétés suivantes:


  • Body - un modèle physique.
  • Sprite - un modèle graphique (sprite).
  • String - un texte affiché sur le cœur.
  • Font - une police.
  • ParticleEffect - particules créées lors de la destruction du cœur.
  • BreakSound - un son de destruction du cœur.

Ensuite, je décrirai les composants de l'application plus en détail.


Textures


Tout d'abord, j'avais besoin de trouver ou de dessiner le cœur. Heureusement, je l'ai facilement googlé puis édité un peu: j'ai ajouté une lueur et un fond transparent. Pour charger des textures dans libgdx , j'ai utilisé la classe Texture . Comme la même texture peut être utilisée plusieurs fois, des objets Sprite supplémentaires ont été utilisés. Ils ont été dessinés en utilisant la méthode de render . La position du sprite et l'angle sont les paramètres de rendu et le modèle physique du cœur. Pour changer, j'ai décidé de dessiner les coeurs dans différentes nuances. J'ai utilisé la palette HSL, qui permet de manipuler la teinte, la saturation et l'éclaircissement, pas les composants de couleur comme RGB. La formule de conversion RVB -> HSL et HSL -> RVB peut être facilement trouvée, et j'ai utilisé les méthodes de l'article Manipulation des couleurs dans .NET sur Java. Toutes les conversions sont dans les prepareHeartsTextures , prepareHslData et generateHeartTexture . Voici l'exemple:


 Pixmap pixmap = new Pixmap(fileHandle); float[][][] result = new float[pixmap.getWidth()][pixmap.getHeight()][4]; for (int i = 0; i < pixmap.getWidth(); i++) for (int j = 0; j < pixmap.getHeight(); j++) { int color = pixmap.getPixel(i, j); float r = (float)((color >> 24) & 0xFF) / 255.0f; float g = (float)((color >> 16) & 0xFF) / 255.0f; float b = (float)((color >> 8) & 0xFF) / 255.0f; float a = (float)(color & 0xFF) / 255.0f; result[i][j] = ColorUtils.RgbToHsl(r, g, b, a); } return result; 

Malheureusement, l'application Android démarre avec un certain retard en raison de la génération de textures avec différentes nuances.


Les polices


Étant donné que libgdx ne peut fonctionner qu'avec des polices raster, j'ai utilisé Hiero Bitmap Font Generator (version 5), qui crée des images de tous les caractères au format PNG, et le fichier FNT, qui contient des informations sur les coordonnées de chaque caractère de l'image. Voici la capture d'écran de ce programme:


Outil de police bitmap


Une fois les fichiers nécessaires générés, la police peut être utilisée dans l'application libgdx comme suit:


 font = new BitmapFont( Gdx.files.internal("data/Jura-Medium.fnt"), Gdx.files.internal("data/Jura-Medium.png"), false); font.setColor(Color.WHITE); 

Et puis le rendre comme ça:


 font.draw(spriteBatch, heart.String, screenPosition.x, screenPosition.y); 

Lors du rendu, j'ai rencontré quelques difficultés: par exemple, la police ne peut pas être rendue sous un angle, comme cela peut être fait avec un sprite. Pour résoudre ce problème, vous devez modifier la matrice de projection de SpriteBatch , puis rendre la police comme suit:


 Matrix4 projection = spriteBatch.getProjectionMatrix(); projection.setToOrtho2D(0, 0, WorldWidth, WorldHeight); projection.translate(tmpVector1.x, tmpVector1.y, 0); projection.rotate(0, 0, 1, body.getAngle() / (float)Math.PI * 180); projection.translate(-tmpVector1.x, -tmpVector1.y, 0); Vector2 stringSize = heart.getStringSize(); tmpVector1.add(heart.Size.x / PhysWorldWidth * WorldWidth * CenterDisplacement.x - stringSize.x * 0.5f, heart.Size.y / PhysWorldHeight * WorldHeight * CenterDisplacement.y + stringSize.y); spriteBatch.begin(); BitmapFont.BitmapFontData fontData = font.getData(); fontData.setScale(heart.Size.x * FontSizeHeartSizeCoef.x, heart.Size.y * FontSizeHeartSizeCoef.y); font.draw(spriteBatch, heart.String, tmpVector1.x, tmpVector1.y); fontData.setScale(1, 1); spriteBatch.end(); 

La physique


En tant que moteur physique, box2d a été utilisé.


Pour faire correspondre l'image du cœur avec son modèle physique, j'ai utilisé box2d-editor :


Éditeur de corps physique .


En utilisant ce programme, j'ai créé un polygone du cœur, qui a été automatiquement divisé en polygones convexes. Le modèle physique est un ensemble de coordonnées de ces polygones au format JSON.


De plus, ce fichier est utilisé dans notre application (le chargement se produit dans la méthode addHeart ). libgdx ne peut charger que des fichiers au format binaire. Heureusement, la classe BodyEditorLoader.java a été trouvée, qui peut également être utilisée pour charger le modèle à partir de JSON (c'est-à-dire la représentation textuelle).


N'oubliez pas de régler la densité, la friction et l'élasticité du corps:


 FixtureDef fdef = new FixtureDef(); fdef.density = 0.75f; fdef.friction = 1.0f; fdef.restitution = 0.4f; bodyLoader.attachFixture(body, "Heart", fdef, newWidth); body.resetMassData(); 

Maintenant, nos cœurs ont une coquille physique!


Afin que les cœurs ne volent pas hors de l'écran, nous pouvons ajouter quatre rectangles statiques sur les côtés de notre petit monde. Sur les appareils mobiles, il est conseillé de régler la gravité en fonction de l'orientation de l'appareil:


 if (Gdx.app.getType() == ApplicationType.Android) { gravity.x = -Gdx.input.getPitch() / 90.0f; gravity.y = Gdx.input.getRoll() / 90.0f; gravity.mul(gravityCoef); world.setGravity(gravity); } 

Système de particules


Dans libgdx , le système de particules est spécifié à l'aide de fichiers spéciaux qui peuvent être générés dans l'éditeur:


Éditeur de particules .


Comme vous pouvez le voir, cet éditeur a beaucoup de paramètres: vous pouvez charger différentes textures, changer la durée de vie, la forme de propagation, la transparence et d'autres paramètres. J'ai créé des particules en forme de cœur, qui apparaîtront lorsque vous tapoterez l'écran et détruirez un grand cœur physique. Dans l'application, le travail avec les particules se produit comme suit:


Initialisation


 ParticleEffect effect = new ParticleEffect(); effect.load(Gdx.files.internal("data/destroy.p"), Gdx.files.internal("data")); 

Début du cycle de vie


Il est important de ne pas oublier le start sans lequel les particules ne seront pas affichées:


 effect.setPosition(.., ..); effect.start(); 

Les sons


Les sons sont chargés comme suit:


 sound = Gdx.audio.newSound(Gdx.files.internal("path/to/file")); 

Et puis sont joués comme ceci:


 sound.play(1); 

Quoi de plus simple? Cependant, il existe également des écueils. Pour une raison quelconque, les fichiers ne peuvent être chargés qu'au format OGG et au débit binaire de 96 kbit / s .


Conclusion


J'espère que les techniques décrites dans cet article seront utiles à beaucoup d'entre vous pour développer des jeux utilisant libgdx . Vous pouvez utiliser le code source et les ressources. Envoyez des applications pour la Saint-Valentin à vos amoureux :)


Il est à noter que le texte affiché sur les coeurs peut être modifié dans le fichier data/words.txt . Cela fonctionne même sans recompilation.


Code source et exécutables


Source: https://habr.com/ru/post/fr440298/


All Articles