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 |
|
|
| Deux boucles imbriquées qui ne fonctionnent pas correctement | |
| | Auteur | Message |
---|
dragonno
Nombre de messages : 341 Localisation : Près de Toulouse Date d'inscription : 22/01/2009
| Sujet: Deux boucles imbriquées qui ne fonctionnent pas correctement Ven 10 Déc 2010 - 22:51 | |
| J'ai l'impression qu'on ne peut pas faire deux boucles imbriquées ? j'essai d'afficher 5 fois 5 sprites (25 donc^^) 5 x 4 ou 5x5 c'est pas grave, le principal est d'afficher une série de lignes et colonnes de sprites. - Code:
-
dim i,x,y,taille,col,lig
scene2d 1 taille=5 i=1 lig=0
while lig<taille-1 for col=0 to taille-1 sprite i sprite_file_load i,"submarine.bmp" y=32+(32*lig) x=32+(32*col) sprite_position i,y,x print "position tableau : "+str$(lig)+" "+str$(col) print i=i+1 next col lig=lig+1 end_while
EFFET : ça affiche entre 1 et 3 sprites c'est tout et c'est donc peu et aléatoire. EDIT : non c'est bon ça fonctionne bien : - Code:
-
dim i,x,y,taille,col,lig
scene2d 1 taille=5 i=1 lig=0
while lig<taille-1 for col=0 to taille sprite i sprite_file_load i,"submarine.bmp" y=32+(32*lig) x=32+(32*col) sprite_position i,y,x print "position tableau : "+str$(lig)+" "+str$(col) print i=i+1 next col lig=lig+1 end_while
Le probleme c'est que dans mon programme ça fait l'effet que j'ai indiqué, bizarre. | |
| | | dragonno
Nombre de messages : 341 Localisation : Près de Toulouse Date d'inscription : 22/01/2009
| Sujet: Re: Deux boucles imbriquées qui ne fonctionnent pas correctement Ven 10 Déc 2010 - 23:17 | |
| Bizarre quand même, ce code là fonctionne impeccable : - Code:
-
dim i,x,y,taille,col,lig
scene2d 1 taille=5 i=1 lig=0
for lig=0 to taille-1 for col=0 to taille-1 sprite i sprite_file_load i,"submarine.bmp" y=32+(32*lig) x=32+(32*col) sprite_position i,y,x print "position tableau : "+str$(lig)+" "+str$(col) print i=i+1 next col next lig
Mais mis dans mon programme il ne fonctionne plus pareil, il affiche pas les 5x5 fois sprites. - Code:
-
label attaque label repos label bonus label petit label moyen label grand label tests label hasard
dim energie,tours dim sonar,canon,mouvement dim nombre,i,y,x,map dim caseY,caseX,lig,col dim taille
scene2d 1
' Pour tester les touches clavier timer 2 timer_interval 2,1 on_timer 2, tests
' pour définir la dimension de la map ' gosub petit
' place 1 aléatoirement (trois fois) dans le tableau virtuel de 5x5 cases ' nombre=3 donc : trois fois. i=0 ' while i<nombre ' gosub hasard ' if (tableau(caseY,caseX)=1) ' gosub hasard ' else ' tableau(caseY,caseX)=1 ' i=i+1 ' end_if ' end_while
' lit le tableau pour afficher sur la map un sprite à la place de 1 lu dans le tableau. i=1 lig=0 taille=5 for lig=0 to taille-1 for col=0 to taille-1 sprite i sprite_file_load i,"submarine.bmp" y=32+(32*lig) x=32+(32*col) sprite_position i,y,x print "position tableau : "+str$(lig)+" "+str$(col) print i=i+1 next col next lig
end
attaque: return
repos: return
bonus: return
' fixe la taille de la map à 5x5 petit: taille=5 dim tableau(5,5) map=192 left 1,200 top 1,200 width 1,map height 1,map file_load 1,"grille05.bmp" nombre=3 return
moyen: taille=10 dim tableau(10,10) map=352 left 1,100 top 1,100 width 1,map height 1,map file_load 1,"grille10.bmp" nombre=5 return
grand: taille=20 dim tableau(20,20) map=672 left 1,0 top 1,0 width 1,map height 1,map file_load 1,"grille20.bmp" nombre=8 return
tests: if scancode=27 then terminate return
' détermine la position aléatoire dans le tableau virtuel. hasard: caseY=int(rnd(taille-1)) caseX=int(rnd(taille-1)) return
Remarque encore bizarre, dans la routine "petit" si je met en REM la ligne nombre=3 le programme affiche 3 sprites consécutifs dans la même colonne : 0,0 premier sprite 0,1 deuxieme sprite 0,2 troisieme sprite Alors que nombre n'est même pas utilisé dans le programme car j'ai mis en REM le code du while qui est censé l'utiliser. Essayez le code qui marche et le programme complet vous verrez la différence, moi je ne vois pas ce qui cloche :/ J'ai mis en REM tous les codes qu'il faut afin de ne voir que le fonctionnement des boucles "for" car seules elles fonctionnent mais pas dans le programme. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Deux boucles imbriquées qui ne fonctionnent pas correctement Sam 11 Déc 2010 - 0:05 | |
| Ton problème, c'est le on_timer à la ligne 21. Si tu le mets en commentaire, tout fonctionne bien.
Tu retombes dans le vieux piège de l'écriture de programmes à la mode ancienne. Tu places tout ton code avant la commande END, tu es donc en mode linéaire, et les évènements timer perturbent joyeusement toute ta gestion.
Solution: place un END juste après on_timer. Insère un label (genre debut:) juste après le END. En début de programme, crée un bouton "Démarrer" avec on_click <numéro_du_bouton>,debut.
Et tout marchera. Il faut absolument passer en mode évènementiel avec Panoramic si l'on veut que toute la gestion fonctionne. | |
| | | dragonno
Nombre de messages : 341 Localisation : Près de Toulouse Date d'inscription : 22/01/2009
| Sujet: Re: Deux boucles imbriquées qui ne fonctionnent pas correctement Sam 11 Déc 2010 - 0:17 | |
| Donc finalement un programme panoramic ce n'est qu'un bloc de définitions suivi par un ensemble de routines "persos" (gosub). Je vais tester ce que tu me conseille là. EDIT : J'ai fait ça : - Code:
-
label attaque label repos label bonus label petit label moyen label grand label tests label hasard label debut
dim energie,tours dim sonar,canon,mouvement dim nombre,i,y,x,map dim caseY,caseX,lig,col dim taille
scene2d 1
' Pour tester les touches clavier timer 2 timer_interval 2,1 on_timer 2, tests goto debut
end
debut: ' pour définir la dimension de la map gosub petit
' place 1 aléatoirement (trois fois) dans le tableau virtuel de 5x5 cases ' nombre=3 donc : trois fois. i=0 ' while i<nombre ' gosub hasard ' if (tableau(caseY,caseX)=1) ' gosub hasard ' else ' tableau(caseY,caseX)=1 ' i=i+1 ' end_if ' end_while
' lit le tableau pour afficher sur la map un sprite à la place de 1 lu dans le tableau. i=1 for lig=0 to taille-1 for col=0 to taille-1 sprite i sprite_file_load i,"submarine.bmp" y=32+(32*lig) x=32+(32*col) sprite_position i,y,x print "position tableau : "+str$(lig)+" "+str$(col) print i=i+1 next col next lig
return
attaque: return
repos: return
bonus: return
' fixe la taille de la map à 5x5 petit: taille=5 dim tableau(5,5) map=192 left 1,200 top 1,200 width 1,map height 1,map file_load 1,"grille05.bmp" nombre=3 return
moyen: taille=10 dim tableau(10,10) map=352 left 1,100 top 1,100 width 1,map height 1,map file_load 1,"grille10.bmp" nombre=5 return
grand: taille=20 dim tableau(20,20) map=672 left 1,0 top 1,0 width 1,map height 1,map file_load 1,"grille20.bmp" nombre=8 return
tests: if scancode=27 then terminate return
' détermine la position aléatoire dans le tableau virtuel. hasard: caseY=int(rnd(taille-1)) caseX=int(rnd(taille-1)) return
C'est sensé m'afficher une map de 5x5 sprites mais ça n'affiche qu'une colonne de sprites. Et en plus seulement 3 sprites. Tu peux l'essayer tel quel, juste besoin d'une petite image de 32x32 pour le sprite. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Deux boucles imbriquées qui ne fonctionnent pas correctement Sam 11 Déc 2010 - 0:30 | |
| Tu n'as pas compris. Ta commande END n'est jamais exécutée ! Il ne suffit pas qu'elle soit placée dans le code: il faut qu'elle soit réellement exécutée par Panoramic afin de basculer en mode évènementiel ! Sinon, tu es toujours dans le conflit indiqué précédemment. Enlève le goto end, place un bouton, et fais on_click <bouton>,debut. Ca ira mieux comme ça.
EDIT
D'ailleurs, regarde dans l'Aide, la rubrique Conseils, point 1.1 structure d'un programme.
| |
| | | dragonno
Nombre de messages : 341 Localisation : Près de Toulouse Date d'inscription : 22/01/2009
| Sujet: Re: Deux boucles imbriquées qui ne fonctionnent pas correctement Sam 11 Déc 2010 - 0:39 | |
| Bon, meaculpa je vais tenter ce que tu dis Effectivement ça fonctionne super, merci klaus, mais c'est dommage que la partie principale du programme soit dans une routine, et que le corps du programme ne soit fait que de définitions (partie avant le end). | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: Deux boucles imbriquées qui ne fonctionnent pas correctement Sam 11 Déc 2010 - 1:16 | |
| Oui, mais c'est comme ça. Depuis que je suis inscrit sur ce forum, j'essaie de promouvoir la façon évènementielle de programmer. Panoramic ressemble à un Basic, et C'EST un Basic, mais sous Windows et plus sous DOS ou tout autre système ancien (Amiga, ...). Et cette façon de faire dépend en fait de Windows, et Pänoramic ne fait que rendre accessible au niveau du programmeur cette fonctionnalité Windows.
Il faut bien comprendre que Windows est un système géré entièrement par des "messages" qui sont envoyés entre les programmes et entre les programmes et le noyau du système. Tous ces messages génèrent des "évènements" qui sont comparables à des interruptions générées par un périphérique, par exemple. Tout le système Windows est composé pour l'essentiel de routines qui réagissent à un évènement particulier, ou à une classe d'évènements qu'elles sont censées dispatcher. Et chaque fois, quelque chose qui ressemble à un RETURN rend la main au noyau du système qui essentiellement "attend" l'évèmenent", le message suivant.
Les messages arrivants sont placés dans une file d'attente et traités séquentiellement (on va laisser de côté la gestion des priorités). Ceci veut dire qu'un message n'est pas forcément traité directement quand il arrive. Et c'est la différence essentielle entre un système de ce genre et un vrai système temps-réel, tel qu'on l'utilise dans le contrôle de processus - Unix est beaucoup mieux adapté à cela.
Lorsque ne noyau de windows traite les messages de la file d'attente, il les dispatche essentiellement vers des "handlers" de messages déclarés pour tel ou tel type d'évènement, créant ainsi de nouvelles files d'attente. ET chaque handler de messages agit de la même manière, jusqu'au récepteur final qui est constitué d'une routine qui effectue le travail réel. Des messages de confirmation sont ensuite envoyés de retour, et ainsi de suite.
Tout programme application (et l'interpréteur Panoramic n'est rien d'autre) se trouve un des récepteurs de messages pour des actions qu'il a initialisées lui-même ou issus de périphériques gérés par lui. Ainsi, si un programme source déclare un timer à l'interpréteur Panoramic, celui-ci à son tour déclare un timer au système. A partir de ce moment, les messages d'interruption de ce timer, reçus d'abord par le noyau de windows, sont dispatchés vers l'interprèteur Panoramic qui à son tour, va appeler la routine déclarée par on_timer. Mais pendant que cette routine se déroule, on est en mode "interruption" et tous les autres évènements sont mis en file d'attente. Et c'est là que le bât blesse: cette gestion ne marche bien que si Panoramic lui-même est en mode évènementiel ! Et ce n'est que l'exécution de la commande END qui réalise cela.
Pourquoi ? parce que Panoramic a un héritage: c'est tout le vécu de BASIC que Panoramic veut pouvoir restituer. Il y a donc, au départ et par défaut, le mode "ancien", le mode linéaire comme je préfère l'appeler. Il permet, comme par le passé, d'écrire des programmes utilisant print, input, scan_code etc - comme un Basic sous DOS. Mais on ne peut pas réellement utiliser les objets VISUELS Panoramic, car ces objets sont en réalité des objets Windows fontionnant directement en mode évènementiel ! Il faut donc impérativement se mettre dans ce mode pour les utiliser.
D'où le conseil de Jack, et accessoirement ce que j'ai déjà expliqué dans de multiples posts: au début: mode linéaire: ici, on fait les déclarations (commandes label, dim et data), puis les initialisations de variables. on fait isi ensuite la CONSTRUCTION du GUI (Graphical User Interface, donc son dessin d'écran) puis, on lance le ou les timers puis, IMPERATIVEMENT, la commande END. Tout le reste du programme est constitué uniquement de sous-programmes appelés par des évèmenents - c'est à cela que servent les commandes ON_xxx, que ce soit on_timer, on_change, on_close, on_click etc. Tout cela, ce sont des messages qui déclenchent des évènements dans le langage Basic, et pour que cela fonctionne, eh bien, il faut que Panoramic soit dans le bon mode, sinon, bonjour le cafouillage ! | |
| | | dragonno
Nombre de messages : 341 Localisation : Près de Toulouse Date d'inscription : 22/01/2009
| Sujet: Re: Deux boucles imbriquées qui ne fonctionnent pas correctement Sam 11 Déc 2010 - 1:28 | |
| ouais, je connais le mode evenementiel mais comme tu le vois je croyais que panoramic pouvait permettre d'écrire son code avant le end, code qui se servirait des routines placées après le end. En fait il se trouve que j'ai eu tord, panoramic fonctionne comme tu le précise très bien dans plusieurs posts et surtout ici, en mode évennementiel, en plaçant son code après le end, comme une routine, en ne laissant avant le end que la partie déclaration des label, dim, timers, pré-affichages (zcene2D, pictures, objets). Ce qui m'a induit en erreur c'est le fait que j'ai (je crois) déjà utilisé un programme "vaisseaux" qui avait l'air de fonctionner et sans m'être occupé de penser s'il était en mode evennementiel ou pas. Je viens de vérifier et en fait effectivement il était en mode evennementiel mais je l'avais fait sans y penser en fait, n'ayant pas ce mode de fonctionnement comme programmation par défaut dans ma tête | |
| | | Contenu sponsorisé
| Sujet: Re: Deux boucles imbriquées qui ne fonctionnent pas correctement | |
| |
| | | | Deux boucles imbriquées qui ne fonctionnent pas correctement | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |