• Aucun résultat trouvé

IFT 1175 - TP2A L'exercice qui suit vise à vous familiariser avec deux notions en même temps : d'une part la

N/A
N/A
Protected

Academic year: 2022

Partager "IFT 1175 - TP2A L'exercice qui suit vise à vous familiariser avec deux notions en même temps : d'une part la"

Copied!
7
0
0

Texte intégral

(1)

IFT 1175 - TP2A

L'exercice qui suit vise à vous familiariser avec deux notions en même temps : d'une part la programmation objet qui permet de créer des classes d'objets et des objets à partir de celles- ci; d'autre part, la familiarisation avec l'environnement et la syntaxe de VB.Net. Tout en utilisant le dossier «TP2A» (le programme modèle lui-même) comme source d'information, vous créerez pas à pas l'application entière à partir de zéro. Il suffit d'utiliser le copier/coller des lignes de textes nécessaires qui se trouvent dans le fichier «TP2Atexte.doc».

Nous supposons ici que le travail se fait dans les salles de la DESI et donc avec les paramètres d'installation qui y sont définis.

Étape 1 : création d'une application «vide»

Lancez l'application «Visual Studio.Net» soit à partir de l'icône du bureau, soit à partir du menu «Démarrer/Tous les programmes» de Windows.

.

0 - Créez d'abord, dans votre dossier «ift1175» (disque R:) un dossier RemTP2 qui contiendra vos deux projets. Puis lancez VB.NET

1 - Cliquez sur le bouton [Nouveau projet]. VB affichera une boîte de dialogue vous permettant de nommer votre projet et de spécifier son emplacement.

2 - Dans la boîte de dialogue, donnez immédiatement un nom significatif à votre projet (exemple, «TP2PartieA») et parcourez vos disques pour le placer dans votre dossier

«ift1175\Remtp2» que vous avez créé sur votre disque «R:».

3 - Agrandissez votre feuille et modifiez sa propriété «Text» pour y placer le texte «Les balles qui tombent».

4 - Placez sur votre feuille deux étiquettes (Label) et un bouton de commande (Button) à partir de la section «Windows Forms» de la boîte à outils. Donnez-leur les noms «lblNbBalles»,

«lblNbChocs» et «btnQuitter» et définissez leur propriété «Text» à la valeur «Nombre de balles», «Nombre de chocs» et «Quitter». Leur taille et police importe peu pour cet exercice.

5 - Double-cliquez sur le bouton de commande, ce qui affichera dans la zone de travail la page de code de votre feuille et y ajoutera l'embryon de la procédure suivant :

Private Sub btnQuitter_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnQuitter.Click

End Sub

Notez au passage que le lien avec l'événement programmé se fait par la clause «Handles» et non plus (comme en VB6) avec le nom de la procédure, qui peut être changé à volonté.

6 - Placez l'énoncé «Me.Close()» dans le corps de cette procédure.

Votre projet peut maintenant être exécuté et le bouton «Quitter» y mettra fin.

(2)

Étape 2 : création d'une classe «simple»

7 - Dans le menu, faites «Projet / Ajouter une classe», donnez-lui le nom «clsPoint» et validez.

Le fichier «clsPoint.vb» sera créé et son contenu s'affichera dans une fenêtre «code» dont l'onglet s'ajoute à ceux déjà présents sur la fenêtre de travail.

8 - Vous pouvez changer le mot clé «Public» pour «Friend». Puis entrez les deux énoncés suivants dans le corps de la classe.

Public X As Short Public Y As Short

Observez le code correspondant de la classe équivalente dans le texte du fichier

«TP2Atexte.doc». Étant donné que ni l'entrée (écriture), ni la sortie (lecture) de ces deux propriétés n'est soumise à un quelconque contrôle, ces deux ensembles d'énoncés sont tout à fait identiques, acceptant l'une et l'autre toute valeur de type «Short» dans la propriété.

Étape 3 : création d'une classe «normale»

Nous allons créer une classe incluant des propriétés, des méthodes et des événements. Pour débuter, chaque cercle aura un «centre» de type «Point», un rayon de type «Short» dont la valeur sera limitée, et un numéro propre pour le distinguer des autres. On lui ajoutera ensuite une méthode «Dessiner» qui affichera le cercle sur la feuille à l'emplacement défini par son centre et son rayon.

9 - Comme précédemment, créez une classe Friend nommée «clsCercle».

10 - Définissez les variables cachées-privées qui contiendront les valeurs des propriétés

«NumCercle», «Centre» et «Rayon».

Private varNumCercle As Short Private varCentre As New clsPoint Private varRayon As Short

11 - Plus bas, définissez les accès aux propriétés «NumCercle» et «Centre» en lecture/écriture et

«Rayon» en écriture seule avec une contrainte sur la valeur minimum de celui-ci.

Public Property NumCercle() As Short Get

NumCercle = varNumCercle End Get

Set(ByVal Value As Short) varNumCercle = Value End Set

End Property

Public Property Centre() As clsPoint Set(ByVal Value As clsPoint) varCentre = Value

End Set Get

Centre = varCentre End Get

End Property

Public WriteOnly Property Rayon() As Short ' WriteOnly est optionnel Set(ByVal Value As Short)

If Value < 5 Then ' Minimum 5 pixels

(3)

Else

varRayon = Value End If

End Set

End Property

Pour l'instant, un cercle créé pourra posséder un numéro et des coordonnées. Si on veut le représenter sur la feuille, on peut lui donner une méthode «Afficher» qui utilisera les «objets graphiques» de VB.NET.

12 - Ajoutez le code de la procédure «Dessiner» ci-dessous qui reçoit en paramètre l'objet sur lequel elle doit inscrire le cercle et qui utilise un objet de type «Graphics» pour ce faire.

Public Sub Dessiner(ByVal MonObjet As Object) Dim g As Graphics

g = MonObjet.CreateGraphics ' On associe le graphique à la surface de la feuille g.DrawEllipse(Pens.Black, varCentre.X - varRayon, varCentre.Y - _

varRayon, 2 * varRayon, 2 * varRayon) g.Dispose()

End Sub

Une fois le graphique «associé» à l'objet, on active sa méthode DrawEllipse qui trace une ellipse incluse dans un rectangle. Ici, «Pens.Black» désigne la couleur «Noir» du trait. Les deux paramètres suivants représentent les coordonnées X,Y du coin gauche supérieur du rectangle, et les deux derniers indiquent la largeur et la hauteur du dit rectangle. Quand la largeur et la hauteur sont équivalentes, l'ellipse tracée est donc un cercle. Ici, si vous faites le calcul, le cercle résultant aura un rayon de «varRayon» et son centre sera placé sur l'objet «MonObjet» (c'est-à-dire la feuille) à un point déterminé par les valeurs des propriétés «X» et «Y» du centre du cercle. Bref, la méthode «Dessiner» du cercle lui commande de «se» tracer sur l'objet spécifié en paramètre à sa position (X,Y)..

Étape 4 : utilisation d'une classe «normale»

Pour illustrer la création d'un cercle et son affichage sur l'écran, nous allons utiliser le click de la souris sur la feuille. Quand l'utilisateur clique sur la feuille, il se produit 3 événements successifs : «MouseDown» qui indique qu'un bouton de la souris a été abaissé, «Click» qui suit immédiatement, et «MouseUp» qui indique que le bouton a été relâché. Les deux événements

«MouseDown» et «MouseUp» envoie comme paramètres (dans la variable objet «e») la position de la souris au moment de l'événement. Nous pouvons donc donner ces coordonnées à notre nouveau cercle.

