QBasic – Les types personalisés
- QBasic – Introduction au QBasic
- QBasic – Ecrire sur l’écran
- QBasic – Mathématiques élémentaires
- QBasic – La ponctuation (syntaxe)
- QBasic – Les variables
- QBasic – Les commentaires
- QBasic – Les constantes
- QBasic – Entrée de données
- QBasic – Les boucles inconditionnelles
- QBasic – Les boucles conditionnelles
- QBasic – Structure conditionnelle
- QBasic – Les cas
- QBasic – Maths, logique et divers
- QBasic – Le texte
- QBasic – Le son
- QBasic – Dessiner
- QBasic – Sous-programmes, fonctions et procedures
- QBasic – Les types de variables
- QBasic – Les tableaux
- QBasic – Les types personalisés
- QBasic – L’organisation des données
- QBasic – QBasic et le système d’exploitation
- QBasic – L’accès aux fichiers
- QBasic – Le traitement des erreurs
- QBasic – La manette de jeu
- QBasic – Encore plus loin dans le graphisme
- QBasic – La mémoire
- QBasic – Le langage machine et la souris
- QBasic – L’heure, la date, le temps
- QBasic – Le clavier
- Introduction sommaire à l’animation
- Définition du type
- Les types et les tableaux
- Types dans types
- Note sur les nombres aléatoires
QBasic est loin d’être un langage de programation orienté objet. Cependant, il permet quand
même à l’utilisateur de définir ses propres types de variable.
Créer un type peut être très utile dans des cas de programme très complexes (jeux ou autres)
et permet de n’avoir que quelques variables dans son code.
Pour expliquer ce qu’est un type, nous allons détailler un exemple de programme en utilisant.
But : faire rebondir une balle (ou plutôt un cercle) sur les 4 cotès de votre écran.
Introduction sommaire à l’animation
Avant d’attaquer les types, vous devez savoir que pour animer un objet (ici, ce sera notre
balle), il faut :
- Effacer cet objet, c’est à dire le dessiner aux même coordonnées, mais avec la couleur
d’arrière plan. - Le redessiner à ces autres coordonnées.
Dans notre exemple, l’objet se limitant à un cercle, nous utiliserons cette technique. Mais
nous verrons plus tard une autre technique pour animer des dessins plus complexes.
Définition du type
Tout d’abord, nous devons définir les propriétés de notre balle :
- Rayon : vu que l’instruction
CIRCLErequiet un rayon et non un diamêtre, cette
propriété le définira. - X : les coordonnées X du centre du cercle sur l’écran.
- Y : les coordonnées Y du centre du cercle sur l’écran.
- CX : pour déplacer la balle, nous allons ajouter aux coordonnées X, ce
coefficient. - CY : de même, nous allons ajouter ce coefficient au coordonnées Y pour déplacer
le cercle.
Comme pour les boucles, on peut comparer un type à un Big-Mac : deux tranches de pain et le
reste au milieu. Le reste, ce sera nos propriétés que nous avons défini ci dessus :
TYPE TBalle ‘ Le nom de notre type est TBalle
Rayon AS INTEGER ‘ Propriété Rayon, du type INTEGER
X AS SINGLE ‘ Propriété X, du type SINGLE
Y AS SINGLE ‘ Propriété Y, du type SINGLE
CX AS SINGLE ‘ Propriété CX, du type SINGLE
CY AS SINGLE ‘ Propriété CY, du type SINGLE
END TYPE ‘ Fin du type
Pareil que pour les boucles, il est conseillé d’observer un retrait.
Cette fois notre type est créé. Il est désormais utilisable comme n’importe quel autre type
(
INTEGER, SINGLE, LONG, DOUBLE, STRING).Nous allons donc déclarer une variable ‘
Balle‘ du type ‘TBalle‘ :
TYPE TBalle ‘ Le nom de notre type est TBalle
Rayon AS INTEGER ‘ Propriété Rayon, du type INTEGER
X AS SINGLE ‘ Propriété X, du type SINGLE
Y AS SINGLE ‘ Propriété Y, du type SINGLE
CX AS SINGLE ‘ Propriété CX, du type SINGLE
CY AS SINGLE ‘ Propriété CY, du type SINGLE
END TYPE ‘ Fin du typeDIM Balle AS TBalle ‘ Déclaration de la variable Balle du type TBalle
Puis, nous allons initaliser d’une part l’écran :
TYPE TBalle ‘ Le nom de notre type est TBalle
Rayon AS INTEGER ‘ Propriété Rayon, du type INTEGER
X AS SINGLE ‘ Propriété X, du type SINGLE
Y AS SINGLE ‘ Propriété Y, du type SINGLE
CX AS SINGLE ‘ Propriété CX, du type SINGLE
CY AS SINGLE ‘ Propriété CY, du type SINGLE
END TYPE ‘ Fin du typeDIM Balle AS TBalle ‘ Déclaration de la variable Balle du type TBalle
SCREEN 12 ‘ Mode d’écran 12
CLS
Et d’autre part, les propriétés de ‘
Balle‘. Pour accéder à ces propriétés, il suffit d’écrirele nom de la variable, un point (.) et le nom de la propriété :
TYPE TBalle ‘ Le nom de notre type est TBalle
Rayon AS INTEGER ‘ Propriété Rayon, du type INTEGER
X AS SINGLE ‘ Propriété X, du type SINGLE
Y AS SINGLE ‘ Propriété Y, du type SINGLE
CX AS SINGLE ‘ Propriété CX, du type SINGLE
CY AS SINGLE ‘ Propriété CY, du type SINGLE
END TYPE ‘ Fin du typeDIM Balle AS TBalle ‘ Déclaration de la variable Balle du type TBalle
SCREEN 12 ‘ Mode d’écran 12
CLSBalle.Rayon = 10 ‘ Rayon de 10 pixels
Balle.X = 320 ‘ Au centre de l’écran
Balle.Y = 240 ‘ Au centre de l’écran
Balle.CX = .05 ‘ Coefficient de départ
Balle.CY = .05 ‘ Coefficient de départ
Il ne nous reste maintenant plus qu’à l’animer. Pour cela, nous allons utiliser la technique
énoncée plus haut et une boucle :
TYPE TBalle ‘ Le nom de notre type est TBalle
Rayon AS INTEGER ‘ Propriété Rayon, du type INTEGER
X AS SINGLE ‘ Propriété X, du type SINGLE
Y AS SINGLE ‘ Propriété Y, du type SINGLE
CX AS SINGLE ‘ Propriété CX, du type SINGLE
CY AS SINGLE ‘ Propriété CY, du type SINGLE
END TYPE ‘ Fin du typeDIM Balle AS TBalle ‘ Déclaration de la variable Balle du type TBalle
SCREEN 12 ‘ Mode d’écran 12
CLSBalle.Rayon = 10 ‘ Rayon de 10 pixels
Balle.X = 320 ‘ Au centre de l’écran
Balle.Y = 240 ‘ Au centre de l’écran
Balle.CX = .05 ‘ Coefficient de départ
Balle.CY = .05 ‘ Coefficient de départDO
CIRCLE(Balle.X, Balle.Y), Balle.Rayon, 0 ‘ On efface la balle
Balle.X = Balle.X + Balle.CX ‘ Calcul de la nouvelle coordonnée X
Balle.Y = Balle.Y + Balle.CY ‘ Calcul de la nouvelle coordonnée Y
CIRCLE(Balle.X, Balle.Y), Balle.Rayon, 14 ‘ On dessine la balle
LOOP
Maintenant, pour la faire rebondir, on va utiliser deux conditions. Pour les bords horizontaux,
on va inverser le coefficient CY dès que le cercle va rencontrer un des deux. Pareil pour les
bords verticaux, mais avec CX :
TYPE TBalle ‘ Le nom de notre type est TBalle
Rayon AS INTEGER ‘ Propriété Rayon, du type INTEGER
X AS SINGLE ‘ Propriété X, du type SINGLE
Y AS SINGLE ‘ Propriété Y, du type SINGLE
CX AS SINGLE ‘ Propriété CX, du type SINGLE
CY AS SINGLE ‘ Propriété CY, du type SINGLE
END TYPE ‘ Fin du typeDIM Balle AS TBalle ‘ Déclaration de la variable Balle du type TBalle
SCREEN 12 ‘ Mode d’écran 12
CLSBalle.Rayon = 10 ‘ Rayon de 10 pixels
Balle.X = 320 ‘ Au centre de l’écran
Balle.Y = 240 ‘ Au centre de l’écran
Balle.CX = .05 ‘ Coefficient de départ
Balle.CY = .05 ‘ Coefficient de départDO
CIRCLE(Balle.X, Balle.Y), Balle.Rayon, 0 ‘ On efface la balle
Balle.X = Balle.X + Balle.CX ‘ Calcul de la nouvelle coordonnée X
Balle.Y = Balle.Y + Balle.CY ‘ Calcul de la nouvelle coordonnée Y
IF Balle.X – Balle.Rayon < 0 OR Balle.X + Balle.Rayon > 640 THEN
‘ Gestion du rebond horizontal
Balle.CX = -Balle.CX
END IF
IF Balle.Y – Balle.Rayon < 0 OR Balle.Y + Balle.Rayon > 480 THEN
‘ Gestion du rebond vertical
Balle.CY = -Balle.CY
END IF
CIRCLE(Balle.X, Balle.Y), Balle.Rayon, 14 ‘ On dessine la balle
LOOP
Vous remarquer que l’on a pris en compte le rayon de la balle dans les conditons de rebond. En
effet, sans cette précaution, la balle aurait rebondit sur son centre et nom sur ces bords.
Les types et les tableaux
Il est tout à fait possible de définir un tableau d’un type personalisé. Ainsi on aurait pu
avoir plusieurs balles sur l’écran, sans pour autant compliquer le programme. On utilise
simplement des boucles
FOR…NEXT :
TYPE TBalle
Rayon AS INTEGER
X AS SINGLE
Y AS SINGLE
CX AS SINGLE
CY AS SINGLE
END TYPEDIM Balle(10) AS TBalle ‘ Un tableau de balles
SCREEN 12
CLSFOR i = LBOUND(Balle) TO UBOUND(Balle) ‘ Remarquer l’utilisation de LBOUND et UBOUND
Balle(i).Rayon = 10
Balle(i).X = 320
Balle(i).Y = 240
Balle(i).CX = .05
Balle(i).CY = .05
NEXT iDO
FOR i = LBOUND(Balle) TO UBOUND(Balle)
CIRCLE(Balle(i).X, Balle(i).Y), Balle(i).Rayon, 0
Balle(i).X = Balle(i).X + Balle(i).CX
Balle(i).Y = Balle(i).Y + Balle(i).CY
IF Balle(i).X – Balle(i).Rayon < 0 OR Balle(i).X + Balle(i).Rayon > 640 THEN
Balle(i).CX = -Balle(i).CX
ENDIF
IF Balle(i).Y – Balle(i).Rayon < 0 OR Balle(i).Y + Balle(i).Rayon > 480 THEN
Balle(i).CY = -Balle(i).CY
END IF
CIRCLE(Balle(i).X, Balle(i).Y), Balle(i).Rayon, 14
NEXT i
LOOP
Que remarquez-vous ? Rien a changé, si ce n’est la vistesse d’execution. C’est parcequ’on à
définit des coordonnées communes à toutes les balles. Elles sont donc confondues et leurs
déplacements passent inaperçus.
Pour remédier à ce problème, nous allons faire intervenir l’aléatoire avec RND.
Souvenez-vous, c’est cette instruction qui permet d’obtenir un nombre alétoire entre 0 et 1.
Donc, pour avoir un nombre entre 0 et 10, on le multipliera par 10, pour en avoir un entre 0
et 421, on le multipliera par 421 :
TYPE TBalle
Rayon AS INTEGER
X AS SINGLE
Y AS SINGLE
CX AS SINGLE
CY AS SINGLE
END TYPEDIM Balle(10) AS TBalle ‘ Un tableau de balles
SCREEN 12
CLSFOR i = LBOUND(Balle) TO UBOUND(Balle) ‘ Remarquer l’utilisation de LBOUND et UBOUND
Balle(i).Rayon = RND * 10
Balle(i).X = RND * 640
Balle(i).Y = RND * 320
Balle(i).CX = RND
Balle(i).CY = RND
NEXT iDO
FOR i = LBOUND(Balle) TO UBOUND(Balle)
CIRCLE(Balle(i).X, Balle(i).Y), Balle(i).Rayon, 0
Balle(i).X = Balle(i).X + Balle(i).CX
Balle(i).Y = Balle(i).Y + Balle(i).CY
IF Balle(i).X – Balle(i).Rayon < 0 OR Balle(i).X + Balle(i).Rayon > 640 THEN
Balle(i).CX = -Balle(i).CX
END IF
IF Balle(i).Y – Balle(i).Rayon < 0 OR Balle(i).Y + Balle(i).Rayon > 480 THEN
Balle(i).CY = -Balle(i).CY
END IF
CIRCLE(Balle(i).X, Balle(i).Y), Balle(i).Rayon, 14
NEXT i
LOOP
Cette fois, ça marche. On aurrait put les faire s’entrechoquer, mais ce n’est plus le sujet
de cette démonstration sur les types.
Types dans types
On peut tout à fait inclure des types personalisés dans d’autres types personalisés et ainsi
de suite. Il suffit de pouvoir s’y retrouver.
Par contre, en QBasic, on ne peut pas définir un tableau dans un type.
Note sur les nombres aléatoires
Comme certains le soutiennent (et j’en fais parti), le hasard n’existe pas. L’informatique (
et donc QBasic) n’echappe pas à cette rêgle. Ainsi, pour simuler le hasard, l’ordinateur
utilise une liste de nombres classés selon un ordre bien prècis.
Or, à chaque fois que vous lancez le programme, cette liste est remise à son point de départ
(pour simplifier).
Conséquence : si on ne fais rien contre, la chance ne va jamais tourné, puisque ce sera
constament les mêmes nombres qui seront « tirés ».
Pour remédier à ce problème crucial, il existe une instrution magique : l’instruction
RANDOMIZE.
RANDOMIZE va initialisé le générateur de nombres aléatoires à la position spécifiée. Exemple :
RANDOMIZE 5′ Initialisation à 5
PRINT RND
Seulement, voilà : dans cette exemple, le nombre tiré sera toujours le même puisqu’on à
initialisé la liste avec une constante (5), qui justement, ne varie pas.
Là aussi, pour remédier à ce problème, il existe deux solutions :
- Laisser le choix du nombre de départ à l’utilisateur. Pour cela, il suffit de ne pas
spécifier de chiffre de départ et il sera automatiquement demandé :
RANDOMIZE ‘ On laisse le choix à l’utilisateur
PRINT RND
- On utilise l’horloge du PC pour calibrer la liste, grâce à la fonction TIMER.
TIMERrenvoie le nombre de secondes écoulées depuis minuit. Le chiffre change donc toutes
les secondes. Il faudrait une remarquable coïncidence pour que l’on retombe plusieurs
fois sur la même liste :
RANDOMIZE TIMER ‘ Le PC décide pour nous
PRINT RND
Le type de leçon pédagogique: on commence très simple et on complique peu à peu avec des commentaires.