Please enable / Bitte aktiviere JavaScript!
Veuillez activer / Por favor activa el Javascript![ ? ]
UMV-RP | Forum

 [Tutoriel] Interface d'un panel de connexion

:

0 Membres et 1 Invité sur ce sujet

Hors ligne William

  • *
  • 1171
    • Voir le profil
  • Nom InGame: William_Galvez
[Tutoriel] Interface d'un panel de connexion
« le: 06 11 2017, 19:59:46 »
C'est un tutoriel qui est de base dans la section française sur le forum officiel Multi Theft Auto

Aujourd'hui on va voir comment réaliser une interface via la méthode GUI et DX, si vous voulez que j'vous apprenne à faire la même chose en CEF dites-le, pour ceux qui ne savent pas, CEF c'est l'abréviation de Chromium Embedded Framework, en gros, c'est l'intégration d'un navigateur WEB en jeu, sur MTA, on utilise Chromium qui nous est développé par Google.

Bien, on va partir du fait que vous savez au moins créer un dossier pour ajouter une nouvelle ressource, donc créer un meta.xml et au moins un fichier client, ce qui nous donnerait une arborescence avec notre ressource "tutorial" comme suit:



I) Mise en place de l'idée

Pour faire simple et utile à tout le monde, dans ce tutoriel on va voir comment créer un panel de connexion de ce style (bien sûr, adapté en fonction des méthodes GUI, DX ou CEF), je l'avais développé pour un serveur qui n'a malheureusement pas eu le temps de voir le jour, bref.


Si vous n'avez pas d'idée et vous ne savez pas à quoi ressemblera votre panel de connexion, je vous invite à vous rendre sur Google Image et tapez "Login Panel" ou encore "GTA SA Login Panel" dans la barre de recherche, vous tomberez sur un bon nombre de panels qui vous permettront d'imaginer le vôtre, ne copiez pas bêtement les panels, c'est sans intérêt.

Dans mon cas, j'ai une petite idée de ce que je vais réaliser, lorsque vous travaillez sur une interface, veillez à toujours faire un plan sur un logiciel de dessin pour éviter de vous perdre et pour ne pas avoir à recommencer tout le temps, voici mon plan réalisé sur Paint.NET à partir d'une simple capture d'écran du jeu :


J'ai utilisé Icons8 pour les icônes (le nom d'utilisateur, le mot de passe et le W en bas à gauche)

Après avoir mis sur papier notre idée, le prochain objectif est clair : le produire en jeu le plus fidèlement possible.



Pensez à extraire tout les éléments séparés, dans mon cas, je dois extraire la petite icône pour le nom d'utilisateur, l'icône pour le mot de passe, celui en bas à droite (le W entouré) puis le fond du bouton "Connexion"

Néanmoins, si vous utilisez comme moi une même forme pour deux éléments, n'extrayez pas les deux éléments, extrayez-en un seul puis modifiez-le en jeu directement.

II) Méthode N° 1: GUI

Il s'agit de la méthode la plus simple pour commencer, elle est, à mon sens, limitée mais elle est optimisée pour l'utilisateur (moins de ralentissements)


Au niveau de l'extraction, je n'extrais qu'un rectangle noir opaque et l'autre un peu transparent de 1x1 pixel puisque nous pouvons par la suite redimensionner l'image comme bon nous semble sans affecter la qualité de celle-ci (c'est qu'un rectangle noir après tout)


Voici donc la liste de mes images extraites :


Nous sommes prêt à passer sur notre éditeur de texte !


Rendons-nous dans le fichier client de notre panel (ici : c _gui.lua) puis ajoutons un événement qui se déclenchera seulement lorsque la ressource se démarre pour l'utilisateur, après une petite recherche sur le Wiki, nous pouvons trouver l’événement qui va nous aider: 

onClientResourceStart


Pour vérifier qu'il est compatible avec notre fichier, en haut à droite nous pouvons voir "Clientside event" qui nous rappelle qu'on peut utiliser cet événement seulement côté Client.

Intégrons-le dans notre fichier, il exécutera la fonction "resourceStart" pour qu'on ne soit pas perdu, ce qui donne :


J'ai mis "getResourceRootElement(getThisResource())" en deuxième argument parce que ça évite qu'à chaque redémarrage de ressource, celle-ci se redémarre, a contrario "getRootElement()" permettra de lancer notre ressource "tutorial" à chaque fois qu'une autre ressource est démarrée.

Ensuite, importons nos images précédemment extraites dans notre ressource sans oublier de compléter le "meta.xml", ce qui nous donne : 


Revenons à notre fichier "c_gui.lua" et créons enfin cette fonction pour afficher le panel ! Nous l'appellerons "panelConnexion".

Affichons le fond du panel en utilisant "rectangle_noir_transparent.png" à la dimension de notre plan soit 520x415 via la fonction suivante :

element guiCreateStaticImage ( float x, float y, float width, float height, string path, bool relative, [element parent = nil] )
Nous pouvons voir que cette fonction parle de "relative" en guise d'argument N° 6, mais qu'est-ce que c'est ?


En fait, il nous faut utiliser le système de positionnement relatif au maximum, parce que si vous travaillez en absolue et que vous développez un panel qui mesure 1920x1080 et que vous dites à votre pote "Regarde j'ai fais un magnifique panel !" et que lui possède un écran 800x600, il ne va rien voir puisque c'est trop grand pour son écran.

C'est pour ça qu'on a inventé le relatif, parce que si vous développez un panel en entrant en dimension 1 en X et 1 en Y, ça prendra tout votre écran peu importe si vous avez l'écran de votre pote (800x600) ou un écran 4K UHD (3840x2160), vous verrez le panel en plein écran.

Enfin bref, travaillons en relatif, pour adapter nos mesures, il suffit de prendre la dimension de l'élément du panel et de le diviser par la dimension sur lequel le plan a été désigné (je suis en 1920x1080 en l’occurrence).

Dans notre cas, le fond du panel mesure 520x415 ce qui donne en X: 520/1920 = 0.271 et en Y = 415/1080 = 0.384.

Le centre d'un élément est définie par la largeur de la zone divisée par 2 moins la taille de l'élément divisé par 2.

Dans notre cas, si on veut centrer notre panel horizontalement il faut faire (1920/2-520/2) ce qui nous donnerait 700 pixels pour l'axe X.

Pour simplifier tout ça, faisons une fonction indépendante de notre code pour centrer un élément sur notre écran, voici comment je l'ai rédigé:

function centrerElement(element)
  local ecranL, ecranH = guiGetScreenSize()
  local largeur, hauteur = guiGetSize(element, false)
  guiSetPosition(element, ecranL/2-largeur/2, ecranH/2-hauteur/2, false)
end


Nous pourrons maintenant centrer n'importe quel élément en faisans "centrerElement(element)" et ainsi ne plus se soucier de la position.

Revenons au fichier client, et écrivons cette fonction une bonne fois pour toutes.

Voici ce que ma fonction panelConnexion donne: 

function panelConnexion()
  local panel = guiCreateStaticImage(0, 0, 0.271, 0.384, "images/rectangle_noir_transparent.png", true)
  centrerElement(panel) -- Centrer le panel de connexion
end


Mon fichier client ressemble à ça :


Lançons tout ça en jeu!

Munissez-vous d'un compte ACL, connectez-vous, affichez le debugscript au niveau 3 (/debugscript 3) au cas où il y aurait une erreur, faites un '/refresh' de votre serveur, démarrez la ressource puis appréciez! Un magnifique rectangle transparent au centre de l'écran! C'est le début de votre panel.


Maintenant que tout ça est expliqué, avançons plus rapidement, je vous propose d'ajouter la barre qui nous servira de titre pour notre panel.


Le plus dur a été fait, il faut désormais disposer les éléments dans le panel, je vous ai expliqué le relatif au début de ce chapitre, mais figurez-vous qu'on peut aussi utiliser le relatif par rapport à un élément et pas seulement par rapport à l'écran!

Ce qui veut dire que si on veut placer un élément tout à gauche de notre panel à sa bordure, on écrira en position "0" en abscisse (axe X), allons-y, prenons la fonction guiCreateStaticImage est remplissons la pour faire en sorte de respecter le plan, ça nous donne:

local barre_titre_fond = guiCreateStaticImage(0, 0, 1, 0.145, "images/rectangle_noir.png", true, panel)
J'ai mis 0 car je veux que l'image s'affiche en haut à gauche de l'écran, la taille en largeur est de 1 parce qu'il faut que la barre de titre fasse tout le panel en largeur et 0.145 car sur mon plan ma barre de titre fait 60 pixels, et mon panel 415 pixels, donc il faut faire 60/415 pour avoir la taille relative.

Notez le dernier argument qui est "panel" ce qui signifie que cette barre de titre est attachée à l'élément panel, les positions sont donc relative à celui-ci.

Attaquons le texte! "Label" est aussi le nom pour designer une zone de texte, nous allons utiliser "guiCreateLabel"

element guiCreateLabel ( float x, float y, float width, float height, string text, bool relative, [element parent = nil] )
Pour centrer le texte, nous allons simplement commencer par afficher le texte en haut à gauche du panel, a la taille de la barre de titre, faisons donc:

local barre_titre_texte = guiCreateLabel(0, 0, 1, 1, "Panel de connexion", true, barre_titre_fond)
Rien de compliqué, puis mettons-le en forme via les fonctions "guiLabelSetHorizontalAlign" et "guiLabelSetVerticalAlign" ce qui donne:

local barre_titre_texte = guiCreateLabel(0, 0, 1, 1, "Panel de connexion", true, barre_titre_fond)
guiLabelSetHorizontalAlign(barre_titre_texte, "center")
guiLabelSetVerticalAlign(barre_titre_texte, "center")

Pour changer la police, il y a la fonction "guiSetFont", MTA possède des polices de base qui sont disponible ici: Standard GUI Font Names

Dans notre cas, nous utilisons une police personnalisée qui est "Pricedown", nous devons donc la créer, procurez vous la police sur internet ou extrayez la de votre ordinateur si vous l'avez puis placez la dans votre ressource.

Ajoutez ensuite la police dans le meta.xml, j'en ai profité pour l'organisé comme suit:

<meta>
  <info author="Wumbaloo Willy" type="script" description="Tutorial."/>

  <script src="c_gui.lua" type="client" />

  <!-- Images -->
  <file src="images/connexion_fond.png" />
  <file src="images/icon_bas_gauche.png" />
  <file src="images/mot_de_passe.png" />
  <file src="images/nom_utilisateur.png" />
  <file src="images/rectangle_noir.png" />
  <file src="images/rectangle_noir_transparent.png" />

  <!-- Polices -->
  <file src="polices/pricedown.ttf" />
 
</meta>

Revenons côté client et importons la police personnalisée.

Pour ça, on utilise la fonction "guiCreateFont" qui prend deux arguments: le chemin d'accès vers la police et la taille de la police.

On créé donc la police avec "guiCreateFont" puis on l'utilise avec "guiSetFont", rien de compliqué.

Tout ça nous donne notre fonction panelConnexion qui ressemble à ça:

function panelConnexion()
  local panel = guiCreateStaticImage(0, 0, 0.271, 0.384, "images/rectangle_noir_transparent.png", true)
  centrerElement(panel) -- Centrer le panel de connexion

  -- Barre de titre (fond)
  local barre_titre_fond = guiCreateStaticImage(0, 0, 1, 0.145, "images/rectangle_noir.png", true, panel)
  -- Barre de titre (texte)
  local barre_titre_texte = guiCreateLabel(0, 0, 1, 1, "Panel de connexion", true, barre_titre_fond)
  guiLabelSetHorizontalAlign(barre_titre_texte, "center")
  guiLabelSetVerticalAlign(barre_titre_texte, "center")
  local pricedown_32px = guiCreateFont("polices/pricedown.ttf", 32) -- Création de la police personnalisée
  guiSetFont(barre_titre_texte, pricedown_32px)
end


En jeu voici à quoi notre panel ressemble:


C'est exactement ce qu'on voulait! Ensuite, mettons en forme notre panel à l'aide des fonctions "guiCreateLabel", "guiCreateStaticImage" et aussi "guiCreateEdit" et voici ce que ça nous donne !

Je compte sur vous, on a vu tout ce qu'il fallait voir pour continuer !


Voici ma fonction panelConnexion :

function panelConnexion()
  local panel = guiCreateStaticImage(0, 0, 0.271, 0.384, "images/rectangle_noir_transparent.png", true) -- 520x415
  centrerElement(panel) -- Centrer le panel de connexion

  -- Barre de titre (fond)
  local barre_titre_fond = guiCreateStaticImage(0, 0, 1, 0.145, "images/rectangle_noir.png", true, panel)
  -- Barre de titre (texte)
  local barre_titre_texte = guiCreateLabel(0, 0, 1, 1, "Panel de connexion", true, barre_titre_fond)
  guiLabelSetHorizontalAlign(barre_titre_texte, "center")
  guiLabelSetVerticalAlign(barre_titre_texte, "center")
  local pricedown_32px = guiCreateFont("polices/pricedown.ttf", 32) -- Création de la police personnalisée
  guiSetFont(barre_titre_texte, pricedown_32px)

  -- Texte d'information
  local information_texte = guiCreateLabel(0.0385, 0.2, 1-0.385, 0.0482, "Entrez vos identifiants :", true, panel)
  guiLabelSetHorizontalAlign(information_texte, "left")
  guiLabelSetVerticalAlign(information_texte, "center")
  local verdana_16px = guiCreateFont("polices/verdana.ttf", 16) -- Création de la police personnalisée
  guiSetFont(information_texte, verdana_16px)

  -- Nom d'utilisateur
  local icon_utilisateur = guiCreateStaticImage(0.077, 0.313, 0.088, 0.111, "images/nom_utilisateur.png", true, panel)
  utilisateur_texte = guiCreateEdit(0.231, 0.325, 0.64, 0.1012, "Nom d'utilisateur", true, panel)

  -- Mot de passe
  local icon_mot_de_passe = guiCreateStaticImage(0.077, 0.525, 0.088, 0.111, "images/mot_de_passe.png", true, panel)
  mot_de_passe_texte = guiCreateEdit(0.231, 0.5301, 0.64, 0.1012, "1234", true, panel)

  -- Connexion
  bouton_connexion = guiCreateStaticImage(0.477, 0.783, 0.3846, 0.12, "images/connexion_fond.png", true, panel)
  bouton_texte = guiCreateLabel(0, 0, 1, 1, "Connexion", true, bouton_connexion)
  guiLabelSetHorizontalAlign(bouton_texte, "center")
  guiLabelSetVerticalAlign(bouton_texte, "center")
  local verdana_14px = guiCreateFont("polices/verdana.ttf", 14) -- Création de la police personnalisée
  guiSetFont(bouton_texte, verdana_14px)

  -- Icône en bas à gauche
  local icon_bas_gauche = guiCreateStaticImage(0.029, 0.723, 0.1731, 0.217, "images/icon_bas_gauche.png", true, panel)
end

J'ai volontairement utilisé plusieurs tailles de polices mais vous pouvez très bien utiliser celles de MTA de base, de même, j'ai mis quelques variables en global et d'autres en local parce que je pense les utiliser dans d'autres fonctions par la suite.

Oh, aussi, n'oubliez pas d'utiliser 

guiEditSetMasked
pour rendre les champs de mot de passe masqué, avec de petites étoiles (*)

Pour finir proprement, ajoutons un événement lorsque nous cliquons sur le bouton "Connexion" ! Il nous suffit d'utiliser l'événement "onClientGUIClick" qui sera relié à une nouvelle fonction qu'on va appeler "seConnecter", du coup, on ajoute l'événement après avoir créé notre bouton de connexion comme ça:

addEventHandler("onClientGUIClick", bouton_connexion, seConnecter)
Puis on fait une petite fonction "seConnecter" qui affiche un message dans le chat.

function seConnecter()
  outputChatBox("Connexion en cours...")
end

Vous pouvez essayer en jeu.

Voila nous avons notre panel entièrement en GUI ! Nous avons réalisé une interface de A à Z et avons même débordé un peu en proposant d'interagir avec notre magnifique bouton de connexion !


En bref, si avoir le panel peut vous aider (ou si vous avez simplement la flemme de le refaire) je vous le met à disposition ici: Télécharger via Mega.NZ

Si ça vous plaît, faites-le moi savoir et je continuerai sur le chapitre avec les DX et pour finir en CEF, on verra même quelques fonctions bonus pour changer la couleur d'un élément quand on passe dessus ou encore la transparence de celui-ci.

C'est mon premier tutoriel, dites-moi ce que je dois changer!

J'espère que je me suis fais comprendre et je reste à votre disposition en dessous! Merci d'avoir lu!


Wumbaloo Willy.

Hors ligne Meteor

  • *
  • 686
    • Voir le profil
  • Nom InGame: Jeff Pion
Re : [Tutoriel] Interface d'un panel de connexion
« Réponse #1 le: 06 11 2017, 23:03:33 »
Excellent, impatient de voir les prochains tuto  :)

Hors ligne William

  • *
  • 1171
    • Voir le profil
  • Nom InGame: William_Galvez
Re : Re : [Tutoriel] Interface d'un panel de connexion
« Réponse #2 le: 07 11 2017, 18:52:39 »
Excellent, impatient de voir les prochains tuto  :)

Merci du retour! Je ferai prochainement la même chose mais en DX cette fois

En ligne DJ Defalt

  • Il faut toujours rechercher l'extra dans l'ordinaire...
  • *
  • 84
  • Rolling On Floor Laughing
    • Voir le profil
  • Nom InGame: /!\James Wayat/!\
Re : [Tutoriel] Interface d'un panel de connexion
« Réponse #3 le: 12 11 2017, 10:50:54 »
C'est génial, je veux voir tes autres tutos ;)
Defalt "Rat Boy"

Hors ligne William

  • *
  • 1171
    • Voir le profil
  • Nom InGame: William_Galvez
Re : [Tutoriel] Interface d'un panel de connexion
« Réponse #4 le: 12 11 2017, 11:53:23 »
C'est génial, je veux voir tes autres tutos ;)

Cool, content que ça te plaise !

Hors ligne Othello

  • *
  • 658
    • Voir le profil
  • Nom InGame: Foka_Vodoleiev
Re : [Tutoriel] Interface d'un panel de connexion
« Réponse #5 le: 13 11 2017, 00:50:25 »
Vraiment propre, beau boulot.
J'ai hate de voir d'en voir d'autres !