C'est un coup de chance, lorsque le pas est différent de 1, si le code détecte le bord de l'écran (nombre pair).
J'insiste pour dire qu'il faut plutôt faire ces tests:Code:
1
2
3
4
5 if(positionball.x >= 0) et if(positionball.x >= 640)
Version imprimable
C'est un coup de chance, lorsque le pas est différent de 1, si le code détecte le bord de l'écran (nombre pair).
J'insiste pour dire qu'il faut plutôt faire ces tests:Code:
1
2
3
4
5 if(positionball.x >= 0) et if(positionball.x >= 640)
J'ai copier le code qui j'ai toi marche, mais j'ai moi cela ne marche Toujours PAS peut être a cause de mon IDE qui est code::block quel est le tien?
Est-ce moi qui n'ai pas les yeux en face des trous ou bien les champs w et h des structures SDL_Rect ne sont jamais initialisés? Je n'ai jamais utilisé SDL, mais rien que cela, c'est louche, non?
EDIT
OK, SDL_BlitSurface n'utilise pas ces deux champs apparemment, je n'ai rien dit... désolé :oops:
Re,
je suis sous code blocks, j ai regardé ca et j ai modifié un peu les tests, et utiliser les supérieurs inférieurs comme conseillé par spoutspout.
j espere que ca va le faire.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 #include <stdlib.h> #include <stdio.h> #include <SDL/SDL.h> #define PAS 10 int main(int argc, char *argv[]) { SDL_Surface *ecran = NULL,*bare = NULL, *ligne=NULL,*bare2=NULL,*ball=NULL; SDL_Rect positionbare,positionligne,positionbare2, positionball; SDL_Event event; int continuer = 1; int tempsPrecedent = 0, tempsActuel = 0; int sens_ball = 1; SDL_Init(SDL_INIT_VIDEO); ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE| SDL_DOUBLEBUF);//charge la fenetre et la taille bare = SDL_CreateRGBSurface(SDL_HWSURFACE, 10, 100, 32, 0, 0, 0, 0); // Allocation de la surface bare2 = SDL_CreateRGBSurface(SDL_HWSURFACE, 10, 100, 32, 0, 0, 0, 0); // Allocation de la surface ball = SDL_CreateRGBSurface(SDL_HWSURFACE, 10, 10, 32, 0, 0, 0, 0); ligne = SDL_CreateRGBSurface(SDL_HWSURFACE, 5, 480, 32, 0, 0, 0, 0); SDL_WM_SetCaption("Pong", NULL); positionbare2.x = 620; positionbare2.y = 180; positionligne.x= (640 / 2)- (2 / 2) ;//coordonné de la ligne positionligne.y=(480 / 2)- (480 / 2); positionbare.x = 10; positionbare.y = 180; positionball.x= 0; positionball.y= 0; SDL_EnableKeyRepeat(10, 10);// répétition des touche while(continuer)//boucle event { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: continuer = 0; break; case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_UP: // Flèche haut positionbare.y -= PAS; break; case SDLK_DOWN: // Flèche bas positionbare.y += PAS; break; } break; } tempsActuel = SDL_GetTicks(); /* si la balle va de droite a gauche && que sa position x <= 1 on rebondit, on change de sens quoi */ if( ( sens_ball == -1 ) && ( positionball.x <= 1 /*( en fait 0 + rayon balle ? */ ) ) { sens_ball = 1; } else { /* presque pareil, si la balle va de gauche a droite && que sa position x >= 639 on rebondit, on change de sens quoi */ if( ( sens_ball == 1 ) && ( positionball.x >= 639 /* ( - rayon balle ? */ ) ) { sens_ball = -1; } } if(positionball.x >=0 && positionball.x <= 640 ) { if (tempsActuel - tempsPrecedent > 30) { positionball.x += ( PAS * sens_ball ); tempsPrecedent = tempsActuel; } else { SDL_Delay(30 - (tempsActuel - tempsPrecedent)); } } SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0,0)); SDL_FillRect(ligne, NULL, SDL_MapRGB(ecran->format, 255, 255, 255)); SDL_BlitSurface(ligne, NULL, ecran, &positionligne); SDL_FillRect(bare, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));//charge la couleur de l'écran SDL_BlitSurface(bare, NULL, ecran, &positionbare); // Collage de la surface sur l'écran SDL_FillRect(bare2, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));//charge la couleur de l'écran SDL_BlitSurface(bare2, NULL, ecran, &positionbare2); SDL_FillRect(ball, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));//charge la couleur de l'écran SDL_BlitSurface(ball, NULL, ecran, &positionball); SDL_Flip(ecran);//on initialise l'écran } SDL_FreeSurface(bare); // Libération de la surface SDL_Quit(); return EXIT_SUCCESS; }
Bon par contre je te conseille de faire ca dans une methode séparée, voir plusieurs, parce que va falloir tester les collisions de la balle en y maintenant, plus celle avec les 2 barres en x et en y !
voila
Oki, mais pourquoi chez moi un code qui marche chez toi, ne marche pas chez moi cela est bizarre vous trouvé pas
sinon je vais essayé aussi de le faire avec plusieurs chiffre pour voir le résulta;)
Bonjour,
à rajouter pour que celà tape juste le bord sans mordre.
De plus, tu nous dit que çà ne marche pas. Qu'est ce qui ne marche pas ?
Tu as des messages d'erreur ? Y a des problèmes à l'exécution ? Explique en détail parce que personne ne sait ce qui ne va pas là, on n'est pas trop devins pout tout t'avouer.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 if( ( sens_ball == -1 ) && ( positionball.x <= 1 /*( en fait 0 + rayon balle ? */ ) ) { sens_ball = 1; positionball.x=0+rayon_de_la_balle; } else { /* presque pareil, si la balle va de gauche a droite && que sa position x >= 639 on rebondit, on change de sens quoi */ if( ( sens_ball == 1 ) && ( positionball.x >= 639 /* ( - rayon balle ? */ ) ) { sens_ball = -1; positionball.x=640-rayon_de_la_balle; } }
Non, c est nul d imposer une deplacement de balle égal au rayon.
5bon moi en define c'est guere mieux, car tu voudr peut etre la faire accelerer ou ralentir cette petite balle, mais ca devrait etre rapide a modifier en define...).
Pour les raison qui font que ca me marche pas, ben je sais pas trop, j ai tester ton code avec code::blocks + mingw sous winXp et la derniere version de SDL pour les tests.
Apres peut etre un petit pb de version de lib ou bien nos codes etaient peut etre pas completement identique (une init manquante ou autre...)
Voila
Humm. Exemple : la balle va bientôt sortir de l'écran à droite.
sens_ball=1
on continue d'aller vers la droite. Lorsque l'on arrive à l'extrémité, pour que la balle soit vraiment à l'extrémité de l'écran mais ne sorte pas d'un pixel, donc le
positionball.x=0+rayon_de_la_balle; et positionball.x=640-rayon_de_la_balle;
me paraissait justifier. Sinon peux-tu expliquer en quoi c'est nul ?
Pour le moment, on essaie de faire rebondir la balle dans l'écran sans débordement il me semble. On parlera de la question des raquettes après.
parce que :
en fesant ca tu modifie la position de la balle en x d autant de pixel que le rayon, pourquoi ?
vaudrai pas mieux tester la position de la bordure de la balle avec le bord de l ecran, ca me parait plus correct. Et pis pour l instant c est simple, on gere qu une dimension sans chercher tous les obstacles, je pense que ce bout de code va/doit/devrait ? devenir la fonction ouEstMaBalleEtQuiMeTape pour passer la main a allerOnChangeDeDirectionPourRebondir, parce que la pareil rebondir de gauche a droite c est bien rigolo mais va falloir calculer des trajectoire correcte.
d autant que comme je le disais, si on veux accelerer la balle ? bon effectivement augmenter le diametre de la balle mais bon, ca fait bidouille la.
Vos propositions reviennent au même.
EntreetCode:if(positionball.x >= (640 - rayonball))
il n'y a aucune différence...Code:if((positionball.x + rayonball) >= 640)
Je n'ai pas assez expliqué l'utilité des lignes en rouge j'avoue. Il s'agit de gérer le cas où la balle au cours du déplacement va déborder de l'écran. Pour son déplacement sans risque de collision, on garde ce qui a déjà été écrit.
La balle se dirige vers la droite, elle ne va pas tarder à toucher le bord droit de l'écran. Donc, il va falloir faire quelque chose.
Ce que j'ai ajouté en rouge est juste de placer la balle le plus à droite possible de l'écran sans déborder. Car son déplacement est stable (constante PAS), mais elle peut être <= à PAS pour toucher le bord sans déborder.
Exemple :
admettons PAS = 7, et x du bord droit= 30, rayon balle=5
7 (+5=bord balle) -> 14 (+5=bord balle) -> 21 (+5=bord balle) -> 28 (+5=bord balle), ca donne 32, donc sachant que le bord est à 30, problème, donc on donne à positionball.x=(x du bord droit)-rayon_de_la_balle=30, du coup on ne déborde pas de l'écran. J'espère que ça paraît clair.
Ne pas oublier que le PAS est une constante pour le moment, mais il faudra la transformer en variable quand on voudra accélérer la balle (effet de raquette, niveau supérieur du jeu).
Certes, c'est pour ca qu on teste les colisions avec des superieurs/inferieurs et pas des egalités, et pas par teleportation de balle.
Faire une affectation alors que les tests par rapport aux bords sont deja fait ca me semble un peu tardif.
Dans le bout de code montré tu positionnes la balle mais on a deja detecté la collision, l'action de déplacement qui en resulte est executée apres.
au pire faut intervenir sur les test mais je ne comprends absolument pas cette affectation.
Ok,
si ton programme tourne, change la valeur de PAS s'il te plaît.
Parce que là, c'est sûr avec un PAS de 10 et un bord à 640, on est dans les mêmes multiple, tout va bien. Met un PAS 7 par exemple ou un chiffre dans le genre. Celà ne te dérange pas que ta balle rebondisse genre à 3 pixels du bord ?
Moi, çà me fait bizarre. Le pas risque d'être changé au cours du jeu, alors il ne faudrait pas que la balle rebondisse alors qu'elle n'est pas à 0 pixel du bord.
J'espère que l'on va se comprendre.
si tu consideres qu un rebond a quelques pixels du bord (visible a l oeil ?) est plus choquant qu une teleportation de la balle contre la zone de rebond, ok
Par contre, effectivement, ca souleve un probleme de conception peut etre, on ne pourrait pas conserver un PAS de 1 pixel et jouer sur le temps de tempo de la boucle principale, comme ca on aura plus le probleme precedent ?
Heu, non, il n'y a pas de téléportation. La balle aura le déplacement habituel, c'est un déplacement de valeur "PAS" toutes les xx ms, SAUF [quand elle va toucher un bord -> on évite de toucher le bord en affectant une valeur < à PAS pour coller au bord]
Jouer sur le tempo, alors faut voir les conséquences, c'est peut-être une solution, même si je voyais plutôt un changement de valeur pour le PAS (selon effet de raquette, niveau supérieur de jeu), et surtout un PAS_X et PAS_Y, car si je tape le bord de la raquette, celà fera un PAS_Y > PAS_X logiquement.
bonjour, c bon mon code marche merci beaucoup a vous
cependant je n'ait pas très bien compris se que vous voulez faire la ?
Que la ball rebondisse sur la barre? et non pas sur l'écran (se qui est mon but sinon il n'y aurai jamais de but ^^)
édit: j'ai modifier le code j'ai rajouté une intelligence artificiel pour que la 2eme barre puisse bougé
Sauf, que quand la barre décent elle sort de l'écran, alors qu'en haut elle reste bloqué, je suis entré de réfléchir pour faire que la ball ne rebondisse que contre les barres.Code:
1
2
3
4
5
6
7
8 if ( positionball.y > positionbare2.y) { positionbare2.y ++; } if ( positionball.y < positionbare2.y) { positionbare2.y --; }
Merci de votre aide:)
salut tout le monde,
Bon voilà kent167, suite à notre petite conversation sur le chat, j'espère que ceci t'aidera à aller de l'avant. Mais tu dois absolument repenser ta conception du jeu, et cela doit se traduire par l'utilisation de fonctions dans ton code comme je te l'ai dit. D'ailleurs, je vois que BainE t'en a parlé en faisant allusion aux méthodes. Si tu continues sur cette lancée, ton code deviendra très vite indéchiffrable, surtout au moment où tu devras aborder le problème des angles d'incidence de la balle.
bonne continuation à tous ;)
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 #include <stdlib.h> #include <stdio.h> #include <SDL/SDL.h> #define PAS 4 int main(int argc, char *argv[]) { SDL_Surface *ecran = NULL,*bare = NULL, *ligne=NULL,*bare2=NULL,*ball=NULL; SDL_Rect positionbare,positionligne,positionbare2, positionball; SDL_Event event; int continuer = 1; int tempsPrecedent = 0, tempsActuel = 0; int sens_ball = 1; SDL_Init(SDL_INIT_VIDEO); ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE| SDL_DOUBLEBUF);//charge la fenetre et la taille bare = SDL_CreateRGBSurface(SDL_HWSURFACE, 10, 100, 32, 0, 0, 0, 0); // Allocation de la surface bare2 = SDL_CreateRGBSurface(SDL_HWSURFACE, 10, 100, 32, 0, 0, 0, 0); // Allocation de la surface ball = SDL_CreateRGBSurface(SDL_HWSURFACE, 10, 10, 32, 0, 0, 0, 0); ligne = SDL_CreateRGBSurface(SDL_HWSURFACE, 5, 480, 32, 0, 0, 0, 0); SDL_WM_SetCaption("Pong", NULL); positionbare2.x = 620; positionbare2.y = 180; positionligne.x= (640 / 2)- (2 / 2) ;//coordonné de la ligne positionligne.y=(480 / 2)- (480 / 2); positionbare.x = 10; positionbare.y = 180; positionball.x= 0; positionball.y= 0; SDL_EnableKeyRepeat(10, 10);// répétition des touche unsigned LimiteMin=1; unsigned LimiteMax=640 -11; while(continuer)//boucle event { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: continuer = 0; break; case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_UP: // Flèche haut if (positionbare.y > 0) positionbare.y -= PAS; break; case SDLK_DOWN: // Flèche bas if (positionbare.y < 480-100) positionbare.y += PAS; break; default: break; } if (positionbare.y < 10) {LimiteMin=21;} else {LimiteMin=1;} break; } tempsActuel = SDL_GetTicks(); if( positionball.x < LimiteMin ) { sens_ball = 1; } else { if( positionball.x > LimiteMax) { sens_ball = -1; } } if (tempsActuel - tempsPrecedent > 30) { positionball.x += ( PAS * sens_ball ); tempsPrecedent = tempsActuel; } else { SDL_Delay(30 - (tempsActuel - tempsPrecedent)); } SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0,0)); SDL_FillRect(ligne, NULL, SDL_MapRGB(ecran->format, 255, 255, 255)); SDL_BlitSurface(ligne, NULL, ecran, &positionligne); SDL_FillRect(bare, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));//charge la couleur de l'écran SDL_BlitSurface(bare, NULL, ecran, &positionbare); // Collage de la surface sur l'écran SDL_FillRect(bare2, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));//charge la couleur de l'écran SDL_BlitSurface(bare2, NULL, ecran, &positionbare2); SDL_FillRect(ball, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));//charge la couleur de l'écran SDL_BlitSurface(ball, NULL, ecran, &positionball); SDL_Flip(ecran);//on initialise l'écran } SDL_FreeSurface(bare); // Libération de la surface SDL_Quit(); return EXIT_SUCCESS; }
Salut, tu pourrait m'expliquer se que tu a rajouté dans le code stp, car je n'ai pas compris comment tu a fait pour que la ball ricoche contre la 1ere barre pour que je puisse le répété sur la deuxième
Je n'ai pas apporté beaucoup de modifications à ton code de sorte à respecter ce que tu as effectué jusqu'ici. Cela dit, il reste encore du travail et ce que je t'ai dit précédemment reste valable.
Enfin pour répondre à ta question, sache que la « balle ne ricoche pas contre la barre », car ça, ce n'est qu'une impression humaine ou un effet de virtualisation si tu préfères. Dans la réalité, je n'ai fait que définir une limite qu'elle ne doit pas dépasser lorsque certaines conditions sont réunies (pense au problème de conceptualisation que l'on a déjà abordée hier sur le chat avant mon premier poste).
Dans le code, voilà comment cela se traduit :
J’ai commencé par définir une variable LimiteMin (Limite Minimum) pour laquelle la « balle doit rebrousser chemin » si cette limite venait à être dépassée.
Si la barre de gauche (bare) venait à se trouver dans le champ de la balle, la Limite Minimum doit être modifiée en conséquence de sorte à représenter le bord de la barre et non plus le bord de la fenêtre, ce qui donne :Code:if( positionball.x < LimiteMin ){sens_ball = 1;}
Comme ceci est intégré dans une boucle et que les positions sont constamment recalculées après chaque événement, ça apporte ainsi l'effet de virtualisation recherché.Code:if (positionbare.y < 10) {LimiteMin=21;} else {LimiteMin=1;}
Sache que par la suite ta balle devra être amenée à utiliser différentes directions, et ton code devra prendre en charge ce paramètre.
Voilà, j'espère avoir répondu à ta question.
Bonne continuation à toi.