Forums Développement Multimédia

Aller au contenu

[MINI TUTO] Brouillard de guerre

CODE AS3 JEUX BROUILLARD DE GUERRE TUTO

3 réponses à ce sujet

#1 RolyMix

    Ceinture Orange

  • Members
  • PipPipPip
  • 48 messages

Posté 18 April 2014 - 20:27 PM

Bonjour à tous !

Comme promis ici je viens vous informer de la méthode que j'ai utilisée pour faire mon brouillard de guerre et qui a maintenant une bonne tête avec une méthode qui n'handicape pas la fluidité.

Comme vous vous en doutez, on utilise un masque qui ne laissera entrevoir que les parties visitées. Il faut donc retenir les parties visitées de la carte.

Du coup j'avais opté pour une première méthode qui consistait à dessiner des cercles pleins dans un graphics, transformer celui-ci en bitmapdata pour découper la partie qui correspond à la zone affichée à l'écran => OUF !

La méthode est précise (c'est beau) mais très gourmande en ressource plus la carte devient grande ! Du coup M Spi m'avait conseillé d'utiliser des dales mémoire pour me rappeler où j'était passé.

Je doutais sur la qualité graphique de la méthode mais j'ai quand même tenté la chose.

Du coup j'utilise maintenant un tableau de dales (qui n'est pas forcement de la taille des dalles du jeu)

Je regarde si la position des dalles est dans la zone de découverte (le cercle autour du jouueur). Je ne fait ce test que si elle ne sont pas découverte et uniquement sur le carré de dalle circonscris du cercle.

Fonction pour ajouter les zones vues, r étant le rayon de visu, x,y la position du joueur et _tabExplo le tableau de dalle mémoire :


  public function addZone(x:int, y:int, r:int ):void {
 
   var c:Object = new Object();
   c.x = (x - r) / SIZE_CASE_EXPLO;
   c.y = (y - r) / SIZE_CASE_EXPLO;
   c.rayon = r / SIZE_CASE_EXPLO;
 
   //positionne les cases vues à 1 et ne test que les cases à 0

   var initR:int = r / SIZE_CASE_EXPLO;
   var initX:int = (x-r) / SIZE_CASE_EXPLO;
   var initY:int = (y-r) / SIZE_CASE_EXPLO;

   for (var i:int = initX; i < initX + initR*2; i++) {
        for (var j:int = initY; j < initY + initR*2; j++) {
         if (_tabExplo[i*sizeWEplo + j]==0) {
          //si la case est dans l'environnement du joueur et pas déjà marquée à 1
          //on, fait le test collision
          TabCollisions.collisionCerclePoint(i, j, c) ? _tabExplo[i * sizeWEplo + j] = 1 : _tabExplo[i * sizeWEplo + j] = 0;
         }
        }  
   }
 

SIZE_CASE_EXPLO est une constante qui défini la taille de mes dalles d'exploration en pixels.

On récupère donc les données par une autre fonction, qui, avec la position de l'image à réaliser, la taille et l'image du jeu (sans ennemis) renvoie le sprite à afficher. Ca donne l'image suivante :
Fichier joint  Capture1.PNG   54.85 Ko   14 téléchargement(s)

Le code :


         public function getFogZone(x:int, y:int, W:int, H:int, bckGround:Graphics = null):Sprite {
                        var sG:Graphics = _spriteGris.graphics;
                        var mG:Graphics = _masqueSpriteGris.graphics;
                        var initX:int = x / SIZE_CASE_EXPLO;
                        var initY:int = y / SIZE_CASE_EXPLO;
                        var initH:int = H / SIZE_CASE_EXPLO;
                        var initW:int = W / SIZE_CASE_EXPLO;
                       
                        //importer l'image de fond a estomper
                        sG.copyFrom(bckGround);
                       
                        //estomper avec un noir mitransparent
                        sG.beginFill(0x000000, 0.75);
                        sG.drawRect(0, 0, W, H);
                        sG.endFill();
                       
                        //Dessiner les carré visités pour montrer l'écran du jeu en dessous (bckGround)
                        mG.clear();
                        mG.beginFill(0x000000);
                        for (var i:int = initX; i < initX + initW + 1; i++) {
                                for (var j:int = initY; j < initY + initH + 1; j++) {
                                        if (_tabExplo[i*sizeWEplo + j]==1) {
                                                //si la case est visitée, à 1, on la dessine pour voir en dessous
                                                mG.drawRect(i * SIZE_CASE_EXPLO - x , j * SIZE_CASE_EXPLO -  y , SIZE_CASE_EXPLO , SIZE_CASE_EXPLO)
                                        }
                                }                      
                        }                      
                        mG.endFill();
                       
                        return _fogWar;
                }
 

Et la touche final, qui ne m'était pas venu à l'esprit avec un masque, c'est de rajouter un petit filtre Blur pour adoucir ces vilains carré que je n'aimais pas :


   _masqueSpriteGris.filters = [new BlurFilter(SIZE_CASE_EXPLO * 2, SIZE_CASE_EXPLO * 2, BitmapFilterQuality.HIGH)];
 

ce qui donne :
Fichier joint  Capture2.PNG   114.81 Ko   17 téléchargement(s)

Voilà le résultat si ca peut aider quelqu'un. Moi je n'ai pas trouvé de site qui parle de brouillard de guerre. Evidemment ce code est produit par un novice (moi), donc il peut certainement être amélioré. Je voulais juste le faire partager car je trouve le résultat très satisfaisant !

Merci à ceux qui m'ont aidé à savoir M Spi et Lilive pour leur explications et voies de recherche.

Roly

#2 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 6954 messages

Posté 22 April 2014 - 17:32 PM

Hello,

Merci pour ce tuto et ce retour, je ne sais pas si le Wiki est toujours d'actu mais ce serait bien de le glisser dans la partie jeux : http://forums.mediab...shplatform/jeux

#3 RolyMix

    Ceinture Orange

  • Members
  • PipPipPip
  • 48 messages

Posté 22 April 2014 - 20:16 PM

Petite modification :

Etant donné que souvent, dans les jeux qui utilisent un brouillard de guerre, il est souvent utile d'avoir une carte des parties visitée, j'ai légèrement modifié le code pourne pas utiliser un tableau mais un bitmapdata dans lequel, chaque pixel représente une case découverte.

Du coup j'utilise des getpixel pour savoir si la zone est dejà explorée, et des setpixel pour passe la zone dans la couleur correspondant à l'exploration.

J'en profite pour faire varier la couleur selon si sur la carte, c'est un mur ou un passage. La minimap se dessine donc au fur et a mesure.

code modifié :

   for (var i:int = initX; i < initX + initR*2; i++) {
    for (var j:int = initY; j < initY + initR * 2; j++) {
       
         if (_miniMapView.getPixel(i,j) == UNVISITED_COLOR) {
          //si la case est dans l'environnement du joueur et pas déjà marquée à 1
          //on, fait le test radial
          if (TabCollisions.collisionCerclePoint(i, j, c)) {
           if (ScrollMonitor.mapData[int(j * SIZE_CASE_EXPLO / T ) * ScrollMonitor.Csize + int(i * SIZE_CASE_EXPLO / T )] != 0) {
            _miniMapView.setPixel(i, j, WALL_COLOR);
           } else {
            _miniMapView.setPixel(i, j, VISITED_COLOR);
           }
          }
         }
    }  
   }  
 

T est la taille de mes cases de carte

Et pour obtenir la carte, elle est déjà toute prete dans ma donnée : _miniMapView

Je n'ai pas trouvé de ralentissement.

Ah si, le filter Blur bouffe pas mal de ressources. A vous de voir, peut-être que sans le filter blur vous aimerez aussi (très fluide).

M SPI, est-ce à moi de déplacer le sujet dans le wiki jeu ? je sais pas faire ca moi...

#4 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 6954 messages

Posté 22 April 2014 - 20:33 PM

Tu peux si tu veux, il suffit de t'inscrire sur le Wiki et de rédiger ton article.
Préviens nous dès que c'est fait, il passera alors en validation et si tout est ok on le met en ligne.
Le tout est de savoir si le Wiki est encore ouvert aux rédacteurs ou pas, je vais me renseigner et je te tiens au courant.



1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)

authorised training centre

Centre de Formation Mediabox - Adobe et Apple Authorised Training Center.

Déclaré auprès de la Direction du Travail et de la Formation Professionnelle

Mediabox : SARL au capital de 62.000€ - Numéro d'activité : 11 75 44555 75 - SIRET : 49371646800035

MEDIABOX, 23, rue de Bruxelles, 75009 PARIS

FFP