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

Bibliothèques C++ Discussion :

[SFML]Projectile 2D, aide calcul.


Sujet :

Bibliothèques C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Points : 28
    Points
    28
    Par défaut [SFML]Projectile 2D, aide calcul.
    Bonjour,
    je suis en train de programmez un jeu de style "Tower defense" en C++ avec SFML.

    J'ai déjà fais la création des tours et leur collision(pour ne pas créé une tour par-dessus une autre),le chargement des maps a partir d'une image .bmp pouvant contenir des "Scenery"(avec couleur de transparence modifiable par un fichier texte) en 3 résolutions différente,les tours peuvent pointer en direction d'une cible et avoir un ordre de priorité.

    Mais tout ca ne sert pas a grand chose si on a même pas la base du jeu...Le tire.
    En fait j'aimerais savoir comment calculer la trajectoire d'un simple projectile(2D bien sur) en ligne droite selon l'angle d'une tour.

    Certains vont probablement me reprocher ne pas assez avoir chercher et d'aller voir sur google,mais c'est ce que j'ai fais,et j'ai trouver moins de réponse que je ne l'espérais.

    Vous voyez,je n'ai que 16 ans,et moi et les maths...Je suis pas très bon.
    (En fait,je suis en secondaire 4 selon le systeme d'éducation Québécois)

    Mais bon merci beaucoup d'avoir lue et encore plus si vous pouvez m'aider a trouver comment calculer ca(bien sur me l'expliquer).

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Bonjour,

    Avant toute chose, sur quelle plateforme travailles-tu, avec quelles bibliothèques et quel système d'exploitation ?

    Citation Envoyé par Itachi_93 Voir le message
    Mais tout ca ne sert pas a grand chose si on a même pas la base du jeu...Le tire. En fait j'aimerais savoir comment calculer la trajectoire d'un simple projectile(2D bien sur) en ligne droite selon l'angle d'une tour [...] Vous voyez,je n'ai que 16 ans,et moi et les maths...Je suis pas très bon. (En fait,je suis en secondaire 4 selon le systeme d'éducation Québécois)
    Ça dépend beaucoup de ce que tu entends par « l'angle de la tour » mais s'il s'agit simplement d'un azimut de 0 à 360° par rapport au nord (ou plutôt à l'est, dans notre cas), alors il suffit de récupérer dans deux float ou double les valeurs de sin(a) et cos(a) (« a » étant ton angle).

    Tu places ensuite le projectile aux coordonnées de la tour puis, étape par étape, tu ajoutes à l'abscisse et à l'ordonnée les valeurs de cos(a) et sin(a), respectivement. Celles-là mêmes que tu as récupérées juste avant. Tu peux également multiplier ces valeurs d'un facteur x si tu veux faire accélérer ton projectile.

    Attention toutefois : ton angle devra être précisé en radians à tes fonctions. Pour convertir tes degrés en radians, tu peux les multiplier par 2𝜋 et les diviser ensuite par 360. Tout cela en virgule flottante, bien sûr.

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Dans un cas plus avancée, nous utilisons des vecteurs ( à deux dimensions pour votre cas ).
    Un vecteur, n'est juste qu'une classe ( structure ) qui contient un x, un y, et qui a tous les operateurs de surcharger pour travaillé facilement ( et avec quelques autre fonctions utiles tels que la normalisation et la distance ).

    Pour l'évolution du projectile, c'est la formule suivante ( version très simple )
    position = position + direction * vitesse.
    (Avec nos supers vecteurs, on peut écrire le code tel quel )
    A chaque tour dans la boucle, on effectue le calcul, et ça marche tout seul.

    Maintenant, l'angle ( qui détermine la direction ). Comme l'a très bien expliqué Obsidian, on utilisera un angle en degrée, qui va déterminer direction.

    Cela peut être:
    direction.x = cos(angle);
    direction.y = sin(angle);
    Voilà,

    Si vous avez plus de question, n'hésitez pas
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    (Au fait,oui je suis avec une vue du dessus)

    Merci,mais j'ai encore quelques petit problème.

    Mon projectile ne va que dans la bonne direction que s'il y a zéro d'angle.
    Et en plus,si l'angle n'est pas de zéro,la position initial change.

    J'ai créé un vecteur(std::vector) d'allocation dynamique comme avec mes tours.

    Au début je voulais implémenter le vecteur dans ma class tour,mais je ne voulais pas que lorsque l'on détruit une tour tous ses projectile disparaisse en même temps(il faut quand même un peu de réaliste).

    Ce n'est qu'une version test du programme alors j'ai fait ça dans le main(plus tard je ferais une class HUDJoueur).

    J'ai fais une fonction qui dit si le projectile est en dehors de la map,c'est un problème principale.Lors de la création du projectile,j'envoie et enregistre la largeur et la hauteur de la fenêtre.

    Voila le code pour donner une idée :
    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
    #include "Bullet.h"
     
    using namespace std;
    using namespace sf;
     
    Bullet::Bullet(float Initial_X, float Initial_Y, float angle, RenderWindow *APP)
    {
        vitesse=10;
        BulletPosition.x=Initial_X;
        BulletPosition.y=Initial_Y;
        BulletSprite=Shape::Circle(BulletPosition.x,BulletPosition.y,5,Color::Black);
        BulletSprite.SetCenter(BulletSprite.GetScale().x/2,BulletSprite.GetScale().y/2);
        BulletSprite.SetRotation(angle);
        WinWidth=APP->GetWidth();
        WinHeight=APP->GetHeight();
    }
    //Shape Circle = Shape::Circle(X, Y, Rayon, Couleur, [Bordure], [CouleurBordure]);
     
    void Bullet::UpdatePosition()
    {
        vx=cos(BulletSprite.GetRotation()*M_PI/180) * vitesse;
     vy=sin(BulletSprite.GetRotation()*M_PI/180) * vitesse;
     
        BulletSprite.Move(vx,vy);
     
    }
     
    bool Bullet::CIO()//CheckIfOut
    {
     
     if(static_cast<unsigned int>(BulletPosition.x) < 0 && 
    static_cast<unsigned int>(BulletPosition.x) > WinWidth &&
    static_cast<unsigned int>(BulletPosition.y) < 0 &&
    static_cast<unsigned int>(BulletPosition.Y) >WinHeight)
     {
         cout<<"Bullet out of map"<<endl;
    return true;
     
     }
     else
     {
     
      return false;
     
     }
    }
     
    Shape Bullet::GetBulletSprite() const
    {
     return BulletSprite;
    }
     
    Bullet::~Bullet()
    {
     
    }
    et le Header :
    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
    #ifndef BULLET_H_INCLUDED
    #define BULLET_H_INCLUDED
     
    #include <iostream>
    #include <cstdio>
    #include <math.h>
     
     
    #include <SFML/System.hpp>
    #include <SFML/Window.hpp>
    #include <SFML/Graphics.hpp>
     
    class Bullet
    {
           public :
     
    Bullet(float Initial_X, float Initial_Y, float angle, sf::RenderWindow *APP);
    void UpdatePosition();
    bool CIO();
    sf::Shape GetBulletSprite() const;
    ~Bullet();
     
        private :
    int vitesse;
    float vx,vy;
    sf::Vector2f BulletPosition;
    sf::Shape BulletSprite;
    unsigned int WinWidth,WinHeight;
    };
     
     
    #endif // BULLET_H_INCLUDED
    Et là ou tout se joue dans le main :
    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
     
    if (havetower==true)
            {
                for (unsigned int n=0;n<tour1.size();n++)
                {
                    tour1.at(n)->LockTarget(App.GetInput().GetMouseY(),App.GetInput().GetMouseX());
                    if (tour1.at(n)->shooting()==true)
                    {
                        AllBullet.push_back(new Bullet(tour1.at(n)->X,tour1.at(n)->Y,tour1.at(n)->GetAngle(),&App));
                   cout<<AllBullet.size()<<" projectile"<<endl;
                    }
    //etc,etc
     
    //Plus loin
     
    if (AllBullet.size()>0)
            {
                for (int NoBullet=0;NoBullet<AllBullet.size();NoBullet++)
                {
     
                    if (AllBullet.at(NoBullet)->CIO()==false)
                    {
                        AllBullet.at(NoBullet)->UpdatePosition();
                        App.Draw(AllBullet.at(NoBullet)->GetBulletSprite());
                    }
                    else if(AllBullet.at(NoBullet)->CIO()==true)
                    {
                        AllBullet.at(NoBullet)->~Bullet();
                         AllBullet.erase(AllBullet.begin() + NoBullet);
                         cout<<AllBullet.size()<<" projectile"<<endl;
                    }
                }
            }
    Ah oui,j'ai fais un "Fire Rate" et il marche bien.

  5. #5
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Je dirai que pour votre problème d'angle, cela peut venir de cette fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    BulletSprite.GetRotation()
    Sinon, pour éliminer tout les projectiles qu'a lancé une tour, lors de sa destruction, il faut avoir une liste de projectile dans la classe de la tour. ( Par pointeurs ou pas ). Il faut savoir qu'il est possible de penser le problème un peu autrement, et de dire, la tour gère les projectiles ( donc dans l'update de la tour, on update tout ces projectiles ). Du coup les projectiles sont seulement visible par leurs tours.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    En fait je ne veux pas supprimer les projectile une fois qu'une tour est détruite,mais juste une fois qu'ils quittent l'écran(libéré la mémoire de mon vector).On dirait que la condition pour vérifier si le projectile est en dehors de la fenêtre ne s'applique pas..Pour l'affichage ça va.

    Ce que je trouve le plus étrange,c'est que la position initial change,c'est la première position que le projectile prend.Je lui envoie dans le constructeur la position de la tour qui fait feu.

    float Initial_X, float Initial_Y

    Après en principe,le projectile ne fait que "mové" dans la bonne direction(donner par cos et sin) fois la vitesse.En tout cas c'est comme ça que j'imaginais faire mon code.
    Mais bon,si l'angle de la tour n'est pas de zéro,la position d'où par les projectile n'est pas du tout au bon endroit,bien loin de la position de la tour qui fait feu.
    tour1.at(n)->X,tour1.at(n)->Y

    Bizar non?Ça viens peut-être de la classe Tour,je vais vérifier.

  7. #7
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Ta condition pour savoir si le projectile est hors de l'écran est fausse. Il faut utiliser "ou" (||) et pas "et" (&&).

    Edit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AllBullet.at(NoBullet)->~Bullet();
    ... c'est pas terrible car tu détruis bien l'objet mais tu ne libère pas la mémoire. Écris plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    delete AllBullet.at(NoBullet);
    Et puis tu ferais peut être mieux de stoquer une fois pour toute ton projectile dans une variable, ça sera plus simple à lire et plus performant :
    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
    for (int NoBullet=0;NoBullet<AllBullet.size();NoBullet++)
    {
        Bullet* bullet = AllBullet.at(NoBullet);
        if (bullet->CIO()==false)
        {
            bullet->UpdatePosition();
            App.Draw(bullet->GetBulletSprite());
        }
        else if(bullet->CIO()==true)
        {
            delete bullet;
            AllBullet.erase(AllBullet.begin() + NoBullet);
            cout<<AllBullet.size()<<" projectile"<<endl;
        }
    }
    ... ou, encore mieux, utiliser un intérateur :
    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
    vector<Bullet*>::iterator iterBullet;
    for (iterBullet = AllBullet.begin(); iterBullet != AllBullet.end(); ++iterBullet)
    {
        Bullet* bullet = *iterBullet;
        if (!bullet->CIO())
        {
            bullet->UpdatePosition();
            App.Draw(bullet->GetBulletSprite());
        }
        else
        {
            delete bullet;
     
            // Attention ici : on supprime un élément du conteneur alors
            // qu'on fait une itération dessus.
            // D'après la doc de std::vector :
            //     "inserting or deleting an element in the middle of a vector
            //      invalidates all iterators that point to elements following
            //      the insertion or deletion point"
            iterBullet = AllBullet.erase(iterBullet);
     
            cout<<AllBullet.size()<<" projectile"<<endl;
        }
    }

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    Merci beaucoup,mon problème est résolu.Je sais maintenant comment calculer ce genre de chose et mes autre problèmes sont régler(en fait,j'ai changer la sf::Shape par une sf::Image et ça a tout régler).

    Il me suffisait de mettre un y négatif.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       vx=cos(BulletSprite.GetRotation()*M_PI/180) * vitesse;
     vy=sin(BulletSprite.GetRotation()*M_PI/180) * vitesse;
     
        BulletSprite.Move(vx,-vy);
    Pour ce qui est de la mémoire tout semble bien se passer,ma mémoire doit bien se libérer,je le vois avec le gestionnaire des taches.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vector<Tour*> tour1;
        vector<Bullet*> AllBullet;
    Au fait je travail avec Windows XP(SP3) et Linux Ubuntu 9.10.

  9. #9
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Profitez de votre linux et installer le meilleur outil du monde:
    valgrind

    Ceci est un outil qui analyse la mémoire en profondeur. Il n'y a rien de mieux pour voir les débordements de tableau ( qui cause bien souvent les erreurs de segmentations ) mais aussi pour voir les fuites de mémoire.

    Je vous le conseille plus que vivement.

    ( Sinon, il existe aussi quelques astuces pour Visual Studio, pour pouvoir voir les fuites, mais c'est du code spécial )
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Points : 28
    Points
    28
    Par défaut
    Merci(de toute façon avec mon internet basse vitesse de 4Ko/sec ça va me prendre 20h le télécharger et pas de pause pour téléphoner).

    Je croyais que la réponse a la vie était 42...

  11. #11
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Merci(de toute façon avec mon internet basse vitesse de 4Ko/sec ça va me prendre 20h le télécharger et pas de pause pour téléphoner).

    Je croyais que la réponse a la vie était 42...
    Euh, en france j'ai du internet plus lent ( 3ko/s ) ( heureux que je ne soit pas souvent chez moi )

    Et la réponse à la vie est 42 ( d'après la source originale ), par contre, peut être que je réponds pour une autre vie :p.

    Malgré votre lente connexion je vous conseille tout de même d'avoir valgrind ( ou du moins de récupéré le paquet à partir d'une autre connexion )
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Besoin d'aide calcul de champs
    Par bouligoulag dans le forum Langage SQL
    Réponses: 3
    Dernier message: 21/05/2012, 18h22
  2. [XL-2003] Aide calcul de stock en VBA
    Par Nishruu05 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 09/05/2011, 14h59
  3. besoin d'aide calcul de date
    Par Missteigne dans le forum Access
    Réponses: 15
    Dernier message: 06/11/2010, 19h12
  4. aide calcul relationnel
    Par gentelmand dans le forum SQL
    Réponses: 3
    Dernier message: 28/04/2010, 12h56
  5. [AIDE] Calcul dans un tableau (JSP+Struts)
    Par Diablo_22 dans le forum Servlets/JSP
    Réponses: 9
    Dernier message: 07/11/2008, 14h40

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