CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Collisions en SDL

News jeu

Expeditions: Samurai veut révolutionner le RPG tactique avec une aventure entièrement jouable en coop

Voir
Pseudo supprimé
Pseudo supprimé 04 mars 2013 à 20:55:05

Salut a tous les créateurs de jeux :)

Je code en C avec la SDL et j'ai un soucis avec les collisions.
J'ai créer un programme ou on dirige un carré, et si on ne doit pas passer a travers un petit mur, bref, un truc simple pour tester les collisions.
Je vous explique : j'ai mon algorithme de collision fonctionnel mais lorsque il y a collision, ca bloque, je ne peux plus bouger mon carré, ce n'est pas un plantage.

Voila le code, j'espere que vous pourrez m'aider :)

  1. include <stdio.h>
  2. include <stdlib.h>
  3. include <sdl.h>

bool collisionAABB(SDL_Rect box1, SDL_Rect box2);

int main (int argc, char** argv)
{
SDL_Init(SDL_INIT_VIDEO);

SDL_Surface *ecran = SDL_SetVideoMode(500, 500, 32, SDL_HWSURFACE || SDL_DOUBLEBUF);

SDL_Surface *perso = SDL_LoadBMP("perso.bmp");
SDL_Surface *barre = SDL_LoadBMP("barre.bmp");

SDL_Rect positionBarre;
positionBarre.x = (500/2)-(barre->w/2);
positionBarre.y = (500/2)-(barre->h/2);
positionBarre.w = barre->w;
positionBarre.h = barre->h;

SDL_Rect positionPerso;
positionPerso.x = 0;
positionPerso.y = 0;
positionPerso.w = perso->w;
positionPerso.h = perso->h;

SDL_Event event;
int continuer = 1;

while (continuer)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;

case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_DOWN:
if (positionPerso.y > (500-perso->w))
break;

if(collisionAABB(positionBarre, positionPerso) == true)
break;

positionPerso.y++;
break;

case SDLK_UP:
if(collisionAABB(positionBarre, positionPerso) == true)
break;

positionPerso.y--;
break;

case SDLK_LEFT:
if(collisionAABB(positionBarre, positionPerso) == true)
break;

positionPerso.x--;
break;

case SDLK_RIGHT:
if (positionPerso.x > (500-perso->h))
break;

if(collisionAABB(positionBarre, positionPerso) == true)
break;

positionPerso.x++;
break;
}
}

SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
SDL_BlitSurface(barre, NULL, ecran, &positionBarre);
SDL_BlitSurface(perso, NULL, ecran, &positionPerso);
SDL_Flip(ecran);

}

SDL_FreeSurface(barre);
SDL_FreeSurface(perso);
SDL_Quit();
}

bool collisionAABB(SDL_Rect box1, SDL_Rect box2)
{
if((box2.x >= box1.x + box1.w) ||
(box2.x + box2.w <= box1.x) ||
(box2.y >= box1.y + box1.h) ||
(box2.y + box2.h <= box1.y))
return false;
else
return true;
}

caelacanthe
caelacanthe
Niveau 10
04 mars 2013 à 20:58:46

je suppose que les deux carrés restent en collision même lorsque tu as détecté celle-ci... :hap:

c'est bien ça, une fois qu'il y a collision, tu interrompt toutes les récupérations des pressions des touches de direction, donc ça ne peut pas fonctionner. :non:

Pseudo supprimé
Pseudo supprimé 04 mars 2013 à 21:00:56

Salut !
merci de t'interesser a mon probleme :)

En effet, je pensait comme toi au debut, puis, j'ai remarquer que lorsque je ne gerait qu'une collision (par exemple lorsque l'on se deplace vers la gauche), ca marche, mais pas quand je gere tout les cotés, j'espere que tu vois ce que je veux dire.

caelacanthe
caelacanthe
Niveau 10
04 mars 2013 à 21:03:08

forcément, si tu interrompt le déplacement vers la gauche lorsqu'il y a collision, mais que tu autorises tous les déplacements dont celui vers la droite, le problème n'aura pas d'influence. :nah:

tu es bon pour recaler ton carré en dehors de la zone de collision, ou au moins le téléporter à sa position précédente, celle d'avant la collision.

Pseudo supprimé
Pseudo supprimé 04 mars 2013 à 21:05:41

Ok, merci, j'essaye ca et je te tient au courant

Pseudo supprimé
Pseudo supprimé 04 mars 2013 à 21:16:07

Ca pose un nouveau probleme, parfois, mon carré rentre dans le mur alors que parfois non.

Voila le code, juste la partie déplacement :

case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_DOWN:
if (positionPerso.y > (500-perso->w))
break;

if(collisionAABB(positionBarre, positionPerso) == true)
{
positionPerso.y--;
break;
}

positionPerso.y++;
break;

case SDLK_UP:
if(collisionAABB(positionBarre, positionPerso) == true)
{
positionPerso.y++;
break;
}

positionPerso.y--;
break;

case SDLK_LEFT:
if(collisionAABB(positionBarre, positionPerso) == true)
{
positionPerso.x++;
break;
}

positionPerso.x--;
break;

case SDLK_RIGHT:
if (positionPerso.x > (500-perso->h))
break;

if(collisionAABB(positionBarre, positionPerso) == true)
{
positionPerso.x--;
break;
}

if(collisionAABB(positionBarre, positionPerso) == true)
break;

positionPerso.x++;
break;
}

caelacanthe
caelacanthe
Niveau 10
04 mars 2013 à 21:22:00

là, tu ne fais le recalage que lorsqu'on presse les boutons, alors qu'il faudrait le faire constamment, en fait. :peur:

tu enregistres la position actuelle quelque part, tu traites les entrées clavier, tu contrôle s'il y a collision et s'il y a collision, tu remets le carré à son ancienne position, c'est déjà un début de solution. :oui:

getkey
getkey
Niveau 6
04 mars 2013 à 21:25:34

Aïe, c'est pas facile a lire ton code comme ça...

Au début, pour gérer les collisions, je conseille d'utiliser un quadrillage.
Sépare ton écran en petit carré et fait les tests de collision dans une matrice par exemple.

Si tel carré est occupé par un objet, alors, je ne peux pas y aller !
sinon, je peux !

tout mes jeux fonctionnent sur ce principe.
la perte en fluidité en rattrapée par la simplicité.

j'espère que ça t'aidera

Pseudo supprimé
Pseudo supprimé 04 mars 2013 à 21:38:37

Merci getkey, je connais cette technique, je l'utilise d'ailleur, mais j'aimerai apprendre comment gerer les collisions autrement, sans utiliser les tiles :)
Mais merci pour ton aide tout de meme.

caelacanthe -> je ne vois pas comment enregistrer la derniere position de mon carré, comment ferais-tu ?

getkey
getkey
Niveau 6
04 mars 2013 à 21:47:12

Personnellement je créerais un nouveau

SDL_Rect position_mem

qui prendrait la dernière valeur valide de ton carré avant le changement de position.

Si le test collision renvoie vrai alors remplace positionbarre par position_mem.

Pseudo supprimé
Pseudo supprimé 04 mars 2013 à 21:51:31

Ok, c'est ce que je pensait faire, mais je ne sait pas comment renseigner cette variable...

getkey
getkey
Niveau 6
04 mars 2013 à 21:56:27

voici la structure du programme il me semble.

debut boucle

position_mem := positionbarre
//on enregistre en memoire la position

deplacement //ta fonction de deplacement

if(test_collision) then
positionbarre := position_mem
//on recharge l'ancienne position
end if

fin boucle

Pseudo supprimé
Pseudo supprimé 05 mars 2013 à 17:19:21

Merci a vous deux pour votre aide, mais c'est trop compliqué, je vais recommencer a gerer les collisions par "blocs".

getkey
getkey
Niveau 6
05 mars 2013 à 18:56:41

Pas de soucis, fais a ton rythme.

J'ai actuellement un projet SDL en cours, ça me ferai plaisir que tu participe en me donnant ton avis. cf sujet [RPG]Daemon sur ce forum
ou bien: http://ovoide.forumactif.org/

Je pourrais même trouver 2 ou 3 fonctions a te faire coder si tu as envie.

Pseudo supprimé
Pseudo supprimé 06 mars 2013 à 14:46:10

Ok, ca me ferait plaisir de soutenir ton projet, je pourrait aussi t'aider :)

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware