Pages: [1]   Bas de page
Imprimer
Auteur Fil de discussion: [C++] Diverses question à propos d'un shoot  (Lu 2111 fois)
0 Membres et 1 Invité sur ce fil de discussion.
Reyhn Hors ligne
Jr. Member
**
Messages: 94


Voir le profil
« 02 Avril 2011, 21:32:29 »

Salut,

je me suis lancé dans la réalisation d'un début de petit shoot (oui oui on commence doucement  whistle ), et je risque d'avoir quelques questions à vous soumettre; en voici déjà une.

J'ai une classe Ship qui représente des vaisseaux du jeu.
Chaque instance de Ship a un pointeur vers un objet MovePattern (patron de déplacement donc), qui consiste simplement en une liste de points (x,y) auquel le Ship doit se rendre et quelques methodes.

J'ai aussi une classe EnnemyManager qui me permet de gérer une liste d'ennemis (Ship) plus facilement,  qui les bouge tous à leurs positions respectives et les affiche dans ma fenetre principale (j'utilise SFML).

A chaque tour de boucle, l'EnnemyManager va faire bouger chaque ennemi de sa liste vers le prochain point de son pattern, et l'afficher. Seulement, je ne vois pas comment savoir lorsque l'ennemi sera arrivé au point voulu pour passer au suivant.
J'avais pensé à garder en mémoire dans quel sens de déplacement doit aller l'ennemi (haut/bas et droite/gauche) puis à faire les comparaisons qui vont bien (< ou >) avec les coordonnées du point, seulement ça me parait un peu naïf et je me demandais s'il n'y avait pas plus simple.

Des avis ? (je pense notamment à valryon qui m'a mis sur la piste par MP Langue)
Journalisée
morukutsu Hors ligne
Sr. Member
****
Messages: 499


Voir le profil
Noctambule

« Réponse #1 : 02 Avril 2011, 23:10:59 »

Comme ça, je dirais que tu pourrais tenter une interpolation linéaire entre deux points, ainsi, quand ton facteur d'interpolation passe à 1, c'est que tu as fini le déplacement vers le point suivant.
Reste ensuite un problème, garder une vitesse indépendante de la distance entre deux points.
Journalisée
Valryon Hors ligne
Sr. Member
****
Messages: 331


Voir le profil WWW
The World ends with you !

« Réponse #2 : 03 Avril 2011, 10:19:06 »

Salut,

Il te manquera peut-être une notion de vitesse ou de temps (mais cela revient au même) entre deux points, pour permettre des patterns complexes.

En gros il faudra que tu puisses indiquer le temps que le vaisseau met à aller du point A au point B.

Sinon pour ta liste de points, tu ne peux pas parcourir un bête tableau ?
pattern = [PointA, PointB, PointC, etc]

Tu commences à 0, et quand tu atteint un point tu attaques l'indice suivant. Reste le problème de savoir quand tu atteints un point : tu peux définir une petite zone de quelques pixels pour chaque point, et tu testes la collision de cette zone avec ton vaisseau.

Enfin concernant la direction, tu peux résoudre cela facilement avec un peu de maths. En gros en prenant deux vecteurs [PositionVaisseau, PointA] et [PointA, PointB] tu peux obtenir l'angle entre ces deux vecteurs.

Ensuite tu appliques cet angle au vecteur de déplacement de ton vaisseau (x +-= x * cos(angle) et y +-= y* sin(angle) mais je ne saurai te dire où sont les + et les -) celui-ci va se diriger vers le prochain point.

Mon message est pas forcément très clair donc :
- Pattern = liste ou tableau de points donc peux facilement avoir l'élément suivant de l'élément courant
- Détecter collision avec point de pattern
- Changement de direction = angle entre deux vecteurs
Journalisée

Développeur professionnel et passionné de jeu vidéo, auteur de The Great Paper Adventure (PC/X360) :
-> http://www.thegreatpaperadventure.com
Reyhn Hors ligne
Jr. Member
**
Messages: 94


Voir le profil
« Réponse #3 : 03 Avril 2011, 10:42:26 »

Au départ, j'avais pour chaque point un nombre de frames (temps donc) à parcourir pour y arriver, et ça marchait plutôt bien. Mais j'ai voulu m'en passer parce que :

Imaginons que je charge depuis un fichier tous les ennemis du niveau, ainsi que leur patterns respectifs, et que j'aie par exemple 5 vaisseaux qui vont parcourir le même chemin mais les uns à la suite des autres. Dans ce cas là je leur met le même pattern en ajoutant par exemple 64 et 64 aux coordonnées de départ de chaque vaisseau. Mais vu qu'ils ont le même nombre de frames pour aller à chaque point, ils vont atteindre le premier en même temps et se superposer.
Mais en fait, il suffirait de modifier la contrainte de temps pour chaque point du pattern (j''espere que je suis clair moi aussi  Cheesy) avant de l'attribuer au vaisseau suivant, pour qu'ils gardent un ecart.

@morukutsu: en gros ça consiste à faire une approximation d'une fonction d'après quelques points ? je regarderais ça en détail d'ici peu.
Journalisée
PypeBros Hors ligne
Hero Member
*****
Messages: 707


Voir le profil WWW
Posez-vous les bonnes questions

« Réponse #4 : 05 Avril 2011, 13:49:58 »

Sinon, la crème de la crème, pour ce genre de choses, ce sont les courbes de Bézier, bien sûr ...
Journalisée

smealum Hors ligne
Administrateur
*****
Messages: 661


Voir le profil WWW
« Réponse #5 : 05 Avril 2011, 17:14:12 »

Sinon, la crème de la crème, pour ce genre de choses, ce sont les courbes de Bézier, bien sûr ...
Et c'est pas si compliqué à implémenter !
Journalisée

Zipler Hors ligne
Full Member
***
Messages: 106


Voir le profil
« Réponse #6 : 28 Août 2011, 09:10:52 »

Je viens de remarquer ce topic et il m'a donné envie d'implémenter les courbes de bézier.
Donc je le met, au cas où ça serve à quelqu'un d'autre:
Code: (cpp)
Vector3 FollowBezierCurve( const Vector3* controlPoints, unsigned numPoints, float lambda )
{
    float s = (1.0f - lambda);
    float d = lambda;

    Vector3 ret;
    Vector3* shadow = new Vector3[ numPoints ];
    memcpy( shadow, controlPoints, sizeof(Vector3) * numPoints );

    while( numPoints > 1 )
    {
        for( int i = 0; i < numPoints - 1; i++ )
            shadow[i] = s * shadow[i] + d * shadow[i+1];
        numPoints--;
    }

    ret = shadow[0];
    delete[] shadow;
    return ret;
}

Je laisse au lecteur faire l'effort de comprendre le code s'il en a besoin.

Question personnelle:
Quelqu'un aurait-il un truc direct pour calculer les coeffs de chaque point et ainsi éviter la double boucle? Juste pour le fun Azn.
Journalisée
PypeBros Hors ligne
Hero Member
*****
Messages: 707


Voir le profil WWW
Posez-vous les bonnes questions

« Réponse #7 : 07 Septembre 2011, 12:43:47 »

Citation
Question personnelle:
Quelqu'un aurait-il un truc direct pour calculer les coeffs de chaque point et ainsi éviter la double boucle? Juste pour le fun Azn.
tu veux dire comme ça ?

Sinon, pour ton code, quand on a un new en début de procédure et un delete en fin de procédure, c'est qu'on peut utiliser un objet alloué sur la pile.
Journalisée

Tiwaz Hors ligne
Full Member
***
Messages: 125


Voir le profil
« Réponse #8 : 17 Septembre 2011, 19:01:46 »

Je me permet de répondre, en particulier au sujet du "comme ça", avec le lien. Il me semble qu'une implémentation récursive est moins bonne qu'une implémentation linéaire.

De plus, je ne reste pas très d'accord pour le "new" et le "delete", la pile ayant toujours une taille limité, si tu travailles sur DS, il est parfaitement possible de déborder, et il faut alors mieux piocher ailleurs. Les bugs seront plus simple à trouver (un new qui échoue) qu'un écrasement de pile qui a un comportement plus... curieux.
Journalisée

"Le jeu est la forme la plus élevée d'apprentissage"
PypeBros Hors ligne
Hero Member
*****
Messages: 707


Voir le profil WWW
Posez-vous les bonnes questions

« Réponse #9 : 26 Septembre 2011, 13:19:10 »

Je me permet de répondre, en particulier au sujet du "comme ça", avec le lien. Il me semble qu'une implémentation récursive est moins bonne qu'une implémentation linéaire.
Pas faux. J'ai du lire trop vite le code posté par zipler... je pensais qu'il devait balayer lambda dans une des boucles.

Citation
De plus, je ne reste pas très d'accord pour le "new" et le "delete", la pile ayant toujours une taille limitée, si tu travailles sur DS, il est parfaitement possible de déborder, et il faut alors mieux piocher ailleurs.
oui, bon, d'un autre côté, il n'y a généralement pas des dizaines de points de contrôles dans une bézier. Allouer/désallouer à chaque calcul peut conduire à de sérieux handicaps de performances.

[quote Les bugs seront plus simple à trouver (un new qui échoue) qu'un écrasement de pile qui a un comportement plus... curieux.[/quote]
J'avoue qu'un buffer overflow à l'intérieur de la pile, c'est pas joli-joli à voir. D'un autre côté, quand on fout le memory manager en l'air, le "new qui échoue" est rarement celui qui pose problème: ça peut être n'importe quel new qui suit un delete foireux. Mais bon, c'est clair qu'on entre dans des considérations de "préférences en terme de debugging", là.
Journalisée

Pages: [1]   Haut de page
Imprimer

Aller à: