algo deplacements

algo deplacements - Programmation

Marsh Posté le 31-08-2002 à 14:58:59    

voila ds mon jeu lorsque je veux deplacer la camera(3d) je fais comme ca  
 
    X = X + sin(rota*pi/180)*FrameTime;
    Z = Z - cos(rota*pi/180)*FrameTime;
 
ou frametime est le nb millisecondes ecoulees depuis la derniere frame comme ca le perso avance de la meme facon qqsoit
le pc (ex : frametime = 0.01 pour un pc normal ou =2 si c plus lent)
 
jai essayé d'ajoute une sorte de velocite pour que le mouvement
parraisse plus naturel :  
 
    XP = XP + sin(rota*pi/180)*FrameTime;
    ZP = ZP - cos(rota*pi/180)*FrameTime;
 
XP = XP* 0.8
ZP = ZP* 0.8
( comme ca diminue au bout dun certain temps )
 
X = X + XP
Z = Z + ZP
 
le prob est que XP et ZP ne diminue pas en fct du temps ecoule
 
alors jai essaye ca  
 
XP = XP* 0.8 / frametime
ZP = ZP* 0.8 / frametime
 
le probleme est que frametime peut aussi bien etre 0.1 que 5 et ca a pour effet daugmenter XP ou ZP alors quil devrait tjs diminuer
 
 :gun:


Message édité par red faction le 31-08-2002 à 15:48:48
Reply

Marsh Posté le 31-08-2002 à 14:58:59   

Reply

Marsh Posté le 31-08-2002 à 16:15:45    

comme ca c un peu cho de t'aider .. précise...
 
 
(frametime est ptet tres grand ! c'est des millisecondes ! a surveiller !)

Reply

Marsh Posté le 31-08-2002 à 16:23:35    

tu devrais exprimer la position du joueur comme suit :
 
nouvellePosition = anciennePosition + vecteurDirection * vitesse
 
* vecteurDirection est un vecteur unitaire
* vitesse est un flottant dépendant du timer. tu as une vitesse absolute (vitesseAbsolue) qui indique la distance à parcourir en par exemple une seconde. ici, vu que tu updates frame par frame, tu le fais en fonction du temps écoulé entre ces deux frames :
 
// choppe le temps courant (en millisecondes)
curTime = GetTickCount();
// updater la position
nouvellePosition = ...
// stocke le temps courant pour la prochaine frame
prevTime = curTime;
 
curTime - prevTime représente donc l'intervalle de temps entre les deux frames et te donne la vitesse à appliquer dans ton déplacement par un simple produit en croix :
 
1 seconde   |    curTime - prevTime
absoluteSpeed     speed
 
pour que ça "diminue au bout d'un certain temps", tu fais juste diminuer absoluteSpeed de la même manière.

Reply

Marsh Posté le 31-08-2002 à 16:25:09    

farib a écrit a écrit :

comme ca c un peu cho de t'aider .. précise...
 
 
(frametime est ptet tres grand ! c'est des millisecondes ! a surveiller !)




dis moi ca que tu ne comprend pas, je pense que c assez clair

Reply

Marsh Posté le 31-08-2002 à 16:38:28    

youdontcare a écrit a écrit :

tu devrais exprimer la position du joueur comme suit :
 
nouvellePosition = anciennePosition + vecteurDirection * vitesse
 
* vecteurDirection est un vecteur unitaire
* vitesse est un flottant dépendant du timer. tu as une vitesse absolute (vitesseAbsolue) qui indique la distance à parcourir en par exemple une seconde. ici, vu que tu updates frame par frame, tu le fais en fonction du temps écoulé entre ces deux frames :
 
// choppe le temps courant (en millisecondes)
curTime = GetTickCount();
// updater la position
nouvellePosition = ...
// stocke le temps courant pour la prochaine frame
prevTime = curTime;
ca je le faisait deja mais avec Queryperformance qui est bcp plus precis : getickcount ne tourne qu'a 10ms
 
curTime - prevTime représente donc l'intervalle de temps entre les deux frames et te donne la vitesse à appliquer dans ton déplacement par un simple produit en croix :
 
1 seconde   |    curTime - prevTime
absoluteSpeed     speed

pour que ça "diminue au bout d'un certain temps", tu fais juste diminuer absoluteSpeed de la même manière.  




 
heu jcomprend pas tres bien  le produit  en croix


Message édité par red faction le 31-08-2002 à 16:54:00
Reply

Marsh Posté le 31-08-2002 à 18:25:01    

a b
c x
 
où x est l'inconnue : x = b * c / a
 
donc ici, speed = absoluteSpeed * (curTime - prevTime) / 1000
 
et si je n'étais pas clair pour l'effet de perte de vitesse, c'est la même chose sauf que tu utilises le temps du début de la perte et le temps que tu mets pour passer de absoluteSpeed à 0.

Reply

Marsh Posté le 31-08-2002 à 18:25:49    

et n'édite pas ton message mais fais en un nouveau histoire que j'ai le drapeau, j'ai failli passer à côté de ton edit.

Reply

Marsh Posté le 01-09-2002 à 00:33:31    

tes variables sont bine en float et pas une connerie en int qd mm

Reply

Marsh Posté le 01-09-2002 à 00:40:07    

frametime serait pas en secondes par hazard ?
 
a ce moment, le plus simple est de faire :
 
XP = XP * 0.8 / (cint(frametime) + 1)
 
avec "cint" une fonction qui convertis en entier

Reply

Marsh Posté le 01-09-2002 à 09:01:36    

jolly a écrit a écrit :

tes variables sont bine en float et pas une connerie en int qd mm




 
oui qd meme ! des int ca te sert pa a grand chose en 3d ...  
pour compter les points de vie du perso peut etre  :D

Reply

Marsh Posté le 01-09-2002 à 09:01:36   

Reply

Marsh Posté le 01-09-2002 à 13:23:47    

tu veux pas poster ton code plutot?
 
sinon quelques remarques generales:
en cinématique, tu as plusieurs grandeurs
la position (x, y , z classique),
la vitesse (vx=dx/dt, vy=dy/dt, vz=dz/dt)
et l'acceleration (dvx/dt, dvy/dt, dvz/dt)
 
L'acceleration est une grandeur  
qui varie comme les forces appliquées a ton objet (gravité, moteur, frottements). (ca c'est de la dynamique).
Tu peux déduire la position par intégration successive
de l'acceleration.  
Ce que tu cherches a avoir c'est une force de norme constante orientée comme le joueur et un frottement fluide:

Code :
  1. ax = a*sin() - abs(vx) * f;
  2. az = -a*cos() - abs(vz) * f;// avec a et f deux constantes positives

a vaut zero quand le joueur n'appuie sur aucune touche, par contre f ne vaut jamais zero.
 
de la tu en deduis la nouvelle vitesse:

Code :
  1. vx = vx + ax * temps;
  2. vy = vy + az * temps;


puis tu en deduis la nouvelle position:

Code :
  1. x = x + vx * temps;
  2. y = y + vy * temps;


 
Ce n'est pas tres precis (il y a des methodes d'intégration plus précises style verlet) mais pour ton cas ca devrait suffire.
 
LeGreg

Reply

Marsh Posté le 07-09-2002 à 12:47:29    

legreg a écrit a écrit :

tu veux pas poster ton code plutot?
 
sinon quelques remarques generales:
en cinématique, tu as plusieurs grandeurs
la position (x, y , z classique),
la vitesse (vx=dx/dt, vy=dy/dt, vz=dz/dt)
et l'acceleration (dvx/dt, dvy/dt, dvz/dt)
 
L'acceleration est une grandeur  
qui varie comme les forces appliquées a ton objet (gravité, moteur, frottements). (ca c'est de la dynamique).
Tu peux déduire la position par intégration successive
de l'acceleration.  
Ce que tu cherches a avoir c'est une force de norme constante orientée comme le joueur et un frottement fluide:

Code :
  1. ax = a*sin() - abs(vx) * f;
  2. az = -a*cos() - abs(vz) * f;// avec a et f deux constantes positives

a vaut zero quand le joueur n'appuie sur aucune touche, par contre f ne vaut jamais zero.
 
de la tu en deduis la nouvelle vitesse:

Code :
  1. vx = vx + ax * temps;
  2. vy = vy + az * temps;


puis tu en deduis la nouvelle position:

Code :
  1. x = x + vx * temps;
  2. y = y + vy * temps;


 
Ce n'est pas tres precis (il y a des methodes d'intégration plus précises style verlet) mais pour ton cas ca devrait suffire.
 
LeGreg




la jcomprend plus trop (c constant mais on ca change en fonction du joueur ????)

Reply

Marsh Posté le 07-09-2002 à 13:03:01    

oui tu as deux formules qui correspondent a deux etats:
moteur allumé/moteur eteint:
 
donc tu as deux jeux de constantes  
[a ,f] moteur allumé
et [a, f] moteur eteint
 
LeGreg

Reply

Marsh Posté le 07-09-2002 à 16:39:09    

[:prosterne]   merci bcp ca marche now
 
ya juste encore qq ptit truc que jarrive pas a regler :  
 

Code :
  1. //init
  2. f=0.8;straf=0;temps=0.1;
  3. //
  4. draw(){
  5. ax= a*sin((turn+straf)*3.14/180)-vx*f;
  6. az=-a*cos((turn+straf)*3.14/180)-vz*f;
  7. vx+=ax*temps;
  8. vz+=az*temps;
  9. x+=vx*temps;
  10. z+=vz*temps;
  11. glRotated(tilt, 1, 0, 0);
  12. glRotated(turn, 0, 1, 0);
  13.  glTranslated(x,0,z);
  14. //gluLookAt(0,0,-10,0,0,0,x,1,0);
  15.   drawscene();
  16.  
  17.   glFlush();
  18.    
  19.    
  20.         if (keys['s']) {
  21.           a=20;
  22.         }
  23.         else if (keys['z']){
  24.   a=-20;
  25.         }
  26. else if (keys['q']){
  27.   a=20;
  28.   straf=90;
  29. }
  30.         else if (keys['d']){
  31.   a=-20;
  32.   straf=90;
  33. }
  34. else{
  35.   a=0;
  36.           straf=0;
  37. }
  38. ...


 
-->deja jai vire le abs() car ca causait des probleme lorsque le perso se retournait
 
-->temps represente le temps ecoule depuis la derniere frame mais en quoi ?? secondes ?? pour que si je met a=20 je bouge alors de 20 unite par secondes
 
--> si on appuie sur q et z en meme temps ca cause un prob, jai pense faire straf=45 mais ce ne sera ptet pas tres realiste


Message édité par red faction le 07-09-2002 à 16:40:05
Reply

Marsh Posté le 07-09-2002 à 17:33:30    

ooops desole pour le abs(),
mais je vois que tu as corrigé de toi meme :)
 
a, c'est une acceleration donc des metres par secondes au carré (m/(s^2)).
pour que ce soit realiste faudrait deja que tu definisses dans quoi tu te deplaces (voiture, vaisseau spatial, bateau, a pied, etc..). L'acceleration de la pesanteur (quand tu tombes) c'est 9 m/(s^2) et c'est beaucoup pour un etre humain mais ce n'est pas beaucoup pour une fusée.
Ca ne te donne pas de combien tu te deplaces en une seconde, pour ca il faut intégrer la formule et ca depend des autres forces qui se sont exercées sur toi (le frottement fluide va limiter ta vitesse maximale).
Donc deux possibilités: soit tu fais un jeu super realiste, tu decides que une unité = 1 metre, et tu calques ton déplacement sur celui d'un vehicule existant. Soit tu ne fixes rien du tout, et tu trouves la valeur d'acceleration au hasard jusqu'a ce que tu sois satisfait. De toute facon cette formule ne marche pas trop pour simuler le deplacement d'un personnage qui marche (plutot pour un vehicule simplifié comme dans WipeOut).
 
pour le strafe, en fait tu orientes ton acceleration non plus dans la direction ou tu regardes mais dans la direction ou tu avances. C'est ce que tu fais avec turn+strafe, sauf qu'effectivement lorsque tu avances et strafe, tu vas te deplacer d'un angle de 45° par rapport a ton angle de vue. Evidemment faut prendre en compte tous les cas (4 au total) ou tu avances et strafes sur la gauche, recules et strafes sur la droite etc.. (+45, -45, +135, -135)
Autre possibilité, tu considères chaque action strafe + avance séparement et tu as le vecteur acceleration = acceleration avance + acceleration strafe.
si acceleration avance c'est (a1* sin, -a1 * cos), acceleration strafe c'est (a2*cos, a2*sin) ou (-a2*cos, -a2*sin).
 
LeGreg

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed