[C/C++] edition d'une carte,Probleme!

Le côté programmation du développement d'un jeu vidéo.

edition d'une carte,Probleme!

Messagepar maxou02 » 13 Avr 2008, 22:11

Bonjour a tous,
je me suis lancer dans la programmation en c et pour parfaire ma connaissance je me suis creer un exercice faire un petit mario like.Mais je suis confronter a un probleme avec mon editeur de map.Quand je me deplace sur la carte a l'aide du scrolling je ne peut pas mettre les objets a la position souhaiter.
Code: Tout sélectionner
#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

#include "constantes.h"
#include "editeur.h"
#include "fichiers.h"

void editeur(SDL_Surface* ecran)
{
    SDL_Surface *sol = NULL, *block = NULL, *blockB = NULL, *hhh = NULL, *fond = NULL, *mario = NULL;
    SDL_Rect position, posMap, positionSurMap, positionO;
    SDL_Event event;

    int continuer = 1, clicGaucheEnCours = 0, clicDroitEnCours = 0;
    int objetActuel = SOL, i = 0, j = 0;
    int carte[NB_BLOCS_LARGEUR][NB_BLOCS_HAUTEUR] = {0};
    SDL_Rect cam = { 0, 0, 800, 600 };


    // Chargement des objets et du niveau
    hhh = IMG_Load("data//images//others//hhh.JPG");
    sol = IMG_Load("data//images//textures//herbe.BMP");
    block = IMG_Load("data//images//textures//bloc.BMP");
    blockB = IMG_Load("data//images//textures//bonus2-1.png");
    mario = IMG_Load("data//images//jeu//mario_droite.gif");
    fond = IMG_Load("data//images//backgrounds//1.GIF");



    if (!chargerNiveau(carte))
        exit(EXIT_FAILURE);

    // Boucle infinie de l'éditeur
    while (continuer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                continuer = 0;
                break;
            case SDL_MOUSEBUTTONDOWN:
                if (event.button.button == SDL_BUTTON_LEFT)
                {
                    // On met l'objet actuellement choisi (mur, caisse...) à l'endroit du clic
                    carte[event.button.x / TAILLE_BLOC][event.button.y / TAILLE_BLOC] = objetActuel;
                    clicGaucheEnCours = 1; // On active un booléen pour retenir qu'un bouton est enfoncé
                }
                else if (event.button.button == SDL_BUTTON_RIGHT) // Le clic droit sert à effacer
                {
                    carte[event.button.x / TAILLE_BLOC][event.button.y /TAILLE_BLOC] = VIDE;
                    clicDroitEnCours = 1;
                }
                break;
            case SDL_MOUSEBUTTONUP: // On désactive le booléen qui disait qu'un bouton était enfoncé
                if (event.button.button == SDL_BUTTON_LEFT)
                    clicGaucheEnCours = 0;
                else if (event.button.button == SDL_BUTTON_RIGHT)
                    clicDroitEnCours = 0;
                break;
            case SDL_MOUSEMOTION:
                if (clicGaucheEnCours) // Si on déplace la souris et que le bouton gauche de la souris est enfoncé
                {
                    carte[event.motion.x / TAILLE_BLOC][event.motion.y / TAILLE_BLOC] = objetActuel;
                }
                else if (clicDroitEnCours) // Pareil pour le bouton droit de la souris
                {
                    carte[event.motion.x / TAILLE_BLOC][event.motion.y / TAILLE_BLOC] = VIDE;
                }
                break;
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                    case SDLK_ESCAPE:
                        continuer = 0;
                        break;
                    case SDLK_RIGHT:
                        positionSurMap.x++;
                        break;
                    case SDLK_LEFT:
                        positionSurMap.x--;
                        break;
                    case SDLK_s:
                        sauvegarderNiveau(carte);
                        break;
                    case SDLK_c:
                        chargerNiveau(carte);
                        break;
                    case SDLK_1:
                        objetActuel = SOL;
                        break;
                    case SDLK_2:
                        objetActuel = BLOCK;
                        break;
                    case SDLK_3:
                        objetActuel = BLOCKB;
                        break;
                    case SDLK_4:
                        objetActuel = MARIO;
                        break;
                }
                break;
        }
cam.x = positionSurMap.x * TAILLE_BLOC - 800 / 2 ;
    if(cam.x < 0) cam.x = 0;
if(cam.x + cam.w > TAILLE_BLOC * NB_BLOCS_LARGEUR)
cam.x = TAILLE_BLOC * NB_BLOCS_LARGEUR - cam.x;

        // Effacement de l'écran
        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
        posMap.x = positionSurMap.x - cam.x;
        posMap.y = positionSurMap.y;
        SDL_BlitSurface(hhh, NULL, ecran, &posMap);

        // Placement des objets à l'écran
        for (i = 0 ; i < NB_BLOCS_LARGEUR ; i++)
        {
            for (j = 0 ; j < NB_BLOCS_HAUTEUR ; j++)
            {
                position.x = i * TAILLE_BLOC;
                position.y = j * TAILLE_BLOC;
                positionO.x = position.x - cam.x;
                positionO.y = position.y;

                switch(carte[i][j])
                {
                    case SOL:
                        SDL_BlitSurface(sol, NULL, ecran, &positionO);
                        break;
                    case BLOCK:
                        SDL_BlitSurface(block, NULL, ecran, &positionO);
                        break;
                    case BLOCKB:
                        SDL_BlitSurface(blockB, NULL, ecran, &positionO);
                        break;
                    case MARIO:
                        SDL_BlitSurface(mario, NULL, ecran, &positionO);
                        break;

                }
            }
        }

        // Mise à jour de l'écran
        SDL_Flip(ecran);
    }

    SDL_FreeSurface(sol);
    SDL_FreeSurface(block);
    SDL_FreeSurface(blockB);
    SDL_FreeSurface(mario);
}


Merci d'avance pour vos reponse.

Coordialement maxou02
maxou02
Hello World, I'm new !
 
Messages: 7
Inscription: 13 Avr 2008, 22:03

Messagepar Mokona » 14 Avr 2008, 07:47

Hello,

je n'ai pas compilé ton code, je n'ai fait que le parcourir. Visiblement, tu gères bien une caméra et ton scrolling droit/gauche fonctionne au niveau du fond et de l'affichage des blocs.

Par contre, lors de l'ajout et effacement de blocs, tu ne corriges pas les coordonnées de la souris par ton scrolling. Je suppose que si tu scrolles d'un bloc vers la droite et que tu ajoutes un bloc, il va être affiché un bloc plus à gauche que ce qui est demandé.

Les coordonnées de la souris qui te sont envoyées sont par rapport à l'écran. Il faut donc les ajuster en fonction de ta caméra / de ton déplacement.

A noter pour l'étape suivante (c'est-à-dire quand tu auras corrigé ton problème d'édition) : tu affiches tout ton tableau de blocs et tu te reposes sur le clipping de SDL pour n'afficher que ce qui est visible à l'écran.

Si ta largeur de tableau devient grande, cela est beaucoup de temps perdu. En largeur, tu n'as besoin de parcourir que les colonnes susceptibles d'êtres visibles à l'écran.

Autre chose : je ne sais pas trop ce qu'est "hhh", mais cela à l'être d'être un fond d'écran. Si tu utilises une immense image de la largeur de ton terrain, tu risques aussi à un moment d'avoir des soucis (ne serait-ce parce que, techniquement, il y a probablement une largeur maximale, mais aussi pour des soucis de performance). Pense à découper ton fond.
Mokona
Hello World, I'm new !
 
Messages: 1686
Inscription: 13 Mar 2005, 13:00

Messagepar maxou02 » 14 Avr 2008, 10:57

ok donc oui mon probleme est bien que les objets sont placer en decalage sur la gauche.Mais Quand je tente de rajouter au coordonnee de ma souris la cam.x le programme plante quand je clique.Pour hhh c'est juste un petit carré blanc qui me permet de gerer le scrolling car quand je le fesais en passant par la souris arriver au bord de la fenetre il s'arreter
maxou02
Hello World, I'm new !
 
Messages: 7
Inscription: 13 Avr 2008, 22:03

Messagepar Mokona » 14 Avr 2008, 12:27

Il est possible, lorsque tu appliques le décalage à la souris que tu "sortes" du tableau, à cause du scrolling.

Vérifie, après avoir fait l'opération de décalage, que tes nouvelles coordonnées sont toujours dans les bornes de ton tableau. S'ils elles sont en dehors, tu ignores la modification.
Mokona
Hello World, I'm new !
 
Messages: 1686
Inscription: 13 Mar 2005, 13:00

Messagepar maxou02 » 14 Avr 2008, 18:46

Voila enfait j'ai reussi a regler le probleme,Quand je compiler avec code block avec les valeur modifier pour mes coordonner de souris le programme planter quand je cliquer.J'ai essayer de le compiler avec DEV c++ et la sa marche je comprend pu rien peut etre a cause de vista.

Merci pour ton aide

[PS]je ne sait pas comment on met le probleme en resolus dsl
maxou02
Hello World, I'm new !
 
Messages: 7
Inscription: 13 Avr 2008, 22:03

Messagepar Atréides » 14 Avr 2008, 18:52

Je cite ce que Mokona m'a dit sur IRC il y a un peu plus d'une heure :

<Mathias> ah oui, je crois qu'on peut dire que le problème est résolu
<Mokona> Non, le probleme est contourné :p
<Mokona> Car tu ne sais pas "pourquoi"


Maxou, essaie de comparer les réglages de dev-cpp et de c::b, tu y trouveras peut-être une réponse :)
Souvent présent sur #gcn, irc.langochat.net
Site web : seuret . com (programmation, biostatistiques, CP Explo 2/1)
Avatar de l’utilisateur
Atréides
 
Messages: 1349
Inscription: 13 Mar 2005, 13:12
Localisation: Suisse

Messagepar Mokona » 15 Avr 2008, 07:33

Dans un cas de débordement de tableau, il est en effet possible que changer de compilateur (DevCpp et C::B utilisent tous les deux MinGW, mais pas forcément la même version ni avec les mêmes paramètres) fasse disparaître le plantage.

Cela ne signifie absolument pas que le bug a disparu. Cela signifie juste qu'on a poussé un peu la poussière sous le lit et qu'on a déclaré : c'est bon, c'est propre.

Bref, c'est dangereux : il est probable que cela entraîne d'autres soucis par la suite, bien plus difficiles à trouver car entraîné par un bug caché.

Mon conseil est donc, tout comme le fait Mathias, de résoudre le problème avec C::B. De vraiment comprendre le problème, pas de l'ignorer en la cachant.
Mokona
Hello World, I'm new !
 
Messages: 1686
Inscription: 13 Mar 2005, 13:00

Messagepar maxou02 » 15 Avr 2008, 12:29

j'ai donc remi la main a la patte ce matin pour resoudre ce probleme sous code Blocks et je pense avoir reussi a le resoudre car maintenant les objets se place la ou je le souhaite je ne sait pas pourquoi CB ne prenet pas en conte les nouvelle coordonnées de la souris je poste le nouveau code si jamais quelqu'un d'autre as ce probleme qu'il puisse s'y inspirer.
Code: Tout sélectionner
#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

#include "constantes.h"
#include "editeur.h"
#include "fichiers.h"

void editeur(SDL_Surface* ecran)
{
    SDL_Surface *sol = NULL, *block = NULL, *blockB = NULL, *hhh = NULL, *fond = NULL, *mario = NULL;
    SDL_Rect position, posMap, positionSurMap, positionO;
    SDL_Event event;

    int continuer = 1, clicGaucheEnCours = 0, clicDroitEnCours = 0;
    int objetActuel = SOL, i = 0, j = 0;
    int carte[NB_BLOCS_LARGEUR][NB_BLOCS_HAUTEUR] = {0};
    SDL_Rect cam = { 0, 0, 800, 600 };


    // Chargement des objets et du niveau
    hhh = IMG_Load("data//images//others//hhh.JPG");
    sol = IMG_Load("data//images//textures//herbe.BMP");
    block = IMG_Load("data//images//textures//Bricks.GIF");
    blockB = IMG_Load("data//images//textures//bonus2-1.png");
    mario = IMG_Load("data//images//jeu//mario_droite.gif");
    fond = IMG_Load("data//images//backgrounds//1.GIF");



    if (!chargerNiveau(carte))
        exit(EXIT_FAILURE);

    SDL_EnableKeyRepeat(100, 100);

    // Boucle infinie de l'éditeur
    while (continuer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                continuer = 0;
                break;
            case SDL_MOUSEBUTTONDOWN:
                if (event.button.button == SDL_BUTTON_LEFT)
                {
                    event.button.x = event.button.x + cam.x;
                    // On met l'objet actuellement choisi (mur, caisse...) à l'endroit du clic
                    carte[event.button.x / TAILLE_BLOC][event.button.y / TAILLE_BLOC] = objetActuel;
                    clicGaucheEnCours = 1; // On active un booléen pour retenir qu'un bouton est enfoncé
                }
                else if (event.button.button == SDL_BUTTON_RIGHT) // Le clic droit sert à effacer
                {
                    event.button.x = event.button.x + cam.x;
                    carte[event.button.x / TAILLE_BLOC][event.button.y /TAILLE_BLOC] = VIDE;
                    clicDroitEnCours = 1;
                }
                break;
            case SDL_MOUSEBUTTONUP: // On désactive le booléen qui disait qu'un bouton était enfoncé
                if (event.button.button == SDL_BUTTON_LEFT)
                    clicGaucheEnCours = 0;
                else if (event.button.button == SDL_BUTTON_RIGHT)
                    clicDroitEnCours = 0;
                break;
            case SDL_MOUSEMOTION:
                if (clicGaucheEnCours) // Si on déplace la souris et que le bouton gauche de la souris est enfoncé
                {
                    event.motion.x = event.motion.x + cam.x;
                    carte[event.motion.x / TAILLE_BLOC][event.motion.y / TAILLE_BLOC] = objetActuel;
                }
                else if (clicDroitEnCours) // Pareil pour le bouton droit de la souris
                {
                    event.motion.x = event.motion.x - cam.x;
                    carte[event.motion.x / TAILLE_BLOC][event.motion.y / TAILLE_BLOC] = VIDE;
                }
                break;
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                    case SDLK_ESCAPE:
                        continuer = 0;
                        break;
                    case SDLK_RIGHT:
                        positionSurMap.x++;
                        break;
                    case SDLK_LEFT:
                        positionSurMap.x--;
                        break;
                    case SDLK_s:
                        sauvegarderNiveau(carte);
                        break;
                    case SDLK_c:
                        chargerNiveau(carte);
                        break;
                    case SDLK_1:
                        objetActuel = SOL;
                        break;
                    case SDLK_2:
                        objetActuel = BLOCK;
                        break;
                    case SDLK_3:
                        objetActuel = BLOCKB;
                        break;
                    case SDLK_4:
                        objetActuel = MARIO;
                        break;
                }
                break;
        }
cam.x = positionSurMap.x * TAILLE_BLOC - 800 / 2 ;
    if(cam.x < 0) cam.x = 0;
if(cam.x + cam.w > TAILLE_BLOC * NB_BLOCS_LARGEUR)
cam.x = TAILLE_BLOC * NB_BLOCS_LARGEUR - cam.x;

        // Effacement de l'écran
        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
        posMap.x = positionSurMap.x - cam.x;
        posMap.y = positionSurMap.y;
        SDL_BlitSurface(hhh, NULL, ecran, &posMap);

        // Placement des objets à l'écran
        for (i = 0 ; i < NB_BLOCS_LARGEUR ; i++)
        {
            for (j = 0 ; j < NB_BLOCS_HAUTEUR ; j++)
            {
                position.x = i * TAILLE_BLOC;
                position.y = j * TAILLE_BLOC;
                positionO.x = position.x - cam.x;
                positionO.y = position.y;

                switch(carte[i][j])
                {
                    case SOL:
                        SDL_BlitSurface(sol, NULL, ecran, &positionO);
                        break;
                    case BLOCK:
                        SDL_BlitSurface(block, NULL, ecran, &positionO);
                        break;
                    case BLOCKB:
                        SDL_BlitSurface(blockB, NULL, ecran, &positionO);
                        break;
                    case MARIO:
                        SDL_BlitSurface(mario, NULL, ecran, &positionO);
                        break;

                }
            }
        }

        // Mise à jour de l'écran
        SDL_Flip(ecran);
    }
    SDL_EnableKeyRepeat(0, 0);
    SDL_FreeSurface(sol);
    SDL_FreeSurface(block);
    SDL_FreeSurface(blockB);
    SDL_FreeSurface(mario);
}

Merci pour votre aide
maxou02
Hello World, I'm new !
 
Messages: 7
Inscription: 13 Avr 2008, 22:03


Retourner vers Programmation

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 11 invités

cron