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 :

Animation d'un bouton


Sujet :

SDL

  1. #1
    Membre régulier Avatar de ludo86
    Homme Profil pro
    Développement applications iOS/android
    Inscrit en
    Avril 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développement applications iOS/android
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 93
    Points : 79
    Points
    79
    Par défaut Animation d'un bouton
    Bonjour,

    Je suis nouveau en ce qui concerne l'usage de la SDL et j'ai un problème.

    J'ai un bouton d'un forme X. Quand la souris ne le survole pas, il a telle apparence. Si la souris le survole il a une autre apparence.
    En ayant suivi les tuto de ce site, j'arrive bien à faire apparaitre le bouton avec son apparence initiale non survolée. Néanmoins, quand je le survole avec la souris l'image ne change pas et je ne comprend pas pourquoi.

    main.cpp
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
     
    #include <iostream>
    #include "environment.h"
    #include "bouton.h"
     
    using namespace std;
     
    void addListener(Bouton* matchOne){
     
    	bool quit = false;
    	SDL_Rect* previousState = matchOne->getState();
    	while(!quit){
    		while(SDL_PollEvent(&event)){
    			if(event.type == SDL_QUIT){
            			//On quitte le programme
            			quit = true;
    			}
    			else{
    				if(event.type == SDL_MOUSEMOTION ){
    					matchOne->handleEvents(event);
     
    					if(matchOne->getState() != previousState){
    						previousState = matchOne->getState();	SDL_BlitSurface(matchOne->getPictureContent(),matchOne->getState(),screen,matchOne->getContainer());
    						//SDL_BlitSurface(matchOne->getPictureContent(),matchOne->getState(),screen,&offset);
    					}				
    				}	
    			}
    		}
    	}
     
    }
     
    void close(){
    	//Libération des surfaces 
    	SDL_FreeSurface( background );
     
    	//On quitte SDL 
    	SDL_Quit(); 
    }
     
    int main(int argc,char* argv[]){
    	//Initialisation de tous les sous-systèmes de SDL 
    	if(SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) { 
    		return EXIT_FAILURE; 
    	}
    	//Mise en place de l'écran 
    	screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
    	//S'il y a une erreur dans la création de l'écran 
    	if( screen == NULL ) { 
    		return EXIT_FAILURE; 
    	}
     
    	//Mise en place de la barre caption 
    	SDL_WM_SetCaption("Test action bouton",NULL);
    	background = load_image("arrierePlan.bmp");
     
    	//On applique le fond sur l'écran 
    	apply_surface( 0, 0, background, screen );
     
    	//on applique les boutons
    	Bouton* matchOne = new Bouton(20,30);
     
    	matchOne->setPictureContent(load_image("allumettesBis.bmp"));
    	SDL_BlitSurface(matchOne->getPictureContent(), matchOne->getState(), screen,matchOne->getContainer());
    	//Mise à jour de l'écran 
    	if( SDL_Flip( screen ) == -1 ){ 
    		return EXIT_FAILURE; 
    	}
     
    	addListener(matchOne);	
    	close();
    	return EXIT_SUCCESS;
    bouton.h
    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
     
    #include <iostream>
    #ifndef BOUTON_H
    #define BOUTON_H
     
    #include "SDL/SDL.h"
    //#include "environment.h"
    using namespace std;
     
    #define ON_MOUSE_OUT 0
    #define ON_MOUSE_OVER 1
     
    class Bouton
    {
    	private : 
    		SDL_Rect container;
    		SDL_Rect states[2];
    		SDL_Rect* state;
    		SDL_Surface* pictureContent;
    	public : 
    		Bouton(int _x,int _y);
    		~Bouton();
    		SDL_Surface* getPictureContent();
    		SDL_Rect* getState();
    		SDL_Rect* getContainer();
    		void initStatePicture();
    		void setPictureContent(SDL_Surface*);
    		void handleEvents(SDL_Event);
    		//SDL_Event MouseEvent;
    };
     
    #endif
    bouton.cpp
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
     
    #include "bouton.h"
     
    Bouton :: Bouton(int _x,int _y){
    	//setPictureContent(load_image("allumettesBis.bmp"));
    	initStatePicture();
    	container.x = _x;
    	container.y = _y;
    	container.w = 100;
    	container.h = 352;
    	state = &states[ON_MOUSE_OUT];
    }
     
    void Bouton :: initStatePicture(){
    	states[ON_MOUSE_OUT].x = 0;
    	states[ON_MOUSE_OUT].y = 0;
    	states[ON_MOUSE_OUT].w = 100;
    	states[ON_MOUSE_OUT].h = 352;
    	states[ON_MOUSE_OVER].x = 100;
    	states[ON_MOUSE_OVER].y = 0;
    	states[ON_MOUSE_OVER].w = 100;
    	states[ON_MOUSE_OVER].h = 352;
    }
     
    void Bouton :: handleEvents(SDL_Event mouseEvent)
    {
        //Les coordonnees de la souris
        int x = 0, y = 0;
    	x = mouseEvent.motion.x;
    	y = mouseEvent.motion.y;
    	//Si la souris est dans le bouton
    	if( ( x > container.x ) && ( x < container.x + container.w ) && ( y > container.y ) && ( y < container.y + container.h)){
         		//Mise à jour du sprite du bouton
         		state = &states[ ON_MOUSE_OVER ];
    	}
    	else{
    	     	//Mise à jour du sprite du bouton
    		state = &states[ ON_MOUSE_OUT ];
    	}
    }
     
    Bouton :: ~Bouton(){
    	delete state;
    	delete pictureContent;
    }
     
    SDL_Surface* Bouton :: getPictureContent(){
    	return pictureContent;
    }
     
    SDL_Rect* Bouton :: getState(){
    	return state;
    }
     
    SDL_Rect* Bouton :: getContainer(){
    	return &container;
    }
     
    void Bouton :: setPictureContent(SDL_Surface* _pictureContent){
    	this->pictureContent = _pictureContent;
    }
    environment.h
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
     
    #include <iostream>
    #include "SDL/SDL.h"
     
    //dimension ecran
    const int SCREEN_WIDTH = 640; 
    const int SCREEN_HEIGHT = 480; 
    const int SCREEN_BPP = 32;
     
     
    //fond d'ecran
    SDL_Surface *background = NULL; 
    SDL_Surface *screen = NULL;
     
     
    //événement
    SDL_Event event;
     
    SDL_Surface *load_image( std::string filename ) { 
    	//Surface tampon qui nous servira pour charger l'image 
    	SDL_Surface* loadedImage = NULL; 
     
    	//L'image optimisée qu'on va utiliser 
    	SDL_Surface* optimizedImage = NULL;
     
    	//Chargement de l'image
    	loadedImage = SDL_LoadBMP( filename.c_str() );
     
    	//Pour toutes les images autres que bmp
    	//loadedImage = IMG_load(filename.c_str());
     
    	//Si le chargement se passe bien
    	if( loadedImage != NULL ) { 
    		//Création de l'image optimisée 
    		optimizedImage = SDL_DisplayFormat( loadedImage ); 
     
       		if( optimizedImage != NULL ){
    			//On met tous les pixels de couleur R 0xFF, G 0xFF, B 0xFF transparent
        			Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0xFF, 0xFF, 0xFF );
    			SDL_SetColorKey( optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorkey );
    		}
    		//Libération de l'ancienne image
    		SDL_FreeSurface( loadedImage ); 
    	}
     
    	//On retourne l'image optimisée 
    	return optimizedImage; 
    }
     
    void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination ) { 
    	SDL_Rect offset; 
     
    	offset.x = x; 
    	offset.y = y;
    	//On blitte la surface 
    	SDL_BlitSurface( source, NULL, destination, &offset ); 
    }
    Où ai-je commis une erreur?

  2. #2
    Membre habitué Avatar de Polyfructol
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2007
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2007
    Messages : 131
    Points : 157
    Points
    157
    Par défaut
    En fait tu oublies de rafraichir l'écran à chaque boucle. Là dans ton code, il faudrait que tu rajoutes SDL_Flip( screen ) à la fin de la boucle while(!quit).

  3. #3
    Membre régulier Avatar de ludo86
    Homme Profil pro
    Développement applications iOS/android
    Inscrit en
    Avril 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développement applications iOS/android
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 93
    Points : 79
    Points
    79
    Par défaut
    Merci pour ton aide ça marche parfaitement.

    Par contre j'ai de nouveau un autre problème. Comme supprimer l'ancienne image de mon bouton?
    En effet, j'ai bien l'image du bouton survolé cependant comme celui-ci comporte des parties transparentes, on peut peut voir l'ancienne image du bouton en arriere plan.


    J'espère être assez clair.

  4. #4
    Membre habitué Avatar de Polyfructol
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2007
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2007
    Messages : 131
    Points : 157
    Points
    157
    Par défaut
    Et bien t'as pas beaucoup de choix, tu peux faire un SDL_FillScreen pour remplir la zone du bouton d'une couleur noire, ou pour effacer toute la zone de l'écran.

    Mais en fait cette question ne se pose pas trop dans les programmes 2D car habituellement, dans les jeux vidéos 2D, l'image est constituée d'un background et de sprites, qui sont systématiquement redessinés à chaque image.

    Parce que j'ai remarqué que tu ne dessinais ton bouton que lors de son changement d'état, cela peut poser des problèmes, ex :
    - Tu personnalises la souris en y assignant un SDL_Surface qui se déplace en fonction de sa position
    -> lorsque la souris va se balader sur le bouton, comme celui ci ne va pas se rafraichir, la trace de la souris va rester jusqu'à ce qu'il change d'état.

    En gros si tu ne redessines pas tout l'écran à chaque rendu, tu risques de laisser des traces sur les zones qui ne sont pas mises à jour. Je sais pas si c'est clair

  5. #5
    Membre régulier Avatar de ludo86
    Homme Profil pro
    Développement applications iOS/android
    Inscrit en
    Avril 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développement applications iOS/android
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 93
    Points : 79
    Points
    79
    Par défaut
    J'utilise en effet des sprites.

    Le problème est que j'ai ça.

    Bouton non survolé


    Bouton survolé



    Comme on peut le voir l'image du bouton non survolé est resté, or je ne le veux pas.

    Comment faire alors?

  6. #6
    Membre habitué Avatar de Polyfructol
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2007
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Avril 2007
    Messages : 131
    Points : 157
    Points
    157
    Par défaut
    J'ai dit SDL_FillScreen à la place de SDL_FillRect()

    Sinon, moi je ferais ça,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while(!quit) {
        SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
        ... // boucle d'évènement, etc...
        SDL_Flip(screen);
    }
    Mais dans ta logique, tu peux aussi faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SDL_FillRect(screen, matchOne->getContainer(), SDL_MapRGB(screen->format, 0, 0, 0));
    SDL_BlitSurface(matchOne->getPictureContent(),matchOne->getState(),screen,matchOne->getContainer());
    Mais j'ai un petit doute sur la deuxième.

  7. #7
    Membre régulier Avatar de ludo86
    Homme Profil pro
    Développement applications iOS/android
    Inscrit en
    Avril 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développement applications iOS/android
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 93
    Points : 79
    Points
    79
    Par défaut
    Merci pour ton aide.

    J'ai choisi la solution suivante, peut être pas la mieux mais pour l'instant elle me convient.

    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
     
     
    while(!quit){
    		while(SDL_PollEvent(&event)){
     
    			if(event.type == SDL_QUIT){
            			quit = true;
    			}
    			else{
    				if(event.type == SDL_MOUSEMOTION ){
    					matchOne->handleEvents(event);
    					SDL_MapRGB(screen->format, 0, 0, 0));
    					apply_surface( 0, 0, background, screen );
    SDL_BlitSurface(matchOne->getPictureContent(),matchOne->getState(),screen,matchOne->getContainer());
    						SDL_Flip( screen );
    				}	
    			}
     
    		}
    	}

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. onmouseover et Animation d'un bouton
    Par starlogix dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 22/04/2009, 15h30
  2. [Maxi débutant] modifier l'animation d'un bouton
    Par comode dans le forum ActionScript 1 & ActionScript 2
    Réponses: 4
    Dernier message: 24/02/2009, 00h31
  3. Gif animé sur un bouton
    Par g_barthe dans le forum wxPython
    Réponses: 2
    Dernier message: 02/09/2008, 14h28
  4. Animation d'un bouton
    Par Nadd dans le forum Flash
    Réponses: 1
    Dernier message: 01/10/2006, 17h46
  5. animation curseur sur bouton
    Par Chonko dans le forum Flash
    Réponses: 11
    Dernier message: 24/07/2006, 13h27

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