13 - Revenez à la page de code de la feuille «Form1.vb» (utilisez l'onglet au haut de la fenêtre de travail). Dans la liste déroulante de gauche, sélectionnez l'objet «Form1 Events» pour obtenir à droite la liste des événements associés à la feuille. Dans cette liste, sélectionnez l'événement «MouseDown». L'entête de la procédure apparaît :

Private Sub Form_MouseDown(ByVal sender As Object, _

ByVal e As System.Windows.Forms.MouseEventArgs) _

Handles MyBase.MouseDown

End Sub

(4)

Ici, le premier paramètre, «sender», représente le contrôle qui a provoqué l'événement, donc le formulaire alors que le deuxième, «e», est un objet qui contient les informations complémen- taires sur l'événement, entre autres la position du pointeur de souris par rapport à la feuille et le bouton (gauche, centre ou droite) utilisé par l'utilisateur.

14 - Ajoutez à la procédure le code suivant qui crée un objet «point» et lui attribue les coordonnées du point de la fenêtre visé par la souris. Après quoi, elle crée un cercle ayant un rayon de 10 pixels centré sur cette coordonnée. Finalement elle appelle la méthode

«Dessiner» et lui fournit la feuille (Me) comme surface de traçage.

Dim UnPoint As clsPoint UnPoint = New clsPoint UnPoint.X = e.X

UnPoint.Y = e.Y

MonCercle = New clsCercle MonCercle.Centre = UnPoint MonCercle.Rayon = 10

MonCercle.Dessiner(Me)

15 - Exécutez le programme. Chaque fois que vous cliquerez sur la feuille, un cercle apparaîtra autour de ce point. ATTENTION : VB.NET ne permet pas, comme le faisait VB6, de corriger le programme en mode «pas à pas». Si une erreur survient, vous avez intérêt à stopper le programme et le corriger avant de l'exécuter de nouveau.

Étape 5 : animation d'une balle

On pourra animer une balle si, régulièrement, on la «déplace» de l'endroit où elle s'affiche vers un point adjacent de la feuille. Déplacer une balle, c'est donc 1) effacer la balle, calculer sa nouvelle position en modifiant sa coordonnée Y et 3) la dessiner au nouvel emplacement. On peut «effacer» la balle si on trace un cercle à l'endroit où elle se trouve en utilisant la même couleur que le fond de la surface, soit la couleur «BackColor» de la feuille. Comme ce

«mouvement» doit sembler continu, on doit le répéter graduellement.

Cependant, une simple boucle projetterait la balle à une vitesse trop rapide pour bien la percevoir. On peut par contre utiliser la minuterie qui permet de synchroniser les déplacements à une fréquence voulue de 1 ou de quelques millisecondes.

16 - Changez la propriété «BackColor» de la feuille pour la mettre en noir. Si vous exécutez de nouveau le projet, vous ne verrez plus les cercles «noir sur noir». Changer la propriété

«BackColor» des trois autres contrôles pour une couleur gris pâle pour qu'on puisse les voir.

17 - Ajoutez une minuterie (Timer) sur votre feuille. Elle sera placée dans une fenêtre «annexe».

18 - Définissez les propriétés du Timer à «Interval = 1» et «Enabled = False».

19 - Faite une copie de la procédure «Dessiner» de la classe «clsCercle». Renommez la nouvelle procédure «Effacer». Rendez les deux procédures «Private» plutôt que «Public». Elles ne seront donc plus visibles de l'extérieur. Puis remplacez la couleur «Pens.Black» par

«Pens.Yellow» dans la procédure «Dessiner». Ainsi, la procédure «Dessiner» trace le cercle en jaune, la procédure «Effacer» le trace en noir.

(5)

20 - Ajoutez la méthode «Déplacer» qui effacera le cercle, augmentera sa hauteur de 1 et le dessinera en jaune. Mais pour mettre fin au mouvement, on arrêtera son déplacement quand la balle atteindra la bordure inférieure de la feuille.

Public Sub Déplacer(ByRef MonObjet As Object) Call Effacer(MonObjet)

If varCentre.Y + varRayon < MonObjet.Size.Height - 35 Then varCentre.Y = varCentre.Y + 1

End If

Call Dessiner(MonObjet)

End Sub

L'ajustement «Height - 35» est nécessaire à cause de la présence de la barre de titre qui est incluse dans la hauteur totale de la feuille mais pas dans ses coordonnées verticales puisque «Y»

vaut zéro au dessous de cette barre. Sinon, la balle s'arrête trop bas.

21 - Revenez à la page code de votre feuille. Dans la procédure «MouseDown» , supprimez l'appel à la méthode «Dessiner» qui n'existe plus et activez la minuterie (Timer). Comme la variable objet «MonCercle» est déclarée localement, elle ne sera pas visible de la procédure événementielle du Timer. Définissez plutôt la variable «Private MonCercle As clsCercle»

dans la section générale de la feuille (devant la procédure «btnQuitter_Click»).

22 - Double-cliquez sur le contrôle «Timer1» pour programmer sa procédure «Tick» (nouveau nom de «Timer») et placez-y l'énoncé «MonCercle.Déplacer(Me)». Donc, à chaque milliseconde, la procédure sera exécutée et déplacera le cercle sur la feuille («Me»).

23 - Si vous exécutez votre projet, un click de souris placera la balle sur la feuille et celle-ci se déplacera vers le bas jusque sur la bordure inférieure de la feuille. Notez que si vous cliquez une deuxième fois, une nouvelle balle sera créée et la première sera «abandonnée», on verra pourquoi plus loin.

Étape 6 : animation d'une balle qui bondit

La balle actuelle se déplace d'un pixel à chaque millième de seconde et se déplace donc à une vitesse constante. Pour simuler une balle qui tombe, il suffit d'augmenter le déplacement de 1 pixel à chaque déplacement : 1 pixel, puis 2, puis 3 etc. On utilisera donc une variable «varDepl»

qui vaudra 0 au départ et qui augmentera de 1 à chaque déplacement.

Puis lorsque la balle touchera le bas de la feuille, elle devra «rebondir», c'est-à-dire que son mouvement sera inversé : elle montera au lieu de descendre donc sa valeur «Y» devra diminuer au lieu d'augmenter. De plus, pour éviter que le mouvement n'ait pas de fin, on supposera un amortissement de 1 pixel, donc si la balle se déplace de 8 pixels au moment du «choc», elle se déplacera vers le haut avec une vitesse de 7 pixels au cycle suivant. La variable booléenne

«varDirMonte» permet de savoir si le mouvement est vers le haut ou vers le bas.

Finalement, à mesure que la balle remonte, son déplacement «varDepl» diminue de 1 unité à la fois jusqu'à ce que le déplacement soit nul, auquel cas le mouvement reprend vers le bas.

24 - Ajoutez les deux variables «varDepl» et «VarDirMonte» dans la section générale de la classe «clsCercle».

25 - Remplacez les énoncés de la méthode «Déplacer» par ceux du modèle. Ajustez le point d'arrêt de la balle au sol si nécessaire (le «- 35»).

(6)

26 - Exécutez votre tâche et vous verrez que 1) votre balle rebondit jusqu'à ce qu'elle s'arrête au sol; 2) si vous cliquez une deuxième fois sur la feuille, la nouvelle balle se déplace mais la première «fige» sur place. Seul l'objet désigné par la variable «MonCercle» est touché par la procédure «Tick» du Timer.

Étape 7 : décompte des chocs de la balle

Chaque fois que la balle s'arrête au bas de la feuille et qu'elle change de direction, un choc se produit. Or le décompte des chocs se fait pour toutes les balles, et donc dans la feuille en affichant le nombre de chocs dans la zone d'étiquette. Ce que la balle ne peut pas faire elle- même. La balle peut cependant «prévenir» la feuille de cette situation en provoquant un événement que celle-ci pourra détecter.

27 - Placez au début de votre classe «clsCercle» l'énoncé «Public Event Choc()» et placez l'énoncé «RaiseEvent Choc()» dans la procédure «Déplacer», sous l'énoncé «varDirMonte = True», qui indique que la balle a atteint le sol. Chaque choc pourra ainsi être détecté par la feuille au moyen d'une procédure événementielle associée.

28 - Sur la page de code de la feuille, ajoutez le mot clé «WithEvents» à la déclaration de MonCercle : (Dim WithEvents MonCercle As clsCercle) qui précise alors que l'on désire programmer les événements de cet objet.

29 - Si vous observez la liste déroulante des objets de la feuille, vous verrez apparaître la variable objet «MonCercle». Sélectionnez son (seul) événement «Choc».

30 - Dans la procédure événementielle qui apparaît, insérez les énoncés suivants.

varNombreChocs = varNombreChocs + 1

lblNbChocs.Text = "Nombre de chocs : " & varNombreChocs

31 - Déclarez la variable «Dim varNombreChocs As Short » dans la zone générale de la feuille.

32 - Exécutez la tâche et vérifiez que le décompte des chocs se fait correctement. Mais le décompte se poursuit après l'arrêt de la balle.

33 - Dans la classe «clsCercle», définissez une propriété booléenne en lecture seule «Immobile»

stockée dans la variable «varImmobile». Cette propriété indiquera si la balle est immobilisée au bas de la feuille : sa vitesse (déplacement «varDepl») est nulle.

34 - Puis dans la procédure «Déplacer», juste après «choc» (raiseEvent), vérifiez si la vitesse est nulle et dans ce cas placez l'énoncé «varImmobile = True» pour indiquer que le mouvement s'est «éteint».

35 - Enfin, dans la procédure «Tick» de la minuterie, vérifiez, avant de «déplacer» la balle, que sa propriété «Immobile» soit «False».

Il ne reste plus qu'à modifier le projet pour gérer un groupe de balles.

(7)

Étape 8 : gestion d'un groupe de balle qui bondissent

Pour gérer plusieurs balles il faudra bien sûr utiliser plusieurs variables, c'est-à-dire un tableau ou une collection. Dans ce cas-ci, la collection est un meilleur choix.

36 - Ajoutez les déclarations suivantes à votre feuille qui vont déclarer des variables pour compter les cercles créés et accumuler les objets cercles créés.

Dim NbrCercles As Short = 0 Dim MaColl As New Collection

37 - Dans la procédure «MouseDown» de la feuille, juste devant l'activation de la minuterie, placez les énoncés suivants, dont un qui numérote le nouveau cercle et un autre qui l'ajoute à la collection en y plaçant l'index

NbrCercles = NbrCercles + 1 MonCercle.NumCercle = NbrCercles

MaColl.Add(MonCercle, "C" & NbrCercles)

lblNbBalles.Text = "Nombre de cercles : " & MaColl.Count() MonCercle = Nothing

Comme la collection contient tous les cercles créés, on peut libérer la variable «MonCercle»

après avoir affiché le nombre de balles dans la collection.

38 - La procédure «Timer_Tick» de la feuille déplace LA balle visée par MonCercle alors qu'il faut déplacer TOUTES les balles Remplacez l'énoncé de cette procédure par les énoncés suivants qui balaient toutes les balles de la collection et les déplacent à tour de rôle.

Dim Un_Cercle As clsCercle For Each Un_Cercle In MaColl MonCercle = Un_Cercle MonCercle.Déplacer(Me) Next ' Un_Cercle

Notez ici que pour détecter l'événement programmé «MonCercle_Choc()», il faut que l'appel à la méthode «Déplacer» se fasse sur cette variable «Mon_Cercle». Par ailleurs cette variable ne peut être utilisée comme variable de balayage de la boucle «For Each ...».

39 - Exécutez le projet : il reste un dernier ajustement : le compteur de balles tient compte des balles immobilisées.

Étape 9 et dernière : suppression des balle immobilisées.

40 - Finalement, il ne reste qu'à supprimer de la collection les balles qui, après leur déplacement (procédure «Timer_Tick») se retrouvent immobiles. On ajuste alors l'affichage du nombre de balles obtenu par la propriété «Count» de la collection. Ajoutez donc ces énoncés à la suite du déplacement de chaque balle, dans la boucle de la procédure.

If MonCercle.Immobile Then

MaColl.Remove("C" & MonCercle.NumCercle)

lblNbBalles.Text = "Nombre de cercles : " & MaColl.Count End If

Fin de l'exercice.

Références

Documents relatifs

Godelier ne semble pas suffire à lever la difficulté, bien qu’il s’efforce d’en repousser les inconvénients en soulignant que la dualité infrastructure/superstructure

[r]

Représenter qualitativement (sans échelle) sur l’enregistrement, les vecteurs vitesse et accélération au point M 3 , justifier succinctement.. Définir une base dans la définition

Familiarisation avec l'environnement de travail. Exercices dirigés et réalisation du travail pratique no 1. ▫ Gestions d’erreurs et débogage. ▫ Programmation

Certains membres (propriétés, méthodes. événements) communs à plusieurs contrôles ont été modifiés, soit dans leur nom, soit dans leur fonctionnement.. • L'événement

Cocher oui, cocher non (CheckBox nommé chkCoche) : la case à cocher manque ici complètement de réaction car elle n’a pas été programmée… Il en va de même pour la bulle

L’idée est que par la propriété de Markov (forte) et par symmétrie, le deuxième processus est aussi un mouvement Brownien.. Justifier que X est un

Si plusieurs sens sont possibles, choisissez votre favori, selon le contexte.. La réaction de la collègue a