Novembre 2024 | Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
---|
| | | | 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 | | Calendrier |
|
|
| Des procédures pour la 2D | |
| | |
Auteur | Message |
---|
Jean Claude
Nombre de messages : 5950 Age : 70 Localisation : 83 Var Date d'inscription : 07/05/2009
| Sujet: Re: Des procédures pour la 2D Sam 23 Mai 2015 - 12:40 | |
| Comme je vais m'en servir, j'ai relooké tout ça. Comme on est en Basic j'ai anglicisé le tout, j'ai également fait un controle avec VARIABLE() pour pouvoir insérer dans un code qui utilise no%. pour compter les objets Et pour finir j'ai regroupé les 3 sub pour redimensionner, en une seule. - Code:
-
dim sprites(500,2) : ' jusqu'à 500 sprites ,0)=largeur ,1)=hauteur ,2)=visible/invisible dim NumDerSprite% : ' dernier numéro de sprite créé dim NumSpriteClicked% : ' numéro du sprite trouvé (ou 0 si non trouvé) dim scene_2d% : ' numéro d'objet du scene2d dim nsp% : ' variable réservée pour manipulation des sprites (remplace n%)
scene_2d% = 17 : ' 17 est juste un exemple scene2d scene_2d% : ' créer le scene2d sprite_target_is scene_2d% :' assurer le ciblage end
sub Create_Sprite(px%,py%,image$) if variable("no%")=1 NumDerSprite%=no% : no%=no%+1 :' Ce qui évite la création d'objet en double et tient à jour no% end_if NumDerSprite% = NumDerSprite% + 1 : ' passer au numéro de sprite suivant sprite NumDerSprite% : ' créer le sprite sprites(NumDerSprite%,0) = 200 : ' mémoriser sa largeur sprites(NumDerSprite%,1) = 200 : ' et sa hauteur sprites(NumDerSprite%,2) = 1 : ' marquer "visible" ou 0 pour invisible sprite_file_load NumDerSprite%,image$+".bmp" :' Charge une image dans le sprite sprite_position NumDerSprite%,px%,py% : ' positionner le sprite à l'endroit voulu end_sub
sub Resize_Sprite_WH(nsp%,WSp%,HSp%) ' redimensionner le sprite nsp% en hauteur et largeur (groupage des 3 subs de redimensionnement) if (nsp%<1) or (nsp%>NumDerSprite%) then message "Erreur à la sub Show_sprite(nsp%): Ce N° ("+str$(nsp%)+") n'exsite pas, ou n'est pas un sprite" : terminate Modify_Width_Sprite(nsp%,WSp%) : Modify_Height_Sprite_y(nsp%,HSp%) : Resize_Sprite(nsp%,WSp%,HSp%) end_sub
sub Modify_Width_Sprite(nsp%,WSp%) ' modifier la largeur du sprite nsp% sprite_x_scale nsp%,WSp% : ' ajuster la largeur sprites(nsp%,0) = sprites(nsp%,0)*WSp% : ' et mémoriser end_sub
sub Modify_Height_Sprite_y(nsp%,HSp%) ' modifier la hauteur du sprite nsp% sprite_y_scale nsp%,HSp% : ' ajuster la hauteur sprites(nsp%,1) = sprites(nsp%,1)*HSp% : ' et mémoriser end_sub
sub Resize_Sprite(nsp%,WSp%,HSp%) ' redimensionner le sprite nsp% sprite_scale nsp%,WSp%,HSp% : ' ajuster largeur et hauteur sprites(nsp%,0) = sprites(nsp%,0)*WSp% : ' et mémoriser la largeur sprites(nsp%,1) = sprites(nsp%,1)*HSp% : ' et mémoriser la hauteur end_sub
sub Hide_Sprite(nsp%) ' Rendre le sprite invisible en le déplaçant hors cadre ' ATTENTION: différence avec SPRITE_HIDE => le sprite restera "SHOW", mais en dehors de l'écran, donc invisible if (nsp%<1) or (nsp%>NumDerSprite%) then message "Erreur à la sub Show_sprite(nsp%): Ce N° ("+str$(nsp%)+") n'exsite pas, ou n'est pas un sprite" : terminate if sprites(nsp%,2)= 1 : ' est-ce que le sprite est visible ? sprite_x_position nsp%,sprite_x_position(nsp%) + 4000 : ' déplacer hors de la vue sprites(nsp%,2) = 0 : ' signaler "invisible" end_if end_sub
sub Show_Sprite(nsp%) ' Rendre le sprite visible en le replaçant dans le cadre ' ATTENTION: différence avec SPRITE_SHOW => le sprite était visible, mais en dehors de l'écran if (nsp%<1) or (nsp%>NumDerSprite%) then message "Erreur à la sub Show_sprite(nsp%): Ce N° ("+str$(nsp%)+") n'exsite pas, ou n'est pas un sprite" : terminate if sprites(nsp%,2)= 0 : ' est-ce que le sprite est invisible ? sprite_x_position nsp%,sprite_x_position(nsp%) - 4000 : ' replacer dans la partie visible sprites(nsp%,2) = 1 : ' signaler "visible" end_if end_sub
sub What_Srite_Is_Clicked() ' retourne NumSpriteClicked% (sprite trouvé) dim_local i%, px%, py%, xs%, ys% NumSpriteClicked% = 0 : ' supposer "non trouvé" if number_click<>scene_2d% then message "Clic en dehors du scene2d !" : exit_sub if NumDerSprite%=0 then message "Aucun Sprite Existant" : exit_sub px% = mouse_x_left_down(scene_2d%) : ' mémoriser la position horizontale du clic py% = mouse_y_left_down(scene_2d%) : ' mémoriser la position verticale du clic for i%=1 to NumDerSprite% xs% = sprite_x_position(i%) : ' mémoriser la position horizontale du sprite i% ys% = sprite_y_position(i%) : ' mémoriser la position verticale dusprite i% if (xs%<px%) : ' le bord gauche du sprite est plus à gauche que l'abscisse du clic ? if (ys%<py%) : ' le bord haut du sprite est plus haute que l'ordonnée du sprite ? if xs%+sprite(i%,0)>=px% : ' le bord droit du sprite est plus à droite que l'abscisse du clic ? if ys%+sprite(i%,1)>=py% : ' le bord bas du sprite est plus en bas que l'ordonnée du clic ? NumSpriteClicked% = i% : ' alors, on a trouvé exit_sub : ' et on sort end_if : ' fin test sur le bord bas du sprite end_if : ' fin test sur le bord droit du sprite end_if : ' fin test sur le bord haut du sprite end_if : ' fin test sur le bord gauche du sprite next i% : ' fin boucle sur les sprites end_sub
A+ Il me reste à les testées tester Rééditer 23/05/2015 à 16:42 (corrections suivant remarque de Jicehel)
Dernière édition par Jean Claude le Sam 23 Mai 2015 - 16:43, édité 3 fois | |
| | | papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Re: Des procédures pour la 2D Sam 23 Mai 2015 - 12:56 | |
| Bravo angliciseur !. Il te reste à les testées tester A la prochaine | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Sam 23 Mai 2015 - 15:03 | |
| erreur dans la sub: sub redimensionner_sprite_xy(n%,cx,cy) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_scale n%,cx,cy : ' ajuster largeur et hauteur sprites(n%,0) = sprites(n%,0)*cx : ' et mémoriser la largeur sprites(n%,1) = sprites(n%,1)*cy : ' et mémoriser la hauteur end_sub
(J'ai remplacé c par cx et cy) | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Sam 23 Mai 2015 - 15:05 | |
| erreur dans las sub: sub chercher_sprite_selon_clic() dim_local i%, x%, y%, xs%, ys% sprite_trouve% = 0 : ' supposer "non trouvé" if number_click<>scene_2d% then exit : ' on n'a pas cliqué dans le scene2d ? if nsprite%=0 then exit_sub : ' pas de sprites créés ? x% = mouse_x_left_down(scene_2d%) : ' mémoriser la position horizontale du clic y% = mouse_y_left_down(scene_2d%) : ' mémoriser la position verticale du clic for i%=1 to nsprite% xs% = sprite_x_position(i%) : ' mémoriser la position horizontale du sprite i% ys% = sprite_y_position(i%) : ' mémoriser la position verticale dusprite i% if (xs%<x%) : ' le bord gauche du sprite est plus à gauche que l'abscisse du clic ? if (ys%<y%) : ' le bord haut du sprite est plus haute que l'ordonnée du sprite ? if xs%+sprites(i%,0)>=x% : ' le bord droit du sprite est plus à droite que l'abscisse du clic ? if ys%+sprites(i%,1)>=y% : ' le bord bas du sprite est plus en bas que l'ordonnée du clic ? sprite_trouve% = i% : ' alors, on a trouvé exit_sub : ' et on sort end_if : ' fin test sur le bord bas du sprite end_if : ' fin test sur le bord droit du sprite end_if : ' fin test sur le bord haut du sprite end_if : ' fin test sur le bord gauche du sprite next i% : ' fin boucle sur les sprites end_sub
au deuxième if, c'était marqué xy% au lieu de ys% et il manquait les s au tableau sprites | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Sam 23 Mai 2015 - 15:21 | |
| J'ai fais un petit programme de test: PS: j'ai fais une modification du code de test car quand on charge l'image dans le sprite, il perd ses coordonnées. On peut donc faire une petite procédure pour charger l'image et remettre le sprite à son emplacement initial. Dans le programme de test, j'ai tout mis dans le code principal. En tout cas, on peut bien tester le test du clic sur le sprite qui fonctionne bien - Code:
-
dim sprites(500,2) : ' jusqu'à 500 sprites ,0)=largeur ,1)=hauteur ,2)=visible/invisible dim nsprite% : ' dernier numéro de sprite créé dim sprite_trouve% : ' numéro du sprite trouvé (ou 0 si non trouvé) dim scene_2d% : ' numéro d'objet du scene2d dim n_croix%, n_cercle% : ' numero du sprite croix et du sprite cercle dim s$ : ' chaine de caractères dim xsprite%,ysprite%
label clic width 0, 600 : height 0,600 scene_2d% = 17 : ' juste un exemple scene2d scene_2d% : ' créer le scene2d width scene_2d%, width(0) - 20 : height scene_2d%, height(0) -20 : ' redimensionnement du scene2d sprite_target_is scene_2d% : ' assurer du bon ciblage ' Creation du sprite croix creer_sprite(10,10) : n_croix% = nsprite% xsprite%= sprite_x_position(n_croix%) : ysprite%= sprite_y_position(n_croix%) picture 100 : height 100,200 : width 100,200 2d_target_is 100 : 2d_line 0,0,200,200 : 2d_line 200,0,0,200 : file_save 100,"sprite_croix.bmp" sprite_file_load n_croix%,"sprite_croix.bmp" : file_delete "sprite_croix.bmp" sprite_position n_croix%,xsprite%,ysprite% redimensionner_sprite_xy(n_croix%,0.1) ' Creation du sprite cercle creer_sprite(400,400) : n_cercle% = nsprite% xsprite%= sprite_x_position(n_cercle%) : ysprite%= sprite_y_position(n_cercle%) cls : color 100, 255,0,0 : 2d_pen_width 5 : 2d_circle 100,100,100 : file_save 100,"sprite_cercle.bmp" sprite_file_load n_cercle%,"sprite_cercle.bmp" : file_delete "sprite_cercle.bmp" sprite_position n_cercle%,xsprite%,ysprite% redimensionner_sprite_xy(n_cercle%,0.33) 2d_target_is 0 : delete 100 on_click scene_2d%,clic end
clic: chercher_sprite_selon_clic() if sprite_trouve% = 0 caption 0, "Vous n'avez pas cliqué sur un sprite" else s$= "" if sprite_trouve% = n_croix% s$ = "croix" else s$ = "cercle" end_if if s$="" then s$="sprite non suivi" caption 0, "Vous avez cliqué sur le sprite : " + s$ end_if return
sub creer_sprite(x%,y%) nsprite% = nsprite% + 1 : ' passer au numéro de sprite suivant sprite nsprite% : ' créer le sprite sprites(nsprite%,0) = 200 : ' mémoriser sa largeur sprites(nsprite%,1) = 200 : ' et sa hauteur sprites(nsprite%,2) = 1 : ' marquer "visible" sprite_position nsprite%,x%,y% : ' positionner le sprite à l'endroit voulu end_sub
sub redimensionner_sprite_x(n%,c) x% = sprite_x_position n% : y% = sprite_y_position n% if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_x_scale n%,c : ' ajuster la largeur sprites(n%,0) = sprites(n%,0)*c : ' et mémoriser end_sub
sub redimensionner_sprite_y(n%,c) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_y_scale n%,c : ' ajuster la hauteur sprites(n%,1) = sprites(n%,1)*c : ' et mémoriser end_sub
sub redimensionner_sprite_xy(n%,cx,cy) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_scale n%,cx,cy : ' ajuster largeur et hauteur sprites(n%,0) = sprites(n%,0)*cx : ' et mémoriser la largeur sprites(n%,1) = sprites(n%,1)*cy : ' et mémoriser la hauteur end_sub
sub cacher_sprite(n%) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser if sprites(n%,2)=1 : ' est-ce que le sprite est visible ? sprite_x_position n%,sprite_x_position(n%) + 4000 : ' déplacer hors de la vue sprites(n%,2) = 0 : ' signaler "invisible" end_if end_sub
sub montrer_sprite(n%) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser if sprites(n%,2)=0 : ' est-ce que le sprite est invisible ? sprite_x_position n%,sprite_x_position(n%) - 4000 : ' replacer dans la partie visible sprites(n%,2) = 1 : ' signaler "visible" end_if end_sub
sub chercher_sprite_selon_clic() dim_local i%, x%, y%, xs%, ys% sprite_trouve% = 0 : ' supposer "non trouvé" if number_click<>scene_2d% then exit : ' on n'a pas cliqué dans le scene2d ? if nsprite%=0 then exit_sub : ' pas de sprites créés ? x% = mouse_x_left_down(scene_2d%) : ' mémoriser la position horizontale du clic y% = mouse_y_left_down(scene_2d%) : ' mémoriser la position verticale du clic for i%=1 to nsprite% xs% = sprite_x_position(i%) : ' mémoriser la position horizontale du sprite i% ys% = sprite_y_position(i%) : ' mémoriser la position verticale dusprite i% if (xs%<x%) : ' le bord gauche du sprite est plus à gauche que l'abscisse du clic ? if (ys%<y%) : ' le bord haut du sprite est plus haute que l'ordonnée du sprite ? if (xs%+sprites(i%,0))>=x% : ' le bord droit du sprite est plus à droite que l'abscisse du clic ? if (ys%+sprites(i%,1))>=y% : ' le bord bas du sprite est plus en bas que l'ordonnée du clic ? sprite_trouve% = i% : ' alors, on a trouvé exit_sub : ' et on sort end_if : ' fin test sur le bord bas du sprite end_if : ' fin test sur le bord droit du sprite end_if : ' fin test sur le bord haut du sprite end_if : ' fin test sur le bord gauche du sprite next i% : ' fin boucle sur les sprites end_sub | |
| | | Jean Claude
Nombre de messages : 5950 Age : 70 Localisation : 83 Var Date d'inscription : 07/05/2009
| Sujet: Re: Des procédures pour la 2D Sam 23 Mai 2015 - 16:43 | |
| Bien vu Jicehel, j'ai corrigé ma version ci-dessus.
A+ | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Des procédures pour la 2D Sam 23 Mai 2015 - 22:59 | |
| J'ai apporté quelques petites modifications à mes SUBs: - application des différentes corrections mentionnées dans vos posts ci-dessus - ajout d'un paramètre à creer_sprite() pour passer le numéro d'objet d'un IMAGE Panoramic contenant l'image à afficher dans le sprite. Ainsi, il n'y a plus de problème de positionnement - dans chercher_sprite_selon_clic(), j'ai inversé la boucle extérieure pour la parcourir du dernier sprite jusqu'au premier. Ainsi, pour l'identification, on tient compte de la superposition des sprites car le dernier créé est toujours au-dessus de l'avant-dernier, etc. Voici le code modifié. Il crée 2 sprites, et on peut cliquer dessus pour les identifier, constatant que le sprite bleu est identifié partout comme sprite 2, même là où il recouvre le sprite rouge qui est le sprite 1: - Code:
-
label clic
dim sprites(500,2) : ' jusqu'à 500 sprites ,0)=largeur ,1)=hauteur ,2)=visible/invisible dim nsprite% : ' dernier numéro de sprite créé dim sprite_trouve% : ' numéro du sprite trouvé (ou 0 si non trouvé) dim scene_2d% : ' numéro d'objet du scene2d dim i%
scene_2d% = 17 : ' juste un exemple scene2d scene_2d% : ' créer le scene2d sprite_target_is scene_2d% : ' assurer du bon ciblage on_click scene_2d%,clic
full_space scene_2d% picture 10 : hide 10 : width 10,200 : height 10,200 image 11 2d_target_is 10
color 10,255,0,0 2d_image_copy 11,0,0,200,200 creer_sprite(50,50,11)
color 10,0,0,255 2d_image_copy 11,0,0,200,200 creer_sprite(120,120,11)
color 10,255,255,0 2d_image_copy 11,0,0,200,200 creer_sprite(80,180,11)
for i%=121 to 350 sprite_x_position 2,i% display next i%
for i%=349 to 120 step -1 sprite_x_position 2,i% display next i%
end
clic: chercher_sprite_selon_clic() if sprite_trouve%>0 message "clic sur sprite "+str$(sprite_trouve%) else message "aucun sprite cliqué" end_if return
sub creer_sprite(x%,y%,img%) nsprite% = nsprite% + 1 : ' passer au numéro de sprite suivant sprite nsprite% : ' créer le sprite sprites(nsprite%,0) = 200 : ' mémoriser sa largeur sprites(nsprite%,1) = 200 : ' et sa hauteur sprites(nsprite%,2) = 1 : ' marquer "visible" if img%>0 then sprite_image_load nsprite%,img% : ' copier une image dans le sprite sprite_position nsprite%,x%,y% : ' positionner le sprite à l'endroit voulu display end_sub
sub redimensionner_sprite_x(n%,c) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_x_scale n%,c : ' ajuster la largeur sprites(n%,0) = sprites(n%,0)*c : ' et mémoriser end_sub
sub redimensionner_sprite_y(n%,c) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_y_scale n%,c : ' ajuster la hauteur sprites(n%,1) = sprites(n%,1)*c : ' et mémoriser end_sub
sub redimensionner_sprite_xy(n%,cx,cy) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_scale n%,cx,cy : ' ajuster largeur et hauteur sprites(n%,0) = sprites(n%,0)*cx : ' et mémoriser la largeur sprites(n%,1) = sprites(n%,1)*cy : ' et mémoriser la hauteur end_sub
sub cacher_sprite(n%) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser if sprites(n%,2)=1 : ' est-ce que le sprite est visible ? sprite_x_position n%,sprite_x_position(n%) + 4000 : ' déplacer hors de la vue sprites(n%,2) = 0 : ' signaler "invisible" end_if end_sub
sub montrer_sprite(n%) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser if sprites(n%,2)=0 : ' est-ce que le sprite est invisible ? sprite_x_position n%,sprite_x_position(n%) - 4000 : ' replacer dans la partie visible sprites(n%,2) = 1 : ' signaler "visible" end_if end_sub
sub chercher_sprite_selon_clic() dim_local i%, x%, y%, xs%, ys% sprite_trouve% = 0 : ' supposer "non trouvé" if number_click<>scene_2d% then exit : ' on n'a pas cliqué dans le scene2d ? if nsprite%=0 then exit_sub : ' pas de sprites créés ? x% = mouse_x_left_down(scene_2d%) : ' mémoriser la position horizontale du clic y% = mouse_y_left_down(scene_2d%) : ' mémoriser la position verticale du clic for i%=nsprite% to 1 step -1 xs% = sprite_x_position(i%) : ' mémoriser la position horizontale du sprite i% ys% = sprite_y_position(i%) : ' mémoriser la position verticale dusprite i% if (xs%<x%) : ' le bord gauche du sprite est plus à gauche que l'abscisse du clic ? if (ys%<y%) : ' le bord haut du sprite est plus haute que l'ordonnée du sprite ? if xs%+sprites(i%,0)>=x% : ' le bord droit du sprite est plus à droite que l'abscisse du clic ? if ys%+sprites(i%,1)>=y% : ' le bord bas du sprite est plus en bas que l'ordonnée du clic ? sprite_trouve% = i% : ' alors, on a trouvé exit_sub : ' et on sort end_if : ' fin test sur le bord bas du sprite end_if : ' fin test sur le bord droit du sprite end_if : ' fin test sur le bord haut du sprite end_if : ' fin test sur le bord gauche du sprite next i% : ' fin boucle sur les sprites end_sub EDIT J'ai ajouté un troisième sprite, pour le plaisir...
Dernière édition par Klaus le Sam 23 Mai 2015 - 23:35, édité 1 fois | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Sam 23 Mai 2015 - 23:20 | |
| | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 1:03 | |
| Et une SUB de plus pour tester les collisions ! Modifs dans l'existant: 1. Le tableau des sprites a une colonne de plus qui est à charger par 0 si le sprite est "pénétrable" (ne déclanche pas de collision si un autre sprite le touche) ou 1 si le sprite est "impénétrable" ou "dur" (déclenche une collision si un autre sprite le touche). 2. la SUB creer-sprite a un paramètre supplémentaire qui est 0 pour "pénétrable" et 1 pour "impénétrable". La nouvelle colonne du tableau sprites sera chargée avec cette valeur. 3. Une SUB tester_si_collision ayant pour paramètre le numéro du sprite qui bouge, et une variable de direction (1=gauche, 2=haut, 3=droite, 4=bas) 4. une variable sprite_collision% qui contient 0 s'il n'y a pas de collision, ou le numéro de sprite touché dans le sens de la direction indiquée (évidemment, uniquement des sprites "durs"). Voici le code: - Code:
-
label clic
dim sprites(500,3) : ' jusqu'à 500 sprites : ' ,0)=largeur ,1)=hauteur ,2)=visible/invisible ,3)=impénétrable dim nsprite% : ' dernier numéro de sprite créé dim sprite_trouve% : ' numéro du sprite trouvé (ou 0 si non trouvé) dim sprite_collision% : ' numéro du sprite touché par une collision dim scene_2d% : ' numéro d'objet du scene2d dim i%
scene_2d% = 17 : ' juste un exemple scene2d scene_2d% : ' créer le scene2d sprite_target_is scene_2d% : ' assurer du bon ciblage on_click scene_2d%,clic
full_space 0 full_space scene_2d% picture 10 : hide 10 : width 10,200 : height 10,200 image 11 2d_target_is 10
color 10,255,0,0 2d_image_copy 11,0,0,200,200 creer_sprite(50,50,11,1) : ' sprite rouge impénétrable
color 10,0,0,255 2d_image_copy 11,0,0,200,200 : ' sprite bleu impénétrable creer_sprite(400,120,11,1)
color 10,255,255,0 2d_image_copy 11,0,0,200,200 : ' sprite jaune pénétrable creer_sprite(80,180,11,0)
for i%=399 to 0 step -1 sprite_x_position 2,i% display tester_si_collision(2,1) if sprite_collision%>0 message "collision avec sprite "+str$(sprite_collision%) exit_for end_if next i%
for i%=sprite_x_position(2) to 400 sprite_x_position 2,i% display next i%
end
clic: chercher_sprite_selon_clic() if sprite_trouve%>0 message "clic sur sprite "+str$(sprite_trouve%) else message "aucun sprite cliqué" end_if return
sub creer_sprite(x%,y%,img%,dur%) nsprite% = nsprite% + 1 : ' passer au numéro de sprite suivant sprite nsprite% : ' créer le sprite sprites(nsprite%,0) = 200 : ' mémoriser sa largeur sprites(nsprite%,1) = 200 : ' et sa hauteur sprites(nsprite%,2) = 1 : ' marquer "visible" sprites(nsprite%,3) = dur% : ' marquer 0="pénétrable" ou 1="impénétrable" if img%>0 then sprite_image_load nsprite%,img% : ' copier une image dans le sprite sprite_position nsprite%,x%,y% : ' positionner le sprite à l'endroit voulu display end_sub
sub redimensionner_sprite_x(n%,c) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_x_scale n%,c : ' ajuster la largeur sprites(n%,0) = sprites(n%,0)*c : ' et mémoriser end_sub
sub redimensionner_sprite_y(n%,c) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_y_scale n%,c : ' ajuster la hauteur sprites(n%,1) = sprites(n%,1)*c : ' et mémoriser end_sub
sub redimensionner_sprite_xy(n%,cx,cy) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser sprite_scale n%,cx,cy : ' ajuster largeur et hauteur sprites(n%,0) = sprites(n%,0)*cx : ' et mémoriser la largeur sprites(n%,1) = sprites(n%,1)*cy : ' et mémoriser la hauteur end_sub
sub cacher_sprite(n%) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser if sprites(n%,2)=1 : ' est-ce que le sprite est visible ? sprite_x_position n%,sprite_x_position(n%) + 4000 : ' déplacer hors de la vue sprites(n%,2) = 0 : ' signaler "invisible" end_if end_sub
sub montrer_sprite(n%) if (n%<1) or (n%>nsprite%) then exit_sub : ' sécuriser if sprites(n%,2)=0 : ' est-ce que le sprite est invisible ? sprite_x_position n%,sprite_x_position(n%) - 4000 : ' replacer dans la partie visible sprites(n%,2) = 1 : ' signaler "visible" end_if end_sub
sub chercher_sprite_selon_clic() dim_local i%, x%, y%, xs%, ys% sprite_trouve% = 0 : ' supposer "non trouvé" if number_click<>scene_2d% then exit : ' on n'a pas cliqué dans le scene2d ? if nsprite%=0 then exit_sub : ' pas de sprites créés ? x% = mouse_x_left_down(scene_2d%) : ' mémoriser la position horizontale du clic y% = mouse_y_left_down(scene_2d%) : ' mémoriser la position verticale du clic for i%=nsprite% to 1 step -1 : ' boucle sur tous les sprites xs% = sprite_x_position(i%) : ' mémoriser la position horizontale du sprite i% ys% = sprite_y_position(i%) : ' mémoriser la position verticale dusprite i% if (xs%<x%) : ' le bord gauche du sprite est plus à gauche que l'abscisse du clic ? if (ys%<y%) : ' le bord haut du sprite est plus haute que l'ordonnée du sprite ? if xs%+sprites(i%,0)>=x% : ' le bord droit du sprite est plus à droite que l'abscisse du clic ? if ys%+sprites(i%,1)>=y% : ' le bord bas du sprite est plus en bas que l'ordonnée du clic ? sprite_trouve% = i% : ' alors, on a trouvé exit_sub : ' et on sort end_if : ' fin test sur le bord bas du sprite end_if : ' fin test sur le bord droit du sprite end_if : ' fin test sur le bord haut du sprite end_if : ' fin test sur le bord gauche du sprite next i% : ' fin boucle sur les sprites end_sub
sub tester_si_collision(n%,dir%) dim_local i%, x%, y%, w%, h%, xs%, ys%, ws, hs sprite_collision% = 0 : ' supposer "pas de collision" if nsprite%<2 then exit_sub : ' pas de collisions possibles ? if sprites(n%,2)=0 then exit_sub : ' le sprite mobile est "invisible" ? if sprites(n%,3)=0 then exit_sub : ' le sprite mobile est "pénétrable" ? x% = sprite_x_position(n%) : ' position horizontale du sprite en movement y% = sprite_y_position(n%) : ' position verticale du sprite en movement ws = sprites(n%,0) : ' largeur du sprite en movement hs = sprites(n%,1) : ' hauteur du sprite en movement for i%=nsprite% to 1 step -1 : ' boucle sur tous les sprites if i%<>n% : ' on est sur un sprite autre que celui qui bouge ? if sprites(i%,3)<>0 : ' sprite en dur ? xs% = sprite_x_position(i%) : ' position horizontale du sprite à tester ys% = sprite_y_position(i%) : ' position verticale du sprite à tester ws = sprites(i%,0) : ' largeur du sprite à tester hs = sprites(i%,1) : ' hauteur du sprite à tester select dir% : ' distinction par direction du mouvement case 1: ' gauche if (xs%+ws)>=(x%-1) then sprite_collision% = i% case 2: ' haut if (ys%+hs)>=(y%-1) then sprite_collision% = i% case 3: ' droite if (xs%-1)<=(x%+w%) then sprite_collision% = i% case 4: ' bas if (ys%-1)<=(y%+h%) then sprite_collision% = i% end_select : ' fin distintion par direction if sprite_collision%>0 then exit_sub end_if : ' fin test sprite en dur end_if : ' fin test sur sprite "autre" next i% : ' fin boucle sur les sprites end_sub
On peut en faire, des choses en Panoramic pur... EDIT J'ai corrigé un petit bug. Maintenant, le sprite bleu est créé loin à droite. Puis il se deplace à gauche jusqu'à entrer en collision avec le sprite rouge, en se glissant sous le sprite jaune. Au cintact du sprite rouge, il y a un message, puis le sprite bleu retourne à sa position de départ. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 9:21 | |
| Regardez ce code ci-dessus - avec gestion des collisions, en 100 % Panoramic ! | |
| | | Jean Claude
Nombre de messages : 5950 Age : 70 Localisation : 83 Var Date d'inscription : 07/05/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 9:28 | |
| Merci Klaus, Je ne vais pas manqué de tester les collisions, je te tiendrais au courant. Si tu regardes le poste "projet débarquement" tu trouveras un début d’application de tes SUB(s) que j'ai relooké, mais qui sont bien les tienne.
A+ | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 9:39 | |
| Je pense que Klaus n'en prendra pas ombrage. Il donne le principe mais après c'est à adapter selon les besoin spécifiques. Par exemple, là on utilise le pricipe de détection rectangle en supposant que tout le sprite soit à considérer. Dans certains cas, on ne devra prendre qu'une partie du sprite pour la détection. Dans ce cas, il faudra donc passer par un procédure de détection classique. De même si le sprite est rond ou a un forme spécifique et qu'il est assez gros (pour les petits sprites même de forme complexe, mieux vaut utiliser la détection de collision par rectangles), il faudra utiliser une procédure de détection adaptée (voir articles). | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 9:58 | |
| Actuellement, Panoramic ne contient pas de détection de collision dans le monde 2D. Et un sprite est toujours rectangulaire. Il est carré à sa création, puis peut être déformé, mais reste toujours rectangulaire, ce dont ma SUB tient compte.
Certes, un sprite peut avoir une couleur de transparence (le noir), ce qui donne l'illusion que le sprite a une autre forme. Si l'on veut détecter une collision sur les parties non-noires, il faudra pousser l'algorithme un peu plus loin, et ce aussi bien pour le sprite en mouvement que pour le sprite fixe rencontré sur son chemin.Et comme on ne peut pas interroger les pixels d'un sprite, il faudrait garder en mémoire l'image de chaque sprite, y compris ses déformations par les commandes scale, afin de pouvoir travailler au niveau des pixels. Autant dire que c'est impossible, avec des temps de calcul raisonnables. La seule possibilité viable, ce serait de mémoriser quelques caractéristiques spécifiques à chaque sprite, pour donner la définition d'une forme simple englobant la partie utile du sprite (sous-rectangle, cercle ou ellipse, triangle stc. Et de moduler la détection par rapport à ces éléments. Ca complexifie un peu, mais c'est jouable. Mais là encore, il faudra adapter ces paramètres à chaque commande scale, ce qui n'est pas une mince affaire ! | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 10:53 | |
| Tout à fait, cela dépend de l'usage. En règle général, il n'y a qu'un gros sprite qui né nécesite un traitement spécial ou deux. Par exemple dans un jeu de combat entre 2 personnages, on a 2 sprites mais pour savoir s'il y a collision ou non entre ces 2 rectangles, il y a plusieurs solutions: Soit la détection par la couleur des pixels, soit la solution par masque ou encore la plus pratique pour ce cas de figure: la définition de sous rectangles adaptés à ce que l'on souhaite. Par exemple un rectangle pour chaque membre (tête, corps, bras, jambes) et un pour l'arme. Ce qui ferait 5 sous rectangles par sprite. Ca nécessite un fichier de définition pour chaque sprite donc un peu de boulot en amont pour faire le jeu mais après ça simplifie carrément la programmation.
Pour un jeu type Arkanoid (un case brique) pas besoin de faire un détection de collision très précise car la balle (ronde) est assez petite pour que la détection standard suffise, mais supposons que l'on ajoute des options telles que le grossissement de la boule par 10. Là, un détection par carré donnerait des résultats visiblement incohérent est l'on est donc "obligé" pour que le joueur ne se rende pas compte de la supercherie, d'utiliser les procédure de détection de collision adaptée (voir article sur les collisions). Il n'y a qu'une balle(sauf si on ajoute aussi un bonus multi balles ..) et oui, il faut gérer ses paramètres spécifiques, mais ce n'et pas grave.
Le principal c'est qu'avec tes procédures, on ait le principe général. A nous d'adapter après selon nos besoins. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 11:04 | |
| J'entends bien, Jicehel. Le problème se pose là où il faudrait faire une détection au niveau des pixels, car on ne peut pas le faire par rapport aux couleurs. Les fonctions color_pixel_xxx ne fonctionnent pas sur un scene2d, et de toutes façons, le scene 2d me montre qu'une fusion uniforme entre le fond et l'ensemble des sprites. On n'a aucun moyen de savoir à quel sprite appartient quel pixel. Imagine plusieurs sprites avec des zones transparentes (noir) qui se superposent. A quel sprite appartient un point particulier ? Mystère... | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 11:13 | |
| Pour ça, il y a le système du masque. En fait tu as ton sprite affiché et son frère qui va être monochrome et ne contiendra que les zones actives (celles sur lequel tu dois pouvoir cliquer). Tu fais le test de détection dans un picture par exemple par rapport à ce masque et non par rapport au sprite affiché. Je vais commencer à écrire l'article sur les collisions plus complexes pour expliquer ça et le tester en vrai (car là, je ne connais que la partie théorique. Il faut que je le test dans Panoramic, mais comme Jack va sortir une version qui inclue déjà des détections de collisions, j'avais mis en standby pour ne pas réinventer la roue si c'était déjà inclu dans le moteur de base...) | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 11:32 | |
| Le masque est une idée séduisante, sur le plan théorique. Mais il y a un certain nombre d'écueils.
Le premier d'entre eux, c'est qu'il faut, non seulement construire un masque pour tous les sprites, mais également le conserver, tout au long de la vie du sprite. Ce qui peut faire beaucoup.
Ensuite, et c'est plus délicat: lorsque tu déformes un sprite par les commandes SCALE, il faut également déformer le masque, ce qui n'est pas simple du tout ! Et je pense que le principal obstacle viendra de là.
Et finalement, le travail au niveau des pxels est très lent, aussi bien en Panoramic qu'en Delphi. C'est pourquoi, au niveau de mes fonctions de traitement d'image dans KGF.dll, j'utilise pa propriété SCANLINE des objets BITMAP afin de donner des performances acceptables. Mais Panoramic ne connait pas SCANLINE... | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 12:16 | |
| Dans un poste ci-dessus, tu suggérais: - Citation :
- Par exemple un rectangle pour chaque membre (tête, corps, bras, jambes) et un pour l'arme.
J'aurais une autre suggestion à faire. Ces différents éléments d'un personnage 2D pourraient être réalisés chacun sous forme d'un sprite séparé. Et l'ensemble des sprites serait déplacé si le personnage se déplace, ce qui est facile. De plus, on pourrait animer le déplacement d'un bras tenant une arme, par exemple, en déplaçant simplement les sprites concernés, Panoramic se chargeant de la représentation graphique. Cai si un personnage complexe était compose d'un seul seul sprite, il faudrait recalculer son image à chaque movement, y compris son masque, tout en tenant compte des déformations en vigueur par les commandes SCALE... une galère. Et représenter un personnage complexe par un ensemble de sprites a un autre avantage: la détection des collisions par mon mécanisme fonctionnera très bien, donnant directement la partie touchée du personnage: la poitrine, la tête, le bras, le bouclier, l'épée, etc. De quoi largement faciliter la gestion des évènements. EDIT Une méthode d'implémentation pourrait être la création d'une DLIST par personnage complexe. Chaque élément de la DLIST contiendrait un des numéros de sprite composant le personnage. Ainsi, le personnage pourra facilement évoluer en ajoutant une arme, déposant une partie d'équipement, perdre un bras ou la tête... Et pour déplacer un personnage, on déplace de façon synchrone tous les sprites contenus dans la DLIST du personnage. On pourrait même ajouter la colonne 4 au tableau sprites(..,..), et cette colonne contiendrait le numéro de la DLIST du personnage complexe (ou 0 s'il s'agit d'un sprite simple). Ainsi, à la collision, on ne connaîtrait pas seulement le sprite, mais également le personnage complexe dont il fait partie. | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 12:29 | |
| Oui tout dépend. En règle général, on utilise pas le scale pour le sprite une fois que l'image est chargée. Quand on charge une image pour le sprite, elle est optimisée au niveau du rendu pour une taille donnée et n'est plus modifiée en taille (mais je dis bien en règle générale car dans les jeux, les façons de faire dépendent du jeu que l'on veut faire). Le masque peut donc être unique et chargé une fois pour toute avec le sprite. Je ne dis pas que cette méthode convient à tous les usages. C'est une méthode qui convient à certains types de jeux. Comme la méthode des zones des sprites. Dans un jeu de combat, on n'utilisera jamais le scale sur le sprite car le sprite ne change jamais de taille, comme dans le cas d'un shoot them up a déplacement horizontal ou vertical ou un casse brique, un wargame, un jeu de dames ou d'échecs, un jeu de cartes, etc...
Tu peux prévoir un mécanisme général et des procédures dans lesquelles l'utilisateur peut piocher, mais il doit quand même les adapter pour les optimiser en fonction du jeu qu'il veut faire. Par exemple la détection du clic telle que tu l'as donné fonctionne parfaitement pour un pion de dames ou d'échecs, un wargame ou un jeu de cartes.
Pour un casse-briques ou un shoot them up, ça n'a aucun interet car ça n'a pas de sens dans le jeu (sauf si l'on mets des boutons dans la scene_2d, ce qui n'est pas ce que l'on fait habituellement dans Panoramic, mais qui pourrait être géré comme ça aussi) | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 12:39 | |
| Et qu'est-ce que tu penses de mon idée d'un personnage complexe composé de plusieurs sprites qui pourraient être animés individuellement pour représenter on coup d'épée, par exemple, ou simultanément pour représenter un déplacement du personnage ? | |
| | | Jean Claude
Nombre de messages : 5950 Age : 70 Localisation : 83 Var Date d'inscription : 07/05/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 13:39 | |
| Message annulée suite à une erreur de ma part A+
Dernière édition par Jean Claude le Dim 24 Mai 2015 - 16:53, édité 1 fois | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 14:11 | |
| C'est exactement un exemple de ce que je voulais expliquer. Les procédures de Klaus donne le principe et après c'est à chacun de les adapter en fonction de leurs besoins ou des leurs habitudes comme toi avec le numéro de sprite que tu décale par rapport aux objets (ce qui n'est pas utile puisque les numetos de sprites sont indépendants des numéros d'objets, mais bon c'est ton droit de vouloir des numéros uniques ) La procédure n'a pas vocation a être universelle, c'est un canevas avec des principes pour que l'on puisse faire ce que l'on veut | |
| | | Jean Claude
Nombre de messages : 5950 Age : 70 Localisation : 83 Var Date d'inscription : 07/05/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 14:18 | |
| Non Jicehel, les numéros de SRITE ne sont pas indépendants des numéros d'objet Panoramic.
Je vais essayer de démonter ce que je dis, plus tard car j'avance bien sur mon jeu et c'est comme ça que j'ai découvert le problème.
A+
Dernière édition par Jean Claude le Dim 24 Mai 2015 - 16:48, édité 1 fois | |
| | | Jicehel
Nombre de messages : 5947 Age : 52 Localisation : 77500 Date d'inscription : 18/04/2011
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 14:45 | |
| C'est nouveau ou un bug de la version actuelle alors car normalement les numeros d'objets sont indépendant des numéros de sprites ou d'objets 3D. | |
| | | Jean Claude
Nombre de messages : 5950 Age : 70 Localisation : 83 Var Date d'inscription : 07/05/2009
| Sujet: Re: Des procédures pour la 2D Dim 24 Mai 2015 - 16:48 | |
| Exact Jicehel, les numéros de SPRITE sont bien indépendants des autres objets. Je te remercie car j'étais dans l'erreur. A+
Dernière édition par Jean Claude le Dim 24 Mai 2015 - 17:00, édité 1 fois | |
| | | Contenu sponsorisé
| Sujet: Re: Des procédures pour la 2D | |
| |
| | | | Des procédures pour la 2D | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |