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

Physique Discussion :

Jeu 2D / gestion de saut d'un personnage


Sujet :

Physique

  1. #1
    Membre à l'essai
    Inscrit en
    Décembre 2006
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut Jeu 2D / gestion de saut d'un personnage
    Salut à tous,

    Alors voila je travaille avec un collègue sur un petit projet d'un jeu de plateforme. Je vous dit tout de suite j'suis pas un crack en développement. Pour le moment on a notre level avec le personnage qui se déplace mais on bute sur le saut. On travaille sur un moteur de jeu basique (pas de SDL, pas d'OpenGL) je pense pas que ce soit nécessaire que je vous détaille le GameEngine. Par contre voici le HandleKey pour le déplacement du personnage avec toutes les erreurs qu'il peut comporter.

    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    void HandleKeys()
    {
    	HWND  hWindow = _pGame->GetWindow();
        HDC   hDC = GetDC(hWindow);
        RECT  rcPos;
     
      if (!_bGameOver && !_bDemo)
      {
        if (GetAsyncKeyState(VK_LEFT) < 0)
        {	
        	_bDirection = FALSE;
        	_pHerosSprite->SetVelocity(-10,0);
        	_pHerosBitmap->Create(hDC, IDB_HEROSGAUCHE, _hInstance);
        	_pHerosSprite->SetNumFrames(6); 
        	_pGame->UpdateSprites();
          // Move left
     
        }
        else if (GetAsyncKeyState(VK_RIGHT) < 0)
        {
        	_bDirection = TRUE;
        	_pHerosSprite->SetVelocity(10,0);
        	_pHerosBitmap->Create(hDC, IDB_HEROSDROITE, _hInstance);
        	_pHerosSprite->SetNumFrames(6);
        	_pGame->UpdateSprites();
          // Move right
     
        }
        else if ((GetAsyncKeyState(VK_UP) < 0) && _bDirection == FALSE)
        {
          _pHerosSprite->SetVelocity(-10,3);
          _pHerosBitmap->Create(hDC, IDB_HEROSSAUTGAUCHE, _hInstance);
          _pHerosSprite->SetNumFrames(6);
          rcPos = _pHerosSprite->GetPosition();
          while(!rcPos.top*2)
          {
          	_pHerosSprite->SetPosition(rcPos.left+2, rcPos.top + 2);
          	//entre chaque affichage monte de 7 px
          	_pHerosSprite->SetVelocity(0, -7);
          	_pGame->AddSprite(_pHerosSprite);
          }
          while(!rcPos.top/2)
          {
          	_pHerosSprite->SetPosition(rcPos.left-2, rcPos.top - 2);
          	//entre chaque affichage le laser 7 px
          	_pHerosSprite->SetVelocity(0, -7);
          	_pGame->AddSprite(_pHerosSprite);
          }
          _pGame->UpdateSprites();
          // Move up
     
        }
        else if (GetAsyncKeyState(VK_UP) < 0 && _bDirection == TRUE)
        {
          _pHerosSprite->SetVelocity(10,3);
          _pHerosBitmap->Create(hDC, IDB_HEROSSAUTDROITE, _hInstance);
          _pHerosSprite->SetNumFrames(6);
          rcPos = _pHerosSprite->GetPosition();
          while(!rcPos.top*2)
          {
          	_pHerosSprite->SetPosition(rcPos.left+2, rcPos.top + 2);
          	//entre chaque affichage le laser monte de 7 px
          	_pHerosSprite->SetVelocity(0, -7);
          	_pGame->AddSprite(_pHerosSprite);
          }
          while(!rcPos.top/2)
          {
          	_pHerosSprite->SetPosition(rcPos.left-2, rcPos.top - 2);
          	//entre chaque affichage le laser monte de 7 px
          	_pHerosSprite->SetVelocity(0, -7);
          	_pGame->AddSprite(_pHerosSprite);
          }
          _pGame->UpdateSprites();
          // Move down
     
        }
        else if(_bDirection == FALSE)
        {	
        	_pHerosSprite->SetVelocity(0,0);
        	_pHerosBitmap->Create(hDC,IDB_HEROSSTOPGAUCHE, _hInstance);
        	_pHerosSprite->SetNumFrames(1);
        	_pGame->UpdateSprites();
        }
     
        else if(_bDirection == TRUE)
        {	
        	_pHerosSprite->SetVelocity(0,0);
        	_pHerosBitmap->Create(hDC,IDB_HEROSSTOPDROITE, _hInstance);
        	_pHerosSprite->SetNumFrames(1);
        	_pGame->UpdateSprites();
        }
     
     
      }
     
      // Start a new game based upon an Enter (Return) key press
      if (GetAsyncKeyState(VK_RETURN) < 0)
        if (_bDemo)
        {
          // Switch out of demo mode to start a new game
          _bDemo = FALSE;
          NewGame();
        }
        else if (_bGameOver)
        {
          // Start a new game
          NewGame();
        }
     
    }
    Pour le moment quand on appuis sur la touche haut (pour le saut), il génère bien le sprite de saut mais au lieu de sauter vers le haut et de retrouver sa position initiale il va juste vers le bas. Merci de bien vouloir m'aider à ce sujet, a bientôt.

  2. #2
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     rcPos = _pHerosSprite->GetPosition();
     while(!rcPos.top*2) {
          _pHerosSprite->SetPosition(rcPos.left+2, rcPos.top + 2);
          ...
    Bizarre le test dans le while. Ca serait pas plutot un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     rcPos = _pHerosSprite->GetPosition();
     rcPosTopmost = 2*rcPos.top;
     while( rcPos.top < rcPosTopmost) {
          _pHerosSprite->SetPosition(rcPos.left+2, rcPos.top + 2);
          ...
    et idem pour les autres while() ?
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  3. #3
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 524
    Points : 5 184
    Points
    5 184
    Par défaut
    est-ce que ton origine, le point y = 0, est en haut ou en bas ? (de ton affichage)
    s'il est en haut (ce que je pense), il faut décrémenter ton rcPos.top pour faire monter ton sprite
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  4. #4
    Membre à l'essai
    Inscrit en
    Décembre 2006
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    y=0 est en haut.

    Citation Envoyé par pseudocode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     rcPos = _pHerosSprite->GetPosition();
     while(!rcPos.top*2) {
          _pHerosSprite->SetPosition(rcPos.left+2, rcPos.top + 2);
          ...
    Bizarre le test dans le while. Ca serait pas plutot un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     rcPos = _pHerosSprite->GetPosition();
     rcPosTopmost = 2*rcPos.top;
     while( rcPos.top < rcPosTopmost) {
          _pHerosSprite->SetPosition(rcPos.left+2, rcPos.top + 2);
          ...
    et idem pour les autres while() ?
    en fait vu que c'est un traitement par message a chaque fois que tu appuye sur une touche il deroule tout le code alors si tu fait un while 10 fois dedans tu va apuyer sur la touche 1 fois et il va derouler 10 fois se code sans tenir compte du reste des sprite et autre dc c pas possible

    fodrait géré ca avec un if!

  5. #5
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par scarface56
    y=0 est en haut.



    en fait vu que c'est un traitement par message a chaque fois que tu appuye sur une touche il deroule tout le code alors si tu fait un while 10 fois dedans tu va apuyer sur la touche 1 fois et il va derouler 10 fois se code sans tenir compte du reste des sprite et autre dc c pas possible

    fodrait géré ca avec un if!
    N'empeche que la clause du while est étrange...

    while(xxxx) {...} execute le contenu du block tant que xxxx est different de FALSE (c-a-d different de 0).

    Donc dans ton cas, tant que !rcPos.top*2 est different de 0.
    Ca me semble louche
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  6. #6
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 524
    Points : 5 184
    Points
    5 184
    Par défaut
    c'est vrai que le while fait que tu boucles pour monter ton sprite, sans réactualiser l'affichage
    même si tu remplaces bêtement le while par un if ça doit aller mieux, sauf que si l'animation est trop rapide tu verras pas la différence
    il faudrait donc que tu gères ton animation en fonction du temps à l'aide de la fonction win32 GetTicksCount
    seulement dans tout ça, je pense que ta méthode n'est pas appropriée

    en gros, lorsque tu appuies sur une touche, tu met une variable à une valeur correspondant à l'animation à effecteur :
    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
    int mouvement = aucun;
    if(mouvement == aucun)
    {
       switch(touche appuyée)
       {
          case VK_LEFT:
             mouvement = gauche;
             break;
          case VK_RIGHT:
             mouvement = droite;
             break;
          case VK_UP:
             mouvement = saut;
             break;
    }
    et dans une autre boucle tu gères l'animation
    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
     
    DWORD temps_passé = GetTicksCount() - temps_précédent;
    if(temps_passé < délai_minimum)
       return; // pas d'animation, limitation de la vitesse
    switch(mouvement)
    {
       case droite:
          déplacer le sprite à droite;
          if(déplacement terminé)
             mouvement = aucun;
          break;
       case gauche:
          déplacer le sprite à gauche;
          if(déplacement terminé)
             mouvement = aucun;
          break;
       case saut:
          modifier la position du sprite pour l'effet de saut;
          if(saut terminé)
              mouvement = aucun;
          break;
    }
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  7. #7
    Membre à l'essai
    Inscrit en
    Décembre 2006
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    Bon ben pour le saut j'crois qu'on est finalement parti sur quelque chose qui devrait marcher.

    Une autre interrogation critique porte sur un problème de collision qui se pose au niveau des plateforme. Car il faudrait tout simplement que le héros puise retomber à sa surface sans qu'il se retrouve les pied ancré sur la plateforme complètement immobilisé.

  8. #8
    Membre actif Avatar de ironzorg
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 288
    Points : 245
    Points
    245
    Par défaut
    J'ais eu les memes problèmes jadis ( c'était du temps où je programmais un jeu de plateforme genre Mario )...
    Cette méthode est très chi...te à mettre en place mais vu que mon jeu ne pesait vraiment rien niveau obstacles , je m'y suis mit : ( je n'ais pas mis les boucles d'évènements et l'initialisation de SDL etc ... )
    int NUL = 0, MONTE = 1, DESCEND = 3;
    int SAUT = NUL;
    if (posPlayer.x > 70 ) && (posPlayer.y > 102)) // coordonnées des espaces //de vide
    {
    SAUT = DESCEND;
    }
    while(SAUT == DESCEND)
    {
    posPlayer.y++;
    }
    Tu vois comment ça marche ? Le gros inconvénient c'est que si ton niveau est grand et chargé de décors , tu en as pour ... environ 1H rien pour déterminer les coordonnées des espaces vides.

  9. #9
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 381
    Points
    20 381
    Par défaut
    Citation Envoyé par ironzorg
    J'ais eu les memes problèmes jadis ( c'était du temps où je programmais un jeu de plateforme genre Mario )...

    if (posPlayer.x > 70 ) && (posPlayer.y > 102)) // coordonnées des espaces //de vide
    {
    SAUT = DESCEND;
    }


    Tu vois comment ça marche ? Le gros inconvénient c'est que si ton niveau est grand et chargé de décors , tu en as pour ... environ 1H rien pour déterminer les coordonnées des espaces vides.
    Non c'est pas bon tu est confronté à des problèmes comme tu dis..
    Que se passe-t-il si des éléments du décors ont un y<102 ???
    La solution c'est de soit mémoriser les éléments du décor susceptibles de provoquer des collisions dans une liste ( avec std::vector) soit un tableau fixe.
    Ou bien on peut prendre la méthode de détection de pixel , si à une cordonnée particulière du perso la couleur de fond est différente d'une certaine valeur alors collision

  10. #10
    Membre actif Avatar de ironzorg
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 288
    Points : 245
    Points
    245
    Par défaut
    Citation:
    ironzorg a écrit :
    J'ais eu les memes problèmes jadis ( c'était du temps où je programmais un jeu de plateforme genre Mario )...

    if (posPlayer.x > 70 ) && (posPlayer.y > 102)) // coordonnées des espaces //de vide
    {
    SAUT = DESCEND;
    }


    Tu vois comment ça marche ? Le gros inconvénient c'est que si ton niveau est grand et chargé de décors , tu en as pour ... environ 1H rien pour déterminer les coordonnées des espaces vides.

    Non c'est pas bon tu est confronté à des problèmes comme tu dis..
    Que se passe-t-il si des éléments du décors ont un y<102 ???
    La solution c'est de soit mémoriser les éléments du décor susceptibles de provoquer des collisions dans une liste ( avec std::vector) soit un tableau fixe.
    Ou bien on peut prendre la méthode de détection de pixel , si à une cordonnée particulière du perso la couleur de fond est différente d'une certaine valeur alors collision
    Euh... OK en fait dans le jeu que j'ais programmé , le but n'était pas de traverser les niveaux avec divers obstacles " suspendus en l'air" mais mon perso était lancé a toute vitesse et devait sauter par dessus des obstacles au niveau du sol...

Discussions similaires

  1. probleme de saut d'un personnage pour un jeu
    Par mystif68 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 1
    Dernier message: 04/09/2007, 09h58
  2. [SDL] Gestion des sauts
    Par Splinter_7 dans le forum Développement 2D, 3D et Jeux
    Réponses: 4
    Dernier message: 02/05/2007, 19h29
  3. [10] Gestion du saut de page sur imprimantes à aiguilles
    Par cramto dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 02/04/2007, 22h52
  4. Jeu de gestion en java
    Par luckyvae dans le forum Développement 2D, 3D et Jeux
    Réponses: 6
    Dernier message: 27/08/2006, 18h19
  5. Saut d'un personnage
    Par Hyoga dans le forum OpenGL
    Réponses: 2
    Dernier message: 08/02/2005, 10h19

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