1. Introduction

Il y a quelques mois, j'avais commencé à fréquemment jouer à GeoGuessr. Il s'agit d'un jeu testant nos compétences en géographie qui se joue sur n'importe quel navigateur. Lorsqu'une partie commence, le joueur apparaît en Street View, service de navigation virtuelle de Google, dans un endroit sélectionné au hasard dans le monde. Son but est ensuite de deviner le plus précisément possible où il se trouve. Étant un jeu que j'apprécie, il m'a inspiré pour ce projet et c'est pour cela que j'ai décidé d'appeler mon jeu CountryFindr.

1.1 Objectif

L'objectif de ce projet sera donc de créer un site sur lequel on pourrait jouer à mon jeu. Le fonctionnement de celui-ci sera le suivant, chaque utilisateur devra d'abord s'enregister avant de pouvoir accéder au reste du site. Une fois cela fait, il pourra soit commencer une nouvelle partie soit observer le classement des meilleurs scores. Concernant le fonctionnement du jeu, une image 360° sera sélectionnée au hasard parmi toutes les images stockées dans la base de données puis sera affichée à l'écran. Le joueur devra deviner dans quel pays cette image fut prise à l'aide d'un menu déroulant. Si sa réponse est correcte, son score augmentera d'un point et une nouvelle image sera affichée mais si sa réponse est incorrecte, la jeu s'arrêtera. Pour la réalisation de ce projet, je vais devoir élargir mes compétences et apprendre du HTML, du CSS, du PHP ainsi que du SQL.

2. Matériel et méthodes

2.1 Matériel

  • Un ordinateur avec une connexion internet
  • Un serveur afin d'exécuter du code PHP
  • Une base de données MySQL

2.2 Méthode

2.2.1 Base de données MySQL

Une base de données permet de stocker des informations en rapport avec une activité et doit être organisée de manière à être facilement gérée et mise à jour. Dans notre cas, elle nous servira premièrement à stocker le nom de l'utilisateur, son mot de passe, son meilleur score et son ID. J'ai donc une table contenant ces quatre valeurs qui sera remplie à chaque fois qu'un utilisateur s'enregistre sur le site.

table_users.png, mai 2022
Figure 1 - Première table contenant les données de l'utilisateur


Il est important d'indiquer que la première case id est une clé primaire, cela signifie qu'à chaque fois qu' un utilisateur s'enregistre, cette valeur sera différente. Il n'y a alors même pas besoin de cocher la case auto-incrémentation puisque la base de données le fait automatiquement.

J'ai ensuite une deuxième table que j'ai appelée images qui aura pour fonction de stocker toutes les images qui seront utilisées pour le jeu. Cette table possède uniquement deux colonnes, la première contiendra le lien qui permettra d'afficher chaque image et la deuxième contiendra le nom du pays auquel cette image correspond.

table_images.png, mai 2022
Figure 2 - Deuxième table contenant les données correspondantes à chaque image


Ici pas besoin de clé primaire puisque chaque image possèdera des données différentes qui seront manuellement attribuées par moi-même. Par ailleurs, j'ai réglé la valeur maximale de charactère à 200 puisque chaque lien permettant d'afficher l'image est d'une longueur assez conséquente.

Heureusement, la gestion des bases de données et les requêtes SQL sont facilitées grâce à phpMyAdmin puisque celui-ci s'occupe de traduire les interactions que nous avons avec l'interface graphique en language SQL.

2.2.2 Formulaire

Lorsque l'utilisateur se rend sur le site, la première page qui apparaitra face à lui sera un formulaire de connexion. Si l'utilisateur ne possède pas encore un compte, il pourra cliquer sur Sign up, ce qui le redirigera sur une autre page lui permettant de s'enregistrer. L'utilisateur doit alors rentrer son username ainsi que son mot de passe. Si il essaie de s'enregistrer sans avoir indiquer de username , de mot de passe ou que la longueur de l'un des deux est trop grande , le site le gardera sur la même page et lui indiquera Invalid information. Par contre si l'utilisateur s'enregistre en ayant rempli correctement les deux cases, son compte sera créer puis il sera redirigé sur la page de connexion et pourra alors se connecter.

<?php
        include("../../etc/mysql.inc.php");

        $db = mysqli_connect($MYSQL_SERVER,$MYSQL_USER,$MYSQL_PASS,"paqc_yannickdegoumois");

        if($_SERVER['REQUEST_METHOD'] == "POST")
        {
                $username = $_POST['username'];
                $password = $_POST['password'];

                if(!empty($username) && !empty($password))
                {
                        $query = "insert into users (username,password) values ('$username','$password')";
                        mysqli_query($db, $query);
                        header("Location: index.php");
                        die;
                }else
                {
                        print "Invalid information";
                }
        }
        mysqli_close($db);
?>

Il faut tout d'abord inclure le fichier PHP nommé mysql.inc.php puisque celui-ci contient les informations permettant la connexion à la base de données. Je vérifie ensuite à l'aide d'une condition que lorsque l'utilisateur clique sur le bouton pour s'enregistrer, les cases username et password doivent être remplies. Si cela est fait, une requête SQL sera envoyé indiquant les nouvelles valeurs à remplir dans la base de données, le compte de l'utilisateur sera créer et il sera redirigé sur la page de connexion comme prévu.

<?php
        include("../../etc/mysql.inc.php");

        $db = mysqli_connect($MYSQL_SERVER,$MYSQL_USER,$MYSQL_PASS,"paqc_yannickdegoumois");

        if($_SERVER['REQUEST_METHOD'] == "POST")
        {
                $username = $_POST['username'];
                $password = $_POST['password'];

                if(!empty($username) && !empty($password))
                {
                        $query = "select * from users where username = '$username' limit 1";
                        $result = mysqli_query($db, $query);
                        if($result)
                        {
                                if ($result && mysqli_num_rows($result) > 0)
                                {
                                        $user_data = mysqli_fetch_assoc($result);
                                        if($user_data['password'] === $password)
                                        {
                                                header("Location: home_page.php");
                                                die;
                                        }
                                }
                        }
                        print "Wrong username or password!";
                }else
                {
                        print "Invalid information!";
                }
        }
        mysqli_close($db);

?>

Pour le formulaire de connexion, il s'agit presque du même code que celui du formulaire d'inscription. Il suffit juste de vérifier en plus, à l'aide de quelques requêtes SQL, si le username et le password correspondent à ceux stockés dans la base de données. Je vérifie aussi que si le nom d'utilisateur indiqué existe mais que le mot de passe est incorrect, ou l'inverse, l'utilisateur reçoit comme message Wrong username or password. Une fois toutes les conditions sont remplies, il sera redirigé vers la page d'acccueil du site.

2.2.3 Classement des meilleurs scores

Concernant le classement des meilleurs score, il faut créer un tableau dans lequel les valeurs seront prises depuis la base de données. La colonne de gauche contiendra le nom des utilisateurs et la colonne de droite le meilleur score de ces derniers.

2.2.4 CSS

Afin de rendre le site un peu plus agréable à regarder, il nous faut ajouter des feuilles de style CSS. J'ai alors voulu faire en sorte qu'une image soit affichée en fond et que les objets avec lesquels nous interagissons soient en premier plan.

                <style type="text/css">
                .container{
                        position: relative;
                }
                .text{
                        height: 25px;
                        border-radius: 5px;
                        padding: 4px;
                        border: solid thin #aaa;
                        position: absolute;
                }
                .box{
                        background-color: white;
                        margin: auto;
                        width: 300px;
                        padding: 20px;
                        position: absolute;
                        top: 0;
                        left: 0;
                }
                </style>

Je me suis renseigné sur comment faire cela et j'ai trouvé qu'il suffit d'attribué la valeur relative au paramètre position afin que l'objet soit au deuxième plan et la valeur absolute pour qu'il soit au premier plan.

Concernant ma page d'accueil, elle sera constituée de seulement deux boutons, l'un commençant une nouvelle partie et l'autre permettant d'accéder au classement des meilleurs scores. Pour rajouter un minimum de diversité je souhaiterais que chaque bouton ait une couleur différente, l'un vert et l'autre bleu.

                <style>
                        .container {
                          position: relative;
                        }

                        .box {
                          position: absolute;
                          margin: auto;
                          background-color: white;
                          top: 0;
                          left: 0;
                          color: white;
                          padding: 50px;
                        }
                        .button{
                          border: none;
                          color: white;
                          padding: 15px 32px;
                          text-align: center;
                          text-decoration: none;
                          display: inline-block;
                          font-size: 16px;
                          margin: 4px 6px;
                          cursor: pointer;
                        }
                        .button1{
                          background-color: #4CAF50;
                        }
                        .button2{
                          background-color: #008CBA;
                        }
                </style>

Pour cela, il suffit tout d'abord créer une classe que j'ai nommée button qui regroupe toutes les caractéristiques que les deux boutons auront en commun. Puis j'ajoute deux autres classes, button1 et button2, qui ont pour seul variable la couleur du bouton. Celle-ci est indiquée en code HEX puisqu'elle ne fait pas partie des couleurs de base. Ainsi lorsque je souhaite avoir un bouton de couleur vert, il suffit d'indiquer que l'objet appartient à la classe button et button1.

Quant à l'affichage du classement des meilleurs scores, je voudrais à nouveau un peu de diversité et donc que la couleur des lignes du tableau soient alternées.

        tr:nth-child(even) {
          background-color: #f2f2f2;
        }

        tr:nth-child(odd) {
          background-color: #ffffff;
        }

Il suffit cette fois-ci d'indiquer la couleur de chaque ligne paire et l'autre couleur de chaque ligne impaire.

2.2.5 Fonctionnement du jeu

Pour commencer, il faut réussir à afficher une image 360°et j'ai alors trouvé un tutoriel expliquant comment faire cela. Il faut utiliser la balise iframe dont la fonction est d'intégrer un autre document à l'intérieur du document PHP existant, puis il faut mettre l' URL de l'image. Cependant, comme il s'agit d'une image 360° il faut d'abord uploader l'image sur un site internet permettant de visualiser des images 360° et ensuite utiliser le lien que ce site partage.

                <div class="img-box">
                        <iframe width="100%" height="100%" frameborder="0px" 
                            src="https://momento360.com/e/u/03b9e885f6e6423cb8575577e9b71144?utm_campaign=embed& \\
                                     utm_source=other&heading=0&pitch=0&field-of-view=75&size=medium"></iframe>
                </div>

Lorsque je teste cela sur mon navigateur j'obtiens donc une image 360° manipulable. J'ai réglé la hauteur et la largeur de l'image à 100% afin qu'elle s'adapte à la taille de la fenêtre.


Ensuite, afin que le joueur puisse envoyer sa réponse au site, il aura accès à un menu déroulant contenant le nom de tous les pays reconnus. Une fois sa réponse envoyée, le site vérifie si elle correspond bel et bien au nom du pays dans lequel cette image fut prise en allant chercher la réponse associée à l' URL dans la base de données. Si la réponse est correct, une nouvelle image sera affichée et le même principe recommence. Si la réponse est incorrecte, le joueur sera redirigé à la page d'accueil et le site s'occupera de vérifier s'il vient de fixer un nouveau record. Cela en faisant la différence entre son ancien meilleur score et le score qu'il vient de faire. Si le résultat est négatif, alors il s'agit d'un nouveau record.

3. Résultats

3.1Images

countryfindr_login.png, mai 2022
Figure 3 - Page de connexion


countryfindr_signup.png, mai 2022
Figure 4 - Page d'inscription


countryfindr_homepage.png, mai 2022
Figure 5 - Page d'accueil


countryfindr_leaderboard.png, mai 2022
Figure 6 - Page du classement des meilleurs scores

3.2 Gestion de compte

La création des comptes et la connexion à ceux-ci marchent parfaitement. Les données des utilisateurs sont bien stockées dans la table users de la base de données.

3.3 Fonctionnement du jeu

Malheureusement lorsqu'on clique sur le bouton New Game de la page d'accueil. L'utilisateur est bel et bien redirigé vers la page du jeu mais il n'y a rien d'autre qu'un fond blanc. Aucune image n'est affichée et le jeu n'est donc pas jouable.

4. Discussion

4.1 Difficultés rencontrées

Lors de la réalisation de ce projet, les principales difficultés que j'ai rencontrées furent du côté de la programmation. En effet la syntaxe paraît d'abord pénible puisque il faut définir chaque variable avec un $, mettre un ; à chaque fin de ligne et mettre des accolades mais on finit par s'y habituer. La programmation de la partie fonctionnelle du site m'a tout de même parue compliquée du fait que je n'ai pas beaucoup d'expérience en programmation. Une autre difficulté que j'ai rencontrée fut qu'il est en fait assez rare de trouver des images 360° de bonne qualité et dont on connaît l'emplacement. Il m'a donc fallut pas mal de temps avant de trouver des images me satisfaisant, tout ça pour que mon jeu ne fonctionne pas.

4.2 Piste d'améliorations

Puisque le jeu ne fonctionne pas du fait qu'aucune image n'est affichée, la première chose serait de trouver un moyen de rétablir cela. Je déduis que j'ai soit, mal utilisé la fonction rand afin de selection un URL aléatoirement dans la base de données soit, mal utilisé ma variable que j'avais définie. Je ne suis pas encore au point en programmation PHP et MySQL, il faudrait donc que je me renseigne d'avantage et que je passe plus de temps à programmer afin de me familiariser et d'acquérir plus d'expérience.

4.3 Ce que je retiens de ce projet

Ce projet m'a tout de même appris à manipuler une base de données à l'aide de phpMyAdmin et SQL. J'ai aussi appris à customiser un peu un site en CSS et j'ai eu un avant-goût des difficultés à faire correctement cela. Je retiens aussi qu'il aurait été favorable si je m'y étais pris un peu plus à l'avance…

5. Conclusion

Je ressors à la fois satisfait et déçu de ce projet. En effet je me retrouve à la fin avec un site dont la gestion de compte marche très bien et dont le design me plaît mais dont le jeu est injouable. Mon site peut alors être grandement amélioré. Mon projet ne me paraissait pas si compliqué que cela mais je doit admettre que j'ai peut-être surestimé mes capacités en programmation. Finalement, je termine ce projet avec quand même un peu plus de connaissance qu'auparavant.

Références

  • https://www.w3schools.com/cssref/
  • https://www.w3schools.com/howto/howto_css_image_text_blocks.asp
  • https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_button_css
  • https://www.w3schools.com/tags/tag_iframe.asp
  • https://www.youtube.com/watch?v=5lrLlcoRFKI
  • https://www.momento360.com/
  • https://www.php.net/manual/fr/