IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

[SDL2] 2048 -- phase de test -- besoin de conseils


Sujet :

SDL

  1. #1
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut [SDL2] 2048 -- phase de test -- besoin de conseils
    Salutations !!

    Pour l'année qui arrive, avec mes élèves, nous avons l'intention de faire un beau petit programme écrit en C en utilisant la librairie SDL2.
    De mon côté, pour essayer de m'y retrouver, j'ai "produit" un 2048.

    J'avais pas envie de télécharger les codes sources, d'autant que je ne suis pas certain que la version open source ait été écrite en C/SDL2.

    Résultats: ça marche, MAIS ^^

    Ma conception est la suivante: j'ai d'abord fait une simulation en mode console, pour intégrer les mécanismes propres au 2048, et vérifier si
    je suis capable de faire des modifications dans le tableau de deux dimensions représentant le score de chaque case.

    Ca fonctionne, je suis quasiment capable de faire une partie de bout en bout, mis à part que je n'ai pas encore fait la fonction qui va vérifier
    si il y a des possibilités de combinaisons sur le plateau de jeu dans le cas où il ne reste aucune case libre pour déposer un nombre (soit 2, soit 4, aléatoirement).

    Par contre le dépôt d'une nouvelle "tile" à chaque "mouvement" (ici le clavier -- touches de direction) fonctionne.
    La fin de partie est déclenchée dès qu'il n'y a plus de case libre.

    Ensuite, j'ai commencé un projet netbeans en incluant SDL2.
    Là c'est moins simple.

    Voici les deux trois petites choses pour lesquelles j'ai un gros soucis au niveau SDL2:

    + je voudrais mettre à jour le plateau de jeu composé de 16 textures en avant plan, en dessous desquelles j'ai "tracé" un carré avec des lignes et des colonnes représentant
    un plateau de jeu style 2048.

    Mon problème est le suivant: j'ai une fonction que j'appelle en début de programme qui me sert à faire le "set up" du plateau de jeu, des appels successifs à celle-ci ne font
    que superposer les "layers" au lieu de les remplacer. J'ai donc créer une fonction Update_Tiles() qui a pour mission de ne modifier sans superposer les cases du plateau de jeu.
    Ceci toujours en parcourant un tableau à deux dimensions contenant les scores de chaque case.

    Après pas mal de réflexion, d'essais et d'erreurs, je suis parvenu à obtenir quelque chose qui me convient au niveau "du rendu" (je n'ai pas l'impression que les "tiles" sont superposées)
    mais l'écran scintille quand j'opère Update_Tiles() après chaque mouvement effectué avec le clavier...

    Je ne sais pas comment ne mouvoir QUE certaines "tiles" (celles sur lesquelles s'opèrent une combinaison "un swap" par exemple).
    Je ne sais pas non plus comment "enlever" une texture, ou un ensemble de textures, pour les remplacer par un nouvel ensemble.

    Je garderais en mémoire les pointeurs sur ces textures (SDL_Texture) et je ferais un delete ou un remove sur ces pointeurs, mais je n'ai rien trouvé dans l'API SDL2 qui me permette
    de faire cela. J'ai d'ailleurs essayé de mettre ces pointeurs dans une liste chainée sans succès, apparemment SDL_Texture n'a pas de taille... j'ai regardé dans les codes sources de l'API
    et effectivement c'est bizarre, il n'y a rien de plus dans tous les fichiers .h du répertoire /usr/bin/SDL2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    /**
     *  \brief An efficient driver-specific representation of pixel data
     */
    struct SDL_Texture;
    typedef struct SDL_Texture SDL_Texture;
    Voici la fonction qui me pose soucis, je n'arrive pas à ne faire qu'un seul "refresh" à la fin de toutes les modifications, quand je fais SDL_RenderPresent() autrement que dans l'exemple, ça part
    en sucette, et je ne sais pas pourquoi --> ça affiche cinq ou six "tiles" mais sans rien d'autre... sans les éléments dessinés par la fonction Display_Layers().

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    void Update_Tiles(SDL_Renderer *paramRenderer)
    {
    	for(cptLignes=0;cptLignes<MAX_Y;cptLignes++)
    	{
     
    		for(cptColonnes=0;cptColonnes<MAX_X;cptColonnes++)
    		{
    			SDL_Rect			currentupdateZone;
    			SDL_Texture		*currentupdateTexture;
     
    			int value=tabTiles[cptLignes][cptColonnes];
    			fprintf(stderr,"[update] value: %d (%d,%d)\n",value,cptColonnes,cptLignes);
    			if(value!=0)
    			{
    				SDL_RenderPresent(paramRenderer);			// je ne suis pas certain du tout...
    				currentupdateTexture=DrawTile(paramRenderer,posupperlefttileX+(100*cptColonnes),posupperlefttileY+(100*cptLignes),5,value,(SDL_Color){170,170,170,200});
    				SDL_RenderPresent(paramRenderer);			// encore moins: comprend pas le principe...
    			}
    			else
    			{
    				// Tracer une tile vierge
    				SDL_RenderPresent(paramRenderer);
    				currentupdateTexture=DrawTile(paramRenderer,posupperlefttileX+(100*cptColonnes),posupperlefttileY+(100*cptLignes),5,0,(SDL_Color){19,19,19,255});
    				SDL_RenderPresent(paramRenderer);
    			}
    		}
    	}
     
    }
    + Est-ce qu'un thread d'affichage ferait l'affaire, si je parviens à effacer l'écran et à redessiner le tout 24 fois par seconde, par exemple ?
    Jusqu'à présent j'obtiens de bons résultats mais je superposes les écrans, je ne parviens pas à effacer les éléments courants même si SDL_RenderClear() est appelé...

    + Si je voulais faire une "animation" lorsque deux "tiles" se combinent (deux 4 côte à côte dans une direction): je pensais copier en un intervalle de une seconde le déplacement de
    la "tile" source vers les coordonnées en (x,y) de la "tile" de destination, cependant, je ne sais pas comment "rétablir" le fond d'écran pendant le déplacement, vu que je ne sais pas
    avoir accès aux textures affichées par le renderer.

  2. #2
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354

  3. #3
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    C'est plus ou moins mieux: je mets les appels à SDL_RenderPresent() en dehors de la boucle :{
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    void Update_Tiles(SDL_Renderer *paramRenderer)
    {
    	SDL_RenderPresent(paramRenderer);
    	for(cptLignes=0;cptLignes<MAX_Y;cptLignes++)
    	{
     
    		for(cptColonnes=0;cptColonnes<MAX_X;cptColonnes++)
    		{
    			SDL_Rect			currentupdateZone;
    			SDL_Texture		*currentupdateTexture;
     
    			int value=tabTiles[cptLignes][cptColonnes];
    			fprintf(stderr,"[update] value: %d (%d,%d)\n",value,cptColonnes,cptLignes);
    			if(value!=0)
    			{
    				currentupdateTexture=DrawTile(paramRenderer,posupperlefttileX+(100*cptColonnes),posupperlefttileY+(100*cptLignes),5,value,(SDL_Color){170,170,170,200});
    			}
    			else
    			{
    				// Tracer une tile vierge
    				currentupdateTexture=DrawTile(paramRenderer,posupperlefttileX+(100*cptColonnes),posupperlefttileY+(100*cptLignes),5,0,(SDL_Color){19,19,19,255});
    			}
    		}
    	}
    	SDL_RenderPresent(paramRenderer);
    }
    Je sais pas pourquoi je me suis obstiné à les mettre dans la boucle, autour de l'appel à DrawTile().

    Je cherche à me documenter mais tous les bouquins qui traitent d'SDL2 sont orientés C++... moi je programme en C uniquement pour les besoins de mes élèves.

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 858
    Points : 218 575
    Points
    218 575
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Pourquoi y a t-il un SDL_RenderPresent() au début de la boucle ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    En fait je ne sais pas j'ai pas encore tout compris, autant en SDL Blit_Surface() et SDL_Flip() je pouvais comprendre, ici "l'abstraction renderer" me pose énormément de soucis dans le sens que je ne sais pas du tout ce que je fais.
    Dans les exemples on me montre SDL_RenderClear() puis après avoir fait des appels à SDL_RenderCopy() il faut faire SDL_RenderPresent()... j'imagine, et je n'ai aucune infos à ce sujet, que RenderClear va mettre une feuille vierge
    à disposition, que RenderCopy va copier des textures sur cette feuille et que RenderClear fait la même chose que SDL_Flip() en SDL1... révéler la page sur laquelle nous venons de dessiner.

    Si mes souvenirs sont bons, si je ne fais pas le RenderPresent en début de boucle, les tiles créées par DrawTile() se superposent... j'ai essayé toutes les combinaisons possibles et c'est cette dernière disposition qui fait "flicker" le moins l'écran.
    Je voudrais juste ne mettre à jour que le plateau de jeu mais je n'y arrive pas... soit je n'ai que les "tiles" soit que le plateau mais les deux ensembles je n'y arrive pas.

    Je vais approfondir en lisant des bouquins et en essayant... là j'ai déjà quelque chose qui fonctionne plus ou moins... je sais que j'ai programmé ça comme un débutant vu que j'en suis un ^^

    Ci-joint le projet netbeans avec les sources, il faut copier les fichiers .o résultant de la compilation des "librairies" cssm_wide et linkedlist dans le répertoire de compilation (moi je fais des liens symboliques) ne pas oublier non plus les .h (pareil -> liens symboliques).
    Fichiers attachés Fichiers attachés

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 858
    Points : 218 575
    Points
    218 575
    Billets dans le blog
    120
    Par défaut
    En effet, SDL_RenderPresent est similaire à SDL_Flip.
    Je tiens à vous conseiller la lecture de ce tutoriel : http://alexandre-laurent.developpez....boucle-de-jeu/
    Pour moi, un seul SDL_RenderPresent() devrait apparaitre dans le code et celui-ci devrait apparaitre à la ligne 188/189 (dans la boucle principale.
    Aussi, l'appel à Display_Layers(), devrait se trouver au début de la boucle (avant le SDL_PollEvent).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  7. #7
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    Bon, je vais un peu m'y mettre, je fais 1000 choses en même temps et du coup je commence à avoir des soucis d'organisation ^^

    Merci pour les conseils... je fais un feedback fin de semaine...

  8. #8
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    ...c'est toujours buggé mais j'y travaille...

    ldf2048.tar.gz

  9. #9
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 313
    Points : 354
    Points
    354
    Par défaut
    Merci beaucoup !!

    J'ai effectivement retiré des instructions comme indiqué dans les exemples ci-dessous du coup: comme annoncé il n'y a plus d'effets de "flickering" (sorte de scintillements) à chaque mise à jour du "plateau de jeu".


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    void Update_Tiles(SDL_Renderer *paramRenderer)
    {
    #ifdef SUPERFLU
    	SDL_RenderPresent(paramRenderer);
    #endif
    	for(cptLignes=0;cptLignes<MAX_Y;cptLignes++)
    	{
    		for(cptColonnes=0;cptColonnes<MAX_X;cptColonnes++)
    		{
    			//SDL_Rect			currentupdateZone;
    			//SDL_Texture		*currentupdateTexture;
     
    			int value=tabObjects[cptLignes][cptColonnes].value;
    			//fprintf(stderr,"[update] value: %d (%d,%d)\n",value,cptColonnes,cptLignes);
    			if(value!=0)
    			{
    				DrawTile(paramRenderer,posupperlefttileX+(100*cptColonnes),posupperlefttileY+(100*cptLignes),5,value,(SDL_Color){170,170,170,200});
    			}
    			else
    			{
    				// Tracer une tile vierge
    				DrawTile(paramRenderer,posupperlefttileX+(100*cptColonnes),posupperlefttileY+(100*cptLignes),5,0,(SDL_Color){19,19,19,255});
    			}
    		}
    	}
    	SDL_RenderPresent(paramRenderer);
    }
    et surtout

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    switch(scancode)																																									// Gestion des codes propres à SDL pour le clavier
    			{
    				case 79:	MoveTiles(r_Dessinateur,&tabObjects[0][0],DROITE);
    #ifdef SUPERFLU
    								        Update_Tiles(r_Dessinateur);
    #endif
    									scancode=-1;
    									bMoved=true;
    									break;
    				case 80:  MoveTiles(r_Dessinateur,&tabObjects[0][0],GAUCHE);
    #ifdef SUPERFLU
    									Update_Tiles(r_Dessinateur);	
    #endif
    									scancode=-1;
    									bMoved=true;
    									break;
    				case 81:	MoveTiles(r_Dessinateur,&tabObjects[0][0],BAS);
    #ifdef SUPERFLU
    									Update_Tiles(r_Dessinateur);
    #endif
    									scancode=-1;
    									bMoved=true;
    									break;
    				case 82:	MoveTiles(r_Dessinateur,&tabObjects[0][0],HAUT);
    #ifdef SUPERFLU
    									Update_Tiles(r_Dessinateur);
    #endif
    									scancode=-1;
    									bMoved=true;
    									break;
    				case 224: bControlKeyDown=true;
    									break;
    				case 7:	if(bControlKeyDown) bRunning=false;
    								break;
    				default: bControlKeyDown=false;				
    			}
    ...sinon il faut revoir la partie "algorithme", en effet il y a des bugs dans la partie qui tente de gérer l'alignement de plusieurs "tiles" de même nombre, de temps en temps il y a des "swaps" qui se font en cascade
    alors que dans l'observation du fonctionnement du jeu, par exemple, quatre "2" alignés doivent donner deux "4" et non "8" en fin de traitement...

    GRAND MERCI pour les conseils ^^ je vais tenter de comprendre ce que je fais, et bouquiner d'avantage.

Discussions similaires

  1. Réponses: 4
    Dernier message: 20/05/2005, 13h30
  2. .htaccess - url rewriting, besoin de conseils
    Par giminik dans le forum Apache
    Réponses: 2
    Dernier message: 25/04/2005, 20h18
  3. [C#] [ADO.NET] Besoin de conseil
    Par djsbens dans le forum Accès aux données
    Réponses: 8
    Dernier message: 01/04/2005, 15h04
  4. Réponses: 3
    Dernier message: 24/12/2004, 12h21
  5. Réponses: 1
    Dernier message: 06/01/2003, 07h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo