Corrigé du TD 6 : déroulement d’un programme événementiel

Gestion des événements claviers

Les fonctions set_flags et grab_focus sont membres de la classe Gtk::DrawingArea ou un de ces ancètres. En l'occurence, ces fonctions sont utiles pour tous les widgets et sont membres de la classe Gtk::Widget.

Événement clavier, par une fonction virtuelle

Il faut redéfinir la fonction bool on_key_press_event(GdkEventKey*) dans la classe ZoneDeJeu. La valeur de la touche est stockée dans le membre keyval de l'événement.

Événement clavier, par un signal

Il faut ajouter une fonction membre bool GestionClavier(GdkEventKey * event) à la classe ZoneDeJeu. Une fois cette fonction créee, on la connecte au signal key_press_event :

signal_key_press_event().connect(sigc::mem_fun(*this, &ZoneDeJeu::GestionClavier));

Pause

Une variable booléenne pause dans la classe ZoneDeJeu décrit l'état du jeu (en pause ou non). Cette variable est inversée lorsque le joueur appuie sur espace. Le code de la fonction de gestion des événements clavier devient :

if(event->keyval == GDK_space)
{
    pause = !pause;
}

La fonction MiseAJour ne déplacera les mobiles que si pause est faux.

Début et fin de partie

L'état de la partie peut être décrit par un enum, membre de la classe ZoneDeJeu :

enum Etat {Debut, Jeu, Pause, Fin};

Il faut aussi bien sur une variable membre de type Etat. Le code de la fonction de gestion des événements clavier devient :

if(event->keyval == GDK_space)
{
    switch(etat)
    {
        case Debut :
            etat = Jeu;
            break;
        case Jeu :
            etat = Pause;
            break;
        case Pause :
            etat = Jeu;
            break;
        case Fin :
            etat = Debut;
            score = 0;
            break;
    }
}

La fonction Dessiner est modifiée de façon similaire pour prendre en compte l'état de la partie :

switch(etat)
{
    case Debut :
        std::ostringstream text;
        text << "appuyez sur espace pour commencer";
        get_window()->draw_layout(gcTexte, 10,10, create_pango_layout(text.str()));
        break;
    case Jeu :
    case Pause :
        mobile.Dessiner();
        std::ostringstream text;
        text << "score: " << score;
        get_window()->draw_layout(gcTexte, 10,10, create_pango_layout(text.str()));
        break;
    case Fin :
        std::ostringstream text;
        text << "fin de partie (appuyez sur espace), score:" << score;
        get_window()->draw_layout(gcTexte, 10,10, create_pango_layout(text.str()));
        break;
}

Gestion de plusieurs mobiles

Au lieu d'avoir une variable membre de type Mobile dans la classe ZoneDeJeu, on met une variable de type std::vector<Mobile*>. Les mobiles sont initialisés dans le constructeur :

for(int i=0;i<10;i++)
{
    mobiles.push_back(new Mobile());
}

Les fonctions PlusVite, MoinsVite, on_realize, Dessiner et MiseAJour appellent les fonctions correspondantes sur l'ensembles des mobiles.

Affichage d'images

Les images sont représentées par un objet de la classe Gdk::Pixbuf, utilisée de la façon suivante :

// Entête nécessaire
#include <gdkmm/pixbuf.h>
 
// On déclare un pointeur sur un Pixbuf
Glib::RefPtr<Gdk::Pixbuf> image;
// On charge une image à partir d'un fichier
image=Gdk::Pixbuf::create_from_file("elephant.jpeg");
// On affiche avec draw_pixbuf, de la même façon qu'un rectangle est
// dessiné avec draw_rectangle.
window->draw_pixbuf(gc, image,
                    0, 0,
                    x, y,
                    image->get_width(), image->get_height(),
                    Gdk::RGB_DITHER_NORMAL, 0, 0);

La fonction Gdk::Drawable::draw_pixbuf permet en fait de dessiner une zone d'un Pixbuf, avec les paramètres suivants :

  • gc : le contexte graphique nécéssaire aux fonctions de dessin.
  • image : l'image à dessiner, de type Glib::RefPtr<Gdk::Pixbuf>.
  • srcX et srcY : deux entiers, début de la zone du Pixbuf qui sera dessinée.
  • destX et destY : deux entiers, coordonnées de l'endroit dans la fenêtre où est dessinée l'image.
  • width et height : largeur et hauteur de la zone de l'image à dessiner.
  • des paramètres de tramage des couleurs, à laisser comme dans l'exemple ci-dessus.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>