Dédécter une collision entre deux surface


Dans ce tutoriels vous allez apprendre a détecter une collision entre de surface en SDL

pour coder proprement cela ce fera dans la fonction isCollide qui prendra comme paramètre deux structure de type SDL_Rect et renvois 1 si il ya eu collision ou 0 si il y’en a pas

  1. int isCollide(SDL_Rect obj1, SDL_Rect obj2)
  2. {
  3. return
  4. (
  5. obj1.x >= obj2.x && obj1.x <= obj2.x+obj2.w &&
  6. obj1.y >= obj2.y && obj1.y <= obj2.y+obj2.h ||
  7.  
  8. obj1.x+obj1.w >= obj2.x && obj1.x+obj1.w <= obj2.x+obj2.w &&
  9. obj1.y >= obj2.y && obj1.y <= obj2.y+obj2.h ||
  10.  
  11. obj1.x >= obj2.x && obj1.x <= obj2.x+obj2.w &&
  12. obj1.y+obj1.h >= obj2.y && obj1.y+obj1.h <= obj2.y+obj2.h ||
  13.  
  14. obj1.x+obj1.w >= obj2.x && obj1.x+obj1.w <= obj2.x+obj2.w &&
  15. obj1.y+obj1.h >= obj2.y && obj1.y+obj1.h <= obj2.y+obj2.h ||
  16.  
  17. obj2.x >= obj1.x && obj2.x <= obj1.x+obj1.w &&
  18. obj2.y >= obj1.y && obj2.y <= obj1.y+obj1.h ||
  19.  
  20. obj2.x+obj2.w >= obj1.x && obj2.x+obj2.w <= obj1.x+obj1.w &&
  21. obj2.y >= obj1.y && obj2.y <= obj1.y+obj1.h ||
  22.  
  23. obj2.x >= obj1.x && obj2.x <= obj1.x+obj1.w &&
  24. obj2.y+obj2.h >= obj1.y && obj2.y+obj2.h <= obj1.y+obj1.h ||
  25.  
  26. obj2.x+obj2.w >= obj1.x && obj2.x+obj2.w <= obj1.x+obj1.w &&
  27. obj2.y+obj2.h >= obj1.y && obj2.y+obj2.h <= obj1.y+obj1.h
  28. );
  29. }

Petite explication:
pour détecter une collision entre deux surface carrée en test en premier temps en test si un des point de la premier surface ce trouve a l’intérieur de la deuxième surface ensuit c’est l’inverse en test si un des point de la deuxièmes surface ce trouve a l’intérieur de la premier surface

Exemple:
pour cela supposions que ‘P’ soit le point a test si il est a l’intérieur d’une surface appeler ‘S’ en fait comme ce-si

  1. if(P.x >= S.x && P.x <= S.x+S.w && P.y >= S.y && P.y <= S.y+S.h)
  2. cout << "Collision !" << endl;
  3.  
  4. else
  5. cout << "Pas de collision" << endl;

Exemple de programme complet:

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. #include <sdl.h>
  5. #include <sdl_framerate.h>
  6.  
  7. #define MOVE_POWER 5
  8.  
  9. int isCollide(SDL_Rect obj1, SDL_Rect obj2)
  10. {
  11. return
  12. (
  13. obj1.x >= obj2.x && obj1.x <= obj2.x+obj2.w &&
  14. obj1.y >= obj2.y && obj1.y <= obj2.y+obj2.h ||
  15.  
  16. obj1.x+obj1.w >= obj2.x && obj1.x+obj1.w <= obj2.x+obj2.w &&
  17. obj1.y >= obj2.y && obj1.y <= obj2.y+obj2.h ||
  18.  
  19. obj1.x >= obj2.x && obj1.x <= obj2.x+obj2.w &&
  20. obj1.y+obj1.h >= obj2.y && obj1.y+obj1.h <= obj2.y+obj2.h ||
  21.  
  22. obj1.x+obj1.w >= obj2.x && obj1.x+obj1.w <= obj2.x+obj2.w &&
  23. obj1.y+obj1.h >= obj2.y && obj1.y+obj1.h <= obj2.y+obj2.h ||
  24.  
  25. obj2.x >= obj1.x && obj2.x <= obj1.x+obj1.w &&
  26. obj2.y >= obj1.y && obj2.y <= obj1.y+obj1.h ||
  27.  
  28. obj2.x+obj2.w >= obj1.x && obj2.x+obj2.w <= obj1.x+obj1.w &&
  29. obj2.y >= obj1.y && obj2.y <= obj1.y+obj1.h ||
  30.  
  31. obj2.x >= obj1.x && obj2.x <= obj1.x+obj1.w &&
  32. obj2.y+obj2.h >= obj1.y && obj2.y+obj2.h <= obj1.y+obj1.h ||
  33.  
  34. obj2.x+obj2.w >= obj1.x && obj2.x+obj2.w <= obj1.x+obj1.w &&
  35. obj2.y+obj2.h >= obj1.y && obj2.y+obj2.h <= obj1.y+obj1.h
  36. );
  37. }
  38.  
  39. int main(int argc, char** argv)
  40. {
  41. SDL_Init(SDL_INIT_VIDEO);
  42. SDL_WM_SetCaption("Tutoriels Collision",0);
  43. SDL_Surface* screen = SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
  44. SDL_Event event;
  45. int exit = 0;
  46.  
  47. SDL_Surface* ball = SDL_CreateRGBSurface(SDL_HWSURFACE,32,32,32,0,0,0,0);
  48. SDL_FillRect(ball,0,SDL_MapRGBA(ball->format,0,255,255,255));
  49.  
  50. SDL_Surface* cube1 = SDL_CreateRGBSurface(SDL_HWSURFACE,64,64,32,0,0,0,0);
  51. SDL_FillRect(cube1,0,SDL_MapRGBA(cube1->format,0,255,255,255));
  52.  
  53. SDL_Surface* cube2 = SDL_CreateRGBSurface(SDL_HWSURFACE,128,128,32,0,0,0,0);
  54. SDL_FillRect(cube2,0,SDL_MapRGBA(cube2->format,0,255,255,255));
  55.  
  56. SDL_Rect ballpos = {10,10};
  57. SDL_Rect cube1pos = {100,100};
  58. SDL_Rect cube2pos = {300,300};
  59.  
  60. FPSmanager fps;
  61. SDL_initFramerate(&fps);
  62. SDL_setFramerate(&fps,60);
  63.  
  64. while(!exit)
  65. {
  66. SDL_PollEvent(&event);
  67.  
  68. if(event.type == SDL_QUIT)
  69. exit = 1;
  70.  
  71. /// Si appuye sur la touceh Espace
  72. if(event.type == SDL_KEYDOWN)
  73. {
  74. if(event.key.keysym.sym == SDLK_UP)
  75. ballpos.y -= MOVE_POWER;
  76.  
  77. if(event.key.keysym.sym == SDLK_DOWN)
  78. ballpos.y += MOVE_POWER;
  79.  
  80. if(event.key.keysym.sym == SDLK_LEFT)
  81. ballpos.x -= MOVE_POWER;
  82.  
  83. if(event.key.keysym.sym == SDLK_RIGHT)
  84. ballpos.x += MOVE_POWER;
  85. }
  86.  
  87. /// Si collision (balle rouge)
  88. if(isCollide(ballpos,cube1pos) || isCollide(ballpos,cube2pos))
  89. SDL_FillRect(ball,0,SDL_MapRGBA(ball->format,255,0,0,255));
  90.  
  91. /// Sinon (balle blue)
  92. else
  93. SDL_FillRect(ball,0,SDL_MapRGBA(ball->format,0,255,255,255));
  94.  
  95. // Ajustement pour que la ball ne depasse pas l'ecran
  96. if(ballpos.y+ballpos.h > screen->h) ballpos.y = screen->h-ballpos.h;
  97. if(ballpos.x+ballpos.w > screen->w) ballpos.x = screen->w-ballpos.w;
  98. if(ballpos.x < 0) ballpos.x = 0;
  99. if(ballpos.y < 0) ballpos.y = 0;
  100.  
  101. SDL_FillRect(screen,0,0);
  102.  
  103. SDL_BlitSurface(cube1,0,screen,&cube1pos);
  104. SDL_BlitSurface(cube2,0,screen,&cube2pos);
  105. SDL_BlitSurface(ball,0,screen,&ballpos);
  106.  
  107. SDL_framerateDelay(&fps);
  108. SDL_Flip(screen);
  109. }
  110.  
  111. SDL_FreeSurface(ball);
  112. SDL_FreeSurface(cube1);
  113. SDL_FreeSurface(cube2);
  114. SDL_Quit();
  115.  
  116. return 0;
  117. }

Image: http://download.tuxfamily.org/b4n92uidsite/sdl-collide/collide.png

Voila cette technique montre comment détecter une collision entre deux surface car pour info ce test s’appelle la détection du Boundign Box de l’image il existe aussi la détection du Boundign Sphere de l’image celle si utilise les vecteur et le rayon d’une sphere pour détecter la collision et s’applique mieux aux forme rond.

Télécharger l’archive content le projet et l’exécutable


  • hamza dit :

    t’es le meilleur mec ,j’ai cherché sur tout les sites et je n’ai jamais reussi a comprendre jusqu’au jour ou je suis tombé sur se magnifique exemple ,merci et bonne continuation

  • Laisser un commentaire

    Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

    *

    Spam protection by WP Captcha-Free