Search code examples
ceventsevent-handlingsdl

Using SDL-C library, mouse motion bug in simple game


I am trying to make a simple game. I have the following code with which I am placing some images on the screen. I want to make it so that when left click is pressed and I move the mouse, those images are continuously put on the screen (so that the player does not have to click many times over.) I have the following:

SDL_Surface *mur = NULL, *caisse = NULL, *objectif = NULL, *mario = NULL;
     SDL_Rect position;
     SDL_Event event;

     int continuer = 1, clic_gauche = 0, clic_droit = 0;
     int objet_actuel = MUR, i = 0, j = 0;
     int carte[NB_BLOCS_LARGEUR][NB_BLOCS_HAUTEUR] = {0};

     //Chargement des objets et du niveau.
     mur = IMG_Load("mur.jpg");
     caisse = IMG_Load("caisse.jpg");
     objectif = IMG_Load("objectif.png");
     mario = IMG_Load("mario_bas.gif");

     if(!Charger_Niveau(carte)) //Erreur de chargement du niveau.
     exit(EXIT_FAILURE);

     while(continuer)
     {
         SDL_WaitEvent(&event);
         switch(event.type)
         {

             case SDL_MOUSEBUTTONDOWN:
                  if (event.button.button == SDL_BUTTON_LEFT)
                  {
                      carte[event.button.x/TAILLE_BLOC][event.button.y/TAILLE_BLOC] = objet_actuel; //On met l'objet actuellement choisi a l'endroit du clic.
                      clic_gauche = 1; //On retient le fait que le dernier clic etait un clic gauche.
                  }
                  else if (event.button.button = SDL_BUTTON_RIGHT)
                  {
                      carte[event.button.x/TAILLE_BLOC][event.button.y/TAILLE_BLOC] = VIDE; //On vide le bloc ou s'est produit le clic droit.
                      clic_droit = 1; //On retient le fait que le dernier clic etait un clic droit.
                  }
                  break;

             case SDL_MOUSEBUTTONUP: //On desactive le booleen qui disait qu'un bouton etait enfonce.
                  if(event.button.button == SDL_BUTTON_LEFT)
                      clic_gauche = 0;
                  else if(event.button.button == SDL_BUTTON_RIGHT)
                      clic_droit = 0;
                  break;

              case SDL_MOUSEMOTION:
                   if(clic_gauche == 1)
                   {
                       carte[event.motion.x / TAILLE_BLOC][event.motion.y / TAILLE_BLOC] == objet_actuel;
                   }
                   else if(clic_droit == 1)
                   {
                       carte[event.motion.x/TAILLE_BLOC][event.motion.y/TAILLE_BLOC] == VIDE;
                   }
                   break;

The loop then continues checking if some keys have been pressed, then I blit all the images that were loaded using the double matrix carte and I refresh the screen. The problem is mouse motion doesn't work. Debugging events is rather difficult...does anyone see an evident problem with the code?


Solution

  • You're not assigning into carte in the SDL_MOUSEMOTION handler, you're comparing.

    (Unfortunately, any expression is allowed to be a statement in C, even if it has no effects/side-effects on the program, so the compiler doesn't necessarily help you find these issues.)

    Your handler should be:

      case SDL_MOUSEMOTION:
           if(clic_gauche == 1)
           {
               carte[event.motion.x / TAILLE_BLOC][event.motion.y / TAILLE_BLOC] = objet_actuel;
           }
           else if(clic_droit == 1)
           {
               carte[event.motion.x/TAILLE_BLOC][event.motion.y/TAILLE_BLOC] = VIDE;
           }
           break;
    

    (Note the single = in each case of the if/else)

    Also, the inverse issue affects the handler for SDL_MOUSEBUTTONDOWN where you're assigning to event.button.button rather than comparing its value against the constant SDL_BUTTON_RIGHT.

    Note: for this reason, many developers have taken to putting the constant on left-hand side of a comparison, so that the compiler will give you an error if you mistype the operator. E.g.,

    else if (SDL_BUTTON_RIGHT == event.button.button)