Se connecter / S'enregistrer
Votre question

[C] problèmes avec mon jeu en SDL

Tags :
  • Programmation
  • Écrans
Dernière réponse : dans Programmation
31 Octobre 2006 19:12:02

Bonjour tout le monde. Je suis en train de programmer un jeu en SDL. Pour le moment j'affiche la map (map quadrillée avec des textures genre RTS), lorsque la souris va sur la droite de l'écran, la map se déplace à gauche pour donner une illusion de déplacement, même chose pour les 3 autres côté. J'affiche aussi l'interface de l'utilisateur (qui n'est pour le moment qu'une image png représentant la futur interface). Seulement j'ai 3 problèmes avec mon jeu :

- J'ai fait un curseur personnalisé (image png) puisqu'on ne voit pas le curseur en plein écran. La surface sur laquelle est le curseur doit se mettre aux coordonnées de la souris. Jusque la ça va mais mon curseur personnalisé a un temps de retard sur la souris.

- Lorsque le joueur décale la souris sur le bord droit ou bas de l'écran, la map se déplace bien mais elle ne peut pas aller à des coordonnées négatives donc la map bloque contre le bord de l'écran. (ce n'est pas le cas pour les 2 autres coins car les coordonnées sont tout le temps positives)

- Lorsque j'affiche l'interface, le jeu lag terriblement alors que l'image à afficher ne fait que 92,6 Ko.

voici mon code des events :
  1. #include <SDL/SDL.h>
  2. #include <SDL/SDL_image.h>
  3.  
  4. void pause(SDL_Rect positionMap, SDL_Surface *ecran, SDL_Surface *map, SDL_Rect positionCurseur, SDL_Surface *interface)
  5. {
  6. int continuer = 1, defiler = 0;
  7. SDL_Rect positionInterface;
  8. SDL_Surface *curseur = NULL;
  9. SDL_Event event;
  10. SDL_EnableKeyRepeat(10, 10);
  11.  
  12. positionInterface.x = 0;
  13. positionInterface.y = (ecran->h)-177;
  14.  
  15. curseur = IMG_Load("curseur.png");
  16. while(continuer)
  17. {
  18. SDL_PollEvent(&event);
  19. switch (event.type)
  20. {
  21. case SDL_QUIT :
  22. continuer = 0;
  23. break;
  24.  
  25. case SDL_KEYDOWN :
  26. switch (event.key.keysym.sym)
  27. {
  28. case SDLK_ESCAPE :
  29. continuer = 0;
  30. break;
  31.  
  32. case SDLK_LEFT :
  33. positionMap.x -= 2;
  34. break;
  35.  
  36. case SDLK_RIGHT :
  37. positionMap.x +=2;
  38. break;
  39.  
  40. case SDLK_UP :
  41. positionMap.y -=2;
  42. break;
  43.  
  44. case SDLK_DOWN :
  45. positionMap.y +=2;
  46. break;
  47.  
  48. }
  49. break;
  50.  
  51. case SDL_MOUSEMOTION:
  52.  
  53.  
  54. if(event.motion.x >= (ecran->w)-10)
  55. {
  56. positionMap.x -= 2;
  57. }
  58. if(event.motion.x <= 10)
  59. {
  60. positionMap.x += 2;
  61. }
  62. if(event.motion.y <= 10)
  63. {
  64. positionMap.y += 2;
  65. }
  66. if(event.motion.y >= (ecran->h)-10)
  67. {
  68. positionMap.y -= 2;
  69. }
  70. break;
  71. }
  72. fprintf(stderr, "\n%ld\n", positionCurseur.x);
  73. positionCurseur.y = event.motion.y;
  74. positionCurseur.x = event.motion.x;
  75.  
  76. SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
  77. SDL_BlitSurface(map, NULL, ecran, &positionMap);
  78. //SDL_BlitSurface(interface, NULL, ecran, &positionInterface);
  79. SDL_BlitSurface(curseur, NULL, ecran, &positionCurseur);
  80. SDL_Flip(ecran);
  81. }
  82.  
  83. SDL_FreeSurface(curseur);
  84. SDL_FreeSurface(interface);
  85. }


Est-ce que quelqu'un pourrait m'éclairer ? Merci d'avance

Autres pages sur : problemes jeu sdl

a b L Programmation
31 Octobre 2006 20:45:52

C'est simple, faut pas faire l'affichage dans la boucle d'évènements, faut faire un autre while autour et mettre l'affichage en dehors du while des évènements.
Je m'explique:
en, bouclant sur un while(SDL_PollEvent(&event)) tu boucle sur tous les évènements de la pile d'évènements. Par exemple si tu bouges la souris rapidement, tu peux avoir beaucoup de messages (peut-être beaucoup plus que nécessaire pour l'affichage).
Le fait de faire l'affichage dans la boucle d'évènement, fait ralentir à cause de l'affichage. Ainsi, si tu as beaucoup de message à dépiler, tu as un décalage temporel entre le mouvement de la souris et le déplacement du curseur. Le phénomène s'amplifie lorsque tu as plein de message (bouger beacoup la souris en appuyant et relachant sur plein de touches).
Par exemple, supposons que tu déplaces la souris et que ça crée 10 messages qui s'emplient dans un temps de 1/25 de seconde = 0.04s (une image vue par l'oeil humain). Supposons que l'affichage prend 1/100 s, alors le temps total pour traiter tous les messages sera de 10 * 1/100 = 1/10 secondes = 0.1s
Donc, voilà, le temps de d'afficher tout prend en fait 2.5 images, donc, tu as 2.5 images de retard pour une seconde, après les messages continuant à s'empiler, l'écrat devient de plus en plus grand.
En jeu vidéo ou autre, le plus lent c'est toujours le graphisme, alors il faut éviter au maximum de trop afficher.

Donc:
- au lieu de boucler sur "continuer", tu boucle sur while(SDL_PollEvent(&event)), car la fonction retourne 0 lorsque la pile de message est vide.
- faire sortir l'affichage en dehors de la boucle (après)
- faire une grande boucle sur "continuer" qui englobe à la fois la boucle des messages et la l'affichage.

1 Novembre 2006 14:47:22

oula je suis pas sûr d'avoir tout compri. En fait si je fais une boucle sur continuer = 1, cela fait une boucle infinie et comme à chaque fois je demande de bliter, ca ralenti c'set ça ? Donc il faut que je fasse une boucle sur continuer = 1 qui englobe une boucle while(SDL_PollEvent(&event)) comme ca ça blit seulement si il y a eu un ou plusieurs évènement(s). Voilà ce que j'ai compri mais je ne suis pas sûr du tout que ce soit ça :) 

merci en tout cas :) 
Contenus similaires
Pas de réponse à votre question ? Demandez !
1 Novembre 2006 15:25:14

Ok c'est bon j'ai fais ce que tu m'avais dit avec les boucles et ça fonctionne à la perfection, la fluidité est parfaite ! Merci beaucoup !

Cependant il me reste encore un gros problème pour mon jeu, c'est que la surface ne peut pas avoir des coordonnées négatives et donc il est impossible de voir le bas de la map par exemple. Comment faut-il faire plz ?? :) 

merci d'avance :) 
a b L Programmation
1 Novembre 2006 16:22:09

Pour ton premier post, je pense que t'as bien compris.

Pour ta seconde question, c'est la technique du clipping que tu dois appliquer. Pour ne pas ralentir, il faut éviter de copier en dehors de l'écran (même pour l'autre côté où c'est positif), surtout si ta map est grande.
En regardant dans ce tutorial : http://lazyfooproductions.com/SDL_tutorials/lesson06/index.php
Je vois qu'il y a la fonction "apply_surface()" qui permet de dénifir une zone de clipping (le rectangle donnée contient les coordonnées par rapport au sprite pas par rapport à l'écran).
Donc, avec cette fonction tu découpes dans "map" juste le carré de l'écran, et tu le pose sur l'écran en (0, 0).
C'est (0,0) car si tu découpe "map" sur (120,530,920,1130), ça met ce rectangle de map en (0,0) sur l'écran, et donc le pixel (0,0) correspondra bien au point de la map mis en (120, 530).
Bon, je sais pas si c'est très clair, parce que sans faire de dessin c'est pas évident à expliquer :D 
1 Novembre 2006 16:48:04

ui tkt je vois ce que c'est il y a la même chose en php ou Javascript je sais pu trop. En plus ca évite de gâcher des ressources car on génère juste ce dont on a besoin. Merci pour le lien mais je ne comprends pas tout, je vais essayer de trouver d'autres tuto sur le clipping. meci bcp :) 

@+

edit: en fait c'est bon, j'ai relu tout ça et ça y est je vois ce qu'il faut faire ! merci encore ;) 
1 Novembre 2006 20:00:06

okay c'est impeccable tout fonctionne parfaitement ! merci encore ! =)
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS