Lemng
Messages postés31Date d'inscriptionmardi 3 juillet 2007StatutMembreDernière intervention 4 mai 2009
-
2 janv. 2009 à 23:40
cs_stephane57
Messages postés12Date d'inscriptionlundi 17 décembre 2007StatutMembreDernière intervention 6 janvier 2009
-
6 janv. 2009 à 22:22
Bonjour tout le monde,
voici mon problème : j'utilise la SDL pour programmer un jeu se jouant a l'aide du clavier et de la souris de la manière suivante : vous, le héros êtes au beau milieu d'un niveau plus grand que l'écran et remplit d'ennemi. Lorsque vous vous approchez d'eux ils vous tirent dessus et vous voyez votre vie descendre. Pour les tuer vous devez cliquer dessus. Je suis assez fier de mon jeux qui incorpore un menu en jeu donnant divers information comme votre vie et vos dégats ou encore votre position sur une mini carte.
Cependant, depuis peu j'ai un gros problème de rapidité. Je ne sais pas a quoi cela est du. Voici la structure de mon programme(seulement l'essentiel)
Tout d'abord j'ai créé des structures ennemis et des structures personnage, un SDL_Rect qui sert de camera pour le scrolling et un tableau d'ennemi, histoire de gerer tout les ennemis a l'aide de ce tableau.
j'arrive ensuite a une boucle des évenements écrite ainsi:
SDL_Event event; //variable pour les evenements
bool continuer = true;
int oldTime = 0;
int now = 0;
int clike = 0;
while(continuer)
{
now = SDL_GetTicks();
if(now-oldTime >= 20) //pour limiter le nombre de fps
{
afficherTout(ecran, adversaires, personnage, Camera);
//fonction qui parcourt le tableau d'ennemis, les blittes
IA(ecran, adversaires, &personnage, Camera);
//fonction qui parcourt le tableau d'ennemi et fait tirer ceux qui sont proche
afficherMenu(ecran, adversaires, personnage, Camera);
//tout est dans le nom
SDL_Flip(ecran);
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = false;
break;
case SDL_KEYDOWN:
if(event.key.keysym.sym == SDLK_UP && Camera.y > 0)
Camera.y -= 5;
else if(event.key.keysym.sym == SDLK_RIGHT && Camera.x < 1000-Camera.w)
Camera.x += 5;
else if(event.key.keysym.sym == SDLK_DOWN && Camera.y < 1000-Camera.h)
Camera.y += 5;
else if(event.key.keysym.sym == SDLK_LEFT && Camera.x > 0)
Camera.x -= 5;
break;
//ci dessus : les mouvements
case SDL_MOUSEBUTTONDOWN:
if(500+206 > event.button.x && event.button.x > 500+10)
{
if(464 > event.button.y && event.button.y > 413)
return; //si on a cliqué sur le bouton quitter du menu, on quitte
}
clike = clik(adversaires, event.button.x, event.button.y, Camera);
//test pour voire si on tue des ennemi
if(clike != -1)
adversaires[clike].PointDeVies -= personnage.Degats;
break;
};
}
}
D'autres part, j'ai vérifié que je libérais toutes les surfaces après les blits. Et je ne pense pas avoir abusé sur le nombre d'ennemis(5) ni la taille du niveau (1000*1000 dans une fenetre de 500*500).
J'ai entendu parlé de probleme de lenteur avec la SDL. Si la SDL ne sait plus suivre pour un tel programme indiquez moi d'autres bibliothèques 2d un peu plus rapides.
Pistol_Pete
Messages postés1053Date d'inscriptionsamedi 2 octobre 2004StatutMembreDernière intervention 9 juillet 20137 4 janv. 2009 à 13:22
Salut
Je ne connais pas bien la SDL mais voici un petit test que tu peux faire:
Calcul le temps d'exécution de chaque fonction: afficherTout, IA, AfficherMenu etc... et regarde laquelle de ces fonction te bouffe le plus de temps et tu pourras cerner mieux ton problème je pense.
Donne nous les temps moyen d'exécution ainsi que le code de la fonction la plus "consommatrice" et on verra mieux ce qu'il faut faire.
A+
________________________________________________________________________________
Mon site internet : http://ImAnalyse.free.fr
cs_stephane57
Messages postés12Date d'inscriptionlundi 17 décembre 2007StatutMembreDernière intervention 6 janvier 2009 4 janv. 2009 à 19:24
salut, j'ai lu ton petit bout de code
ta lenteur semble venir de la façon dont tu gères le temps avec les FPS avec SDL_GetTicks().
tu écris:
....
if(now-oldTime >= 20) //pour limiter le nombre de fps
{
afficherTout(ecran, adversaires, personnage, Camera);
//fonction qui parcourt le tableau d'ennemis, les blittes
IA(ecran, adversaires, &personnage, Camera);
//fonction qui parcourt le tableau d'ennemi et fait tirer ceux qui sont proche
...
ce n'est pas bon du touttttttttttttttttt.
en effet en mettant un if, tu obliges le programme à attendre jusqu'à 20 sans rien faire !!! d'où la perte de temps.
La solution:
D'ABORD tu dois afficher tout, tu gère l' intelligence artificielle etc etc etc etc
et seulement APRES tu demandes au programme d'attendre jusqu'à ce qu'une certaine valeur entre l'ancien temps et le nouveau temps soit atteinte (pour avoir un affichage constant en nombres de cycles, quel que soit le processeur et le nombres d'actions effectuées à un moment ou à un autre de ton jeu)
Lemng
Messages postés31Date d'inscriptionmardi 3 juillet 2007StatutMembreDernière intervention 4 mai 2009 4 janv. 2009 à 20:31
Merci pour toutes vos réponse. D'abord pour ce qui est de ma fonctio la plus longue voici les temps
afficherTout() : 41
IA() : 2
afficherMenu() : 29
Et le code de ma fonction afficherTout():
void afficherTout(SDL_Surface* ecran, Ennemi adversaires[], Hero personnage, SDL_Rect Camera)
{
SDL_Rect posBlit;
SDL_Surface *niveau = IMG_Load("herbe.png");
SDL_Surface *ennemi = IMG_Load("EnnemiRouge.png");
SDL_SetColorKey(ennemi, SDL_SRCCOLORKEY, SDL_MapRGB(ennemi->format, 255, 255, 255));
SDL_Surface *hero = IMG_Load("Hero.png");
SDL_SetColorKey(hero, SDL_SRCCOLORKEY, SDL_MapRGB(hero->format, 255, 255, 255));
SDL_BlitSurface(niveau, &Camera, ecran, NULL);
SDL_FreeSurface(niveau);
int i=0;
for(i=0;i<NOMBRE_ENNEMI;i++)
{
if(adversaires[i].X > Camera.x && adversaires[i].X + adversaires[i].W < Camera.x+Camera.w && adversaires[i].PointDeVies > 0)
{
if(adversaires[i].Y > Camera.y && adversaires[i].Y + adversaires[i].H < Camera.y+Camera.h)
{
posBlit.x = adversaires[i].X - Camera.x;
posBlit.y = adversaires[i].Y - Camera.y;
SDL_BlitSurface(ennemi, NULL, ecran, &posBlit);
}
}
}
SDL_FreeSurface(ennemi);
posBlit.x = Camera.w/2 - personnage.W/2;
posBlit.y = Camera.h/2 - personnage.H/2;
SDL_BlitSurface(hero, NULL, ecran, &posBlit);
SDL_FreeSurface(hero);
}
Pour ce qui est de ma façon de gérer les fps, je ne pense pas que ce soit la cause de la lenteur : même en enlevant la gestion des fps(pas de limitation) ou en faisant SDL_Delay(20-(oldTime-now)), pour ne pas boucler dans le vide, le résultat est le même : ca lague. D'autre part je peut aussi affirmer que les ralentissement apparaissent le plus souvent lors de l'utilisation du clavier et de la souris en même temps (tirer sur un ennemi et bouger en même temps).
Merci pour votre aide.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Lemng
Messages postés31Date d'inscriptionmardi 3 juillet 2007StatutMembreDernière intervention 4 mai 2009 5 janv. 2009 à 18:30
Merci beaucoup stephane 57, tu as trouvé le problème. En passant les images comme arguments voici les temps :
afficherTout : 8
IA : 2
afficherMenu : 6
ya pas photo :) .
Merci de m'avoir aider, la prochaine fois je ferais plus attention. Je vais poster mon jeu comme source, n'hésite pas à aller la voir.
Lemng
Messages postés31Date d'inscriptionmardi 3 juillet 2007StatutMembreDernière intervention 4 mai 2009 5 janv. 2009 à 18:30
Merci beaucoup stephane 57, tu as trouvé le problème. En passant les images comme arguments voici les temps :
afficherTout : 8
IA : 2
afficherMenu : 6
ya pas photo :) .
Merci de m'avoir aider, la prochaine fois je ferais plus attention. Je vais poster mon jeu comme source, n'hésite pas à aller la voir.
Lemng
Messages postés31Date d'inscriptionmardi 3 juillet 2007StatutMembreDernière intervention 4 mai 2009 5 janv. 2009 à 18:31
Merci beaucoup stephane 57, tu as trouvé le problème. En passant les images comme arguments voici les temps :
afficherTout : 8
IA : 2
afficherMenu : 6
ya pas photo :) .
Merci de m'avoir aider, la prochaine fois je ferais plus attention. Je vais poster mon jeu comme source, n'hésite pas à aller la voir.