Programmer un screenshaker en C# / XNA
 

      Lorsque j'ai décidé de convertir Wiwi's Adventures du C avec la SDL en C# avec Xna, j'ai dû tout recoder. Et forcément, j'ai aussi dû recoder mon screenshaker qui faisait son petit effet avec les boss !

Tutoriel présenté par : Jérémie F. Bellanger
Publication : 07 octobre 2010
Date de révision : 7 novembre 2015



    Mais tant qu'à le recoder, j'avais envie de l'améliorer ! Le problème de la première version, c'est qu'il figeait le jeu quelques secondes pendant le tremblement. Pour cette mouture, je voulais que l'écran tremble mais que le jeu continue à se dérouler en temps réel ! Plus dur, hein ?

    Comme j'ai fait un tutoriel pour le premier screenshaker en C et que j'ai dû cherhcer un moment avant de trouver comment faire en C# (en fait il y a plusieurs possibilité, mais j'ai choisi la plus simple ), je propose donc un nouveau tuto pour le C# avec Xna.

    Je vous rappelle que si vous ne savez pas ce qu'est Xna, vous pouvez vous rendre ici, et découvrir sa puissance (et à vous la programmation de la Xbox 360, ce qui est quand même pas mal  !)

    Bon passons à notre code. Première chose, on va créer une petite fonction qui se chargera de démarrer le tremblement de l'écran (cela dit, ce n'est pas obligatoire, car elle ne fait que deux lignes -> vous ne gagnerez donc qu'une ligne de copier/coller à chaque fois que vous voudrez l'appeler).

    Cette fonction utilise une autre classe : Gestion, qui contient toutes les variables nécessaires à la gestion globale du jeu : ici un son (SoundEffect) : choc et une variable (int) : shakeScreen. Libre à vous de placer ces variables où bon vous semble dans votre projet !

 
         public static void shakeScreen(Gestion jeu)
        {
            jeu.choc.Play();
            jeu.shakeScreen = 100;
        }


    Ce que fait cette fonction est donc très simple : quand il y a un tremblement, elle joue le son de ce tremblement et donne la valeur 100 à la variable shakeScreen (avant à 0) pour indiquer qu'il va falloir faire trembler l'écran.

    Maintenant, pour faire trembler l'écran, on va retourner dans la 1ère classe de base d'un projet de jeu Xna (par défaut game1.cs, je crois) et on va aller dans la fonction, ajoutée par défaut :
Draw().

    C'est en effet ici, que l'on doit indiquer tous les sprites à dessiner à l'écran et c'est donc ici que l'on doit faire trembler notre écran !
 
 
        protected override void Draw(GameTime gameTime)
        {
            //Efface l'écran en le coloriant en noir
             GraphicsDevice.Clear(Color.Black);


           //Si on doit faire trembler l'écran, on fait une translation grâce            
           //à la fonction Shake(), ci -dessous.


             if (jeu.
shakeScreen > 0)
            {
                Matrix translate = Matrix.CreateTranslation(Shake());

                // Displace everything that gets drawn in this batch 
                spriteBatch.Begin(SpriteBlendMode.AlphaBlend,                                    
                      //Ici, choisissez immediate si vous voulez que vos                            
                     //sprites soient superposés dans l'ordre où vous les

                     // avez placés (d'autres options sont possibles - cf. doc)
                      SpriteSortMode.
Immediate,

                      SaveStateMode.None, translate);
                jeu.
shakeScreen
--;
            }

            //Sinon on lance le spriteBatch normal
             else

            {
                spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            }

           
            /* Draw your sprites, tiles, images here */
           
                       
            spriteBatch.End();

            base.Draw(gameTime);
        }


         //Voici la fonction Shake() qui renvoie un x et un y au hasard
        //pour faire varier la position de l'écran. Notez que vous pouvez        
        //jouer sur la valeur (4) pour diminuer ou augmenter les

        // tremblements.

         private Vector3 Shake()
        {
            return new Vector3(
                (float)((random.NextDouble() * 4) - 1),
                (float)((random.NextDouble() * 4) - 1), 0);
        }




    Voilà, donc en fait on modifie le spriteBatch (qui est chargé de dessiner les sprites les uns par dessus les autres et de les afficher à l'écran) si l'on doit faire trembler l'écran en lui appliquant une translation, calculée au hasard par la fonction Shake(). A chaque tremblement, on diminue la variable shakeScreen jusqu'à 0.

    Vous pouvez donc contrôler la durée du tremblement en changeant la valeur d'initialisation de la variable 
shakeScreen et son intensité en changeant la valeur multiplicative (4) de la fonction Shake().

    Vous noterez également, que notre code n'entrave pas la fonction Update() de notre jeu qui continue donc de gérer les sprites, boss, monstres, etc. et que le jeu continue d'afficher tous les sprites comme normalement. 

    Notre code se contente donc de faire une translation alétoire de la position de l'écran à chaque frame (60 fois par seconde) pendant la durée du screenshake ! Si c'est pas beau ça  !


Attention !

    Pour d'obscures raisons, ce code fonctionne mal dès lors que l'on ajoute les GamerServices permettant de se connecter au compte joueur Xbox Live du player ( pour info : Components.Add(new GamerServicesComponent(this)); dans la partie Initialize() ). Si vous affichez du tilemapping, on pourra voir des espaces entre les tiles, ce qui n'est pas très beau.

    C'est donc surtout gênant pour la Xbox, mais si vous restez sur Windows et que vous n'avez pas besoin du Xbox Live ou que vous ne faites pas de Tilemapping, il ne devrait pas y avoir de problème. Je cherche en ce moment-même une alternative...


 

Connexion

CoalaWeb Traffic

Today167
Yesterday157
This week679
This month2972
Total1742179

18/04/24