Partage
  • Partager sur Facebook
  • Partager sur Twitter

[SFML]Faire des sauts réalistes.

Des aides pour faire des sauts réalistes en 2D ?

Sujet résolu
    27 janvier 2019 à 21:35:00

    Bonsoir, 

    Je viens de commencer la SFML et comme premier jeu j'aimerais faire un bête jeu de plateforme, mais je ne comprends pas comment réussir à faire des sauts réalistes. J'ai à peu près réussi à faire une "gravité" en appliquant toute les millisecondes une valeur (-10) sur mon personnage en Y, mais pour les saut je n'y arrive pas et sur internet je ne trouve rien d'expliquant cela vraiment clairement... quelqu'un pourrait m'aider ? :P 

    Mon code :

    #include <SFML/Graphics.hpp>
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <thread>
    #include <SFML/System/Time.hpp>
    
    using namespace sf;
    
    std::string jeu("[FlappyDoc] ");
    std::string nameGame("Jeu");
    int l(1920), h(1080); //Dimension par défaut de la fenêtre (l = Largeur, h = 1080)
    int jmpH(h / 2);
    int cy((h/2)-50), cx((l/2)-50);
    int var(0), i, j(+10);
    
    #pragma region variables
    sf::RenderWindow w;
    sf::Event e;
    sf::CircleShape cercle;
    sf::CircleShape bullet;
    sf::RectangleShape rect;
    sf::Clock cl;
    sf::Time el1 = cl.getElapsedTime();
    #pragma endregion variables
    
    void collision() {
    	if (cercle.getGlobalBounds().intersects(rect.getGlobalBounds())) {
    		cercle.move(0, -1);
    		var = 1;
    	}
    }
    
    void g() {
    	cl = cl;
    	if(el1.asMilliseconds() == 0 &&  var == 0) {
    			cercle.move(0, +20);
    
    			cl.restart();
    		}
    }
    
    void player() {
    	if (Keyboard::isKeyPressed(Keyboard::Up) && var == 1) {
    
    		cercle.move(0, -10);
    		var = 0;
    	}
    	if (Keyboard::isKeyPressed(Keyboard::Down) && var != 1) {
    		cercle.move(0, +10);
    	}
    	if (Keyboard::isKeyPressed(Keyboard::Left)) {
    		cercle.move(-10, 0);
    	}
    	if (Keyboard::isKeyPressed(Keyboard::Right)) {
    		cercle.move(Vector2f(10, 0));
    	}
    	if (Keyboard::isKeyPressed(Keyboard::RControl)) {
    		w.draw(bullet);
    		bullet.move(+10, 0);
    	}
    }
    
    int main(){
    
    	std::cout << jeu << "Le jeu se lance bien !" << std::endl;
    
    	w.create(VideoMode(l, h), nameGame);
    	w.setFramerateLimit(60);
    
    	//Modifier position fenêtre
    	//window.setPosition(Vector2i(X, Y));
    
    	cercle.setFillColor(Color::Green);
    	cercle.setRadius(50.f);
    	cercle.setPosition(cx, cy);
    	cercle.setOutlineColor(Color::Red);
    	cercle.setOutlineThickness(10.f);
    
    	bullet.setFillColor(Color::White);
    	bullet.setRadius(3.f);
    	bullet.setPosition(cercle.getPosition());
    	
    
    	rect.setFillColor(Color::White);
    	rect.setSize(Vector2f(l, 100));
    	rect.setPosition(0, h - 100);
    
    	while (w.isOpen()) {
    		while (w.pollEvent(e)) { //Place la suite en priorité sur l'event Queue
    			if (e.type == e.KeyPressed && e.key.code == Keyboard::Escape){
    				w.close();
    			}
    			else if (e.type == e.Closed) {
    				w.close();
    			}
    		}
    
    		g();
    		collision();
    
    		player();
    
    		w.draw(cercle);
    		w.draw(rect);
    		w.display();
    		w.clear();
    
    
    		
    	}
    	return 0;
    }
    
    



    -
    Edité par JoLeCactus 27 janvier 2019 à 21:35:39

    • Partager sur Facebook
    • Partager sur Twitter
      28 janvier 2019 à 9:40:52

      Newton, quantité de mouvement, différence entre accélération/vitesse/position, etc...

      Une petite révision des cours de physiques ?

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        28 janvier 2019 à 12:39:27

        bacelar a écrit:

        Newton, quantité de mouvement, différence entre accélération/vitesse/position, etc...

        Une petite révision des cours de physiques ?


        Oui, mais justement, il n'y a pas moyen de simplifier ça ? n'y a t'il pas une fonction pour quelque chose d'aussi utile pour faire des jeux ?

        Et sinon comment on peut formuler ça ? 

        Merci :)

        • Partager sur Facebook
        • Partager sur Twitter
          28 janvier 2019 à 13:41:46

          Salut,

          Malheureusement, si tu veux que ce soit "réaliste", il faut que tu fasse appliquer les règles de la physique "élémentaire".  Plus tu t'éloigneras de ces règles, moins le rendu que tu obtiendra sur ton écran correspondra à ce que tu verrais si quelqu'un sautait à coté de toi :p

          Tu peux simplifier ta logique au point de n'avoir que des sortes de triangle isocèles plus ou moins hauts, plus ou moins larges, voire, des "demis cercles" sous des formes proches de

              *              ***                        ******
             ***           *** ***                   ****    ****
            ** **        ***     ***               ****        *****
            *   *   ou ***         *** ou encore ****             ****

          mais tu ne dois alors pas t'attendre à ce que cela fasse "réaliste".

          • Partager sur Facebook
          • Partager sur Twitter
          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
            28 janvier 2019 à 14:14:09

            koala01 a écrit:

            Salut,

            Malheureusement, si tu veux que ce soit "réaliste", il faut que tu fasse appliquer les règles de la physique "élémentaire".  Plus tu t'éloigneras de ces règles, moins le rendu que tu obtiendra sur ton écran correspondra à ce que tu verrais si quelqu'un sautait à coté de toi :p

            Tu peux simplifier ta logique au point de n'avoir que des sortes de triangle isocèles plus ou moins hauts, plus ou moins larges, voire, des "demis cercles" sous des formes proches de

                *              ***                        ******
               ***           *** ***                   ****    ****
              ** **        ***     ***               ****        *****
              *   *   ou ***         *** ou encore ****             ****

            mais tu ne dois alors pas t'attendre à ce que cela fasse "réaliste".

            Hmmm, mais dans un Mario par exemple.. c'est pas "réaliste" mais la courbe est assez juste, enfin jouable quoi.

            Mais il n'y a pas de fonction qui fait ça ? Une fonction qui permettrait juste que quand un appuie sur un bouton, le personnage saut de x et la courbe se calculerait en fonction des déplacements latéraux du joueurs... ?

            • Partager sur Facebook
            • Partager sur Twitter
              28 janvier 2019 à 14:16:06

              Sauf erreur de ma part SFML est un moteur graphique, pas un moteur de jeu.

              Une des grosses différences entre ces 2 types de moteurs, c'est la présence d'un moteur physique.

              Donc, pour se simplifier la vie, utilises un moteur de jeu ou intègre un moteur physique adapté à ton besoin dans ton programme.

              -
              Edité par bacelar 30 janvier 2019 à 16:19:47

              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                28 janvier 2019 à 14:19:07

                Salut,

                En général, c'est simplifié (mais ça revient au même)

                Dans la structure du sprite tu as :

                x,y : position sprite : vx,vy = vecteur vitesse.  status  (au sol, en saut)

                A chaque frame, tu déplaces le sprite ainsi : 

                x+=vx ; y+=vy

                Si tu as le statut au sol, et que tu appuies sur le saut, alors le status devient "en saut" et vy prend une valeur négative forte.

                et a chaque frame, tu augmentes vy d'une constante... au bout de quelques frames, il devient positif et donc le sprite part dans l'autre sens (redescente du saut).

                • Partager sur Facebook
                • Partager sur Twitter

                Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                  30 janvier 2019 à 15:52:23

                  Salut !

                  La première chose que tu dois faire, c'est chronométrer tes frames (cela permettra de t'assurer que ton jeu tourne de la même façon sur n'importe quel PC). Tu peux utiliser une sf::Clock (ou std::chrono) pour cela.

                  Ensuite, il faut que tu définisse une constante pour la gravité, exprimée en pixel/seconde^2, soit la vitesse que gagnera ton joueur à chaque seconde. Cette vitesse sera donc exprimée en pixels.

                  Puis, à chaque frame, tu devras mettre à jour la position y de ton joueur, en fonction du temps écoulé depuis la dernière frame et de la vitesse de ton joueur.

                  Tu dois donc également stocker la vitesse verticale de ton joueur.

                  Tu auras donc besoin de deux formules :

                  Gain de vitesse = Accélération * Temps écoulé

                  Déplacement = Vitesse * Temps écoulé

                  Et dans ton code ça donnera quelque chose comme ça :

                  velocity += GRAVITY * elapsedTime;
                  position += velocity * elapsedTime;

                  (Tu pourras remplacer la vitesse, la gravité et la position par des vecteurs)

                  Voilà, j’espère t'avoir aidé !

                  N'hésite pas à poser plus de questions si tu n'a pas compris quelque chose :)

                  • Partager sur Facebook
                  • Partager sur Twitter
                    31 janvier 2019 à 13:00:58

                    Raynobrak a écrit:

                    Salut !

                    La première chose que tu dois faire, c'est chronométrer tes frames (cela permettra de t'assurer que ton jeu tourne de la même façon sur n'importe quel PC). Tu peux utiliser une sf::Clock (ou std::chrono) pour cela.

                    Ensuite, il faut que tu définisse une constante pour la gravité, exprimée en pixel/seconde^2, soit la vitesse que gagnera ton joueur à chaque seconde. Cette vitesse sera donc exprimée en pixels.

                    Puis, à chaque frame, tu devras mettre à jour la position y de ton joueur, en fonction du temps écoulé depuis la dernière frame et de la vitesse de ton joueur.

                    Tu dois donc également stocker la vitesse verticale de ton joueur.

                    Tu auras donc besoin de deux formules :

                    Gain de vitesse = Accélération * Temps écoulé

                    Déplacement = Vitesse * Temps écoulé

                    Et dans ton code ça donnera quelque chose comme ça :

                    velocity += GRAVITY * elapsedTime;
                    position += velocity * elapsedTime;

                    (Tu pourras remplacer la vitesse, la gravité et la position par des vecteurs)

                    Voilà, j’espère t'avoir aidé !

                    N'hésite pas à poser plus de questions si tu n'a pas compris quelque chose :)

                    Fvirtman a écrit:

                    Salut,

                    En général, c'est simplifié (mais ça revient au même)

                    Dans la structure du sprite tu as :

                    x,y : position sprite : vx,vy = vecteur vitesse.  status  (au sol, en saut)

                    A chaque frame, tu déplaces le sprite ainsi : 

                    x+=vx ; y+=vy

                    Si tu as le statut au sol, et que tu appuies sur le saut, alors le status devient "en saut" et vy prend une valeur négative forte.

                    et a chaque frame, tu augmentes vy d'une constante... au bout de quelques frames, il devient positif et donc le sprite part dans l'autre sens (redescente du saut).


                    Merci énormément ! ça confirme ce que j'étais entrain de faire !! Merciiii !!


                    • Partager sur Facebook
                    • Partager sur Twitter

                    [SFML]Faire des sauts réalistes.

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown