Ver Mensaje Individual
  #23 (permalink)  
Antiguo 06/05/2005, 18:41
Avatar de Boxmaster
Boxmaster
 
Fecha de Ingreso: agosto-2004
Ubicación: Ahorita... frente a mi PC
Mensajes: 74
Antigüedad: 19 años, 9 meses
Puntos: 0
Exclamación Tutorial del PACMAN en VB.NET (1a Parte)

Un PacMan avec VB.NET. Tutoriel POO

Ce jeu de PacMan n'est absolument pas optimisé. Mais son but est de vous montrer les nouveautés de la programmation orientée objet de VB.net
(vu 6829)



PacMan is back


Bon, autant vous prévenir tout de suite, le code qui vous est présenté ce mois-ci n’est absolument pas optimisé et défit même par moment les règles élémentaires de programmation (et en plus, le jeu n’est pas terrible alors…). Mais il a l’avantage de vous présenter plusieurs Namespaces et certaines nouvelles fonctionnalités de VB.NET, bref il n’est présent que dans un but pédagogique.

Vous allez donc créer, grâce à VB.NET, une énième version du PacMan
(comme dirait Droopy, « I’m happy »).

Toutes les classes que vous pouvez manipuler avec VB.NET sont sagement rangées dans des Namespaces ou espaces de nom (dans un même Namespace, deux classes du même nom ne peuvent cohabiter).

La plate-forme Microsoft.NET nous livre nombre de Namespaces qui contiennent eux-même, nombre de classes. Une bonne partie de la maîtrise de VB.NET va donc consister à bien connaître ces Namespaces et savoir utiliser les bonnes classes au bon endroit.

La structure de l’application
Regardons maintenant comment vous allez organiser votre application. Vous avez à dessiner la carte, le PacMan, les fantômes et à animer le tout. Vous allez créer les classes suivantes :

cSprite, une classe qui dessine un élément mouvant,
cPacMan pour le PacMan, qui hérite de cSprite,
cFantome pour un fantôme, qui hérite de cSprite,
cFantomes, une classe collection qui contient l’ensemble des fantômes,
cSquare pour un élément du décor,
cSquares, une classe collection qui contient l’ensemble des éléments de décors,
cAppli, la classe à la tête de votre hiérarchie.
Au début de votre application, vous allez créer une instance de votre classe cAppli. Dans son constructeur, vous passez en paramètres la Form ou vous affichez votre jeu ainsi que le nom du fichier où se trouve la carte :

Public Sub New(ByVal FormA As Form1, ByVal sMapFile As String)

Dans le constructeur, vous allez lire le fichier contenant la carte et créer les instances de tous les objets dont vous avez besoin

Commençons tout de suite l’exploration très fort avec le NameSpace System.IO pour la lecture de la carte.

Lecture de la carte
Chaque niveau de votre jeu va être stocké dans un fichier texte. Pour concevoir un niveau, utilisez simplement Excel en créant un tableau de 19 lignes par 19 colonnes. Dans chaque cellule, placez des 1 pour les murs, 0 pour du vide, 5 pour l’emplacement de départ du PacMan, 4 pour les fantômes (les méchants), etc. Puis, sauvegardez le tout dans un fichier au format cvs (on dirait une recette de cuisine ! ). Ce qui vous donne un fichier du genre :

1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1
1;5;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;1
1;0;1;1;1;0;1;0;1;0;1;0;1;0;1;1;1;0;1


1;6;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;1
1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1

La lecture de ce fichier va vous permettre de remplir votre collection cSquares d’objets cSquare.

Pour pouvoir lire un fichier au format texte, vous utilisez un objet nommé StreamReader qui fait partie de System.IO.

Dans System.IO, vous avez des classes qui vous permettent de lire et écrire le contenu de fichiers soit au format binaire (BinaryReader, BinaryWriter), soit au format texte (StreamReader, StreamWriter). C’est ce qui nous intéresse ici mais il y a également des classes qui vous permettent d’obtenir des informations sur les fichiers (File) et les dossiers (Directory) et de les renommer, supprimer, déplacer, etc. Ces derniers remplacent les classes de la référence FileSystemObject.

Pour ouvrir votre fichier, il vous faut créer une instance de la classe StreamReader. Celle-ci possède 9 constructeurs différents mais vous allez utiliser le plus simple qui demande juste le nom du fichier :

Dim oStreamR As New System.IO.StreamReader(sMapFile)

Puis pour lire une ligne :

sRead = oStreamR.ReadLine

A la fin de votre fichier, ReadLine retourne un String vide.

La classe cSquares est une simple classe collection (cf article du mois dernier). Chaque élément du décors (de type cSquare) peut êre un mur, un bonus, un superBonus, etc. Pour une meilleure lisibilité de votre code, vous allez définir une nouvelle énumération définie dans cSquares :

Public Enum eSquareTypes
Vide = 0
Mur = 1
Point = 5
Bonus = 2
SuperBonus = 3
End Enum

Rien de bien différent par rapport à VB6 mais attention, en utilisant cette énumération, vous définissez un nouveau type. Cela signifie que si vous tapez le code suivant :

Dim i as Integer = 1
objSquare.SquareType = i ‘un mur

Le compilateur en mode Strict On va générer une erreur. Pour éviter cela, il faut convertir le type Integer en type eSquareTypes :

Dim i as Integer = 1
objSquare.SquareType = cType(i,eSquareTypes) ‘un mur

Pour ajouter un élément au décor, vous allez définir la méthode Add suivante :

Public Function Add(ByVal X As Integer, ByVal Y As Integer, ByVal SquareType As eSquareTypes, ByVal PoidsA As Integer) As cSquare

X et Y sont la position de l’élément, SquareType le type et Poids son poids (il nous servira par la suite pour le calcul de la trajectoire des fantômes).

Je vous laisse le soin de regarder le code qui permet d’extraire les informations d’une ligne qui est somme toute classique. N’oubliez pas tout de même de fermer votre fichier :

oStreamR.Close()

Vous aurez remarqué que pour créer mon objet, vous avez été obligé de taper System.IO.StreamReader. Vous êtes de grand fainéant comme moi (si, si) ? Vous pouvez dire au compilateur VB que dans le fichier où est écrit ce code, vous allez utiliser le Namespace System.IO. De la même façon, vous allez le prévenir que vous souhaitez utiliser les déclarations qui sont dans cSquares (l’énumération entre autres). Pour cela, ajoutez les lignes suivantes en tête de votre fichier :

Imports System.IO
Imports c2iPacMan.cSquares

Attention, il ne s’agit pas d’ajouter une nouvelle référence à votre projet, mais bel et bien de dire au compilateur que le code qui suit (dans ce fichier .vb) utilise ce Namespace.

Pour les fantômes et le PacMan, lors de leur création, vous indiquez juste leurs positions et couleurs.

Une fois tous les objets instanciés, il reste à les dessiner le tout sur votre Form. Pour cela, vous allez avoir besoin d’un autre NameSpace : System.Drawing.

Un peu de dessin
Le dessin n’a jamais été le fort de Visual Basic. J’en veux comme exemple l’aberration pour dessiner un rectangle plein :

Form1.Line (5,10) – Step(10,10),,BF

Gasp ! Comme programmation orientée objets, on faisait mieux et encore, je passe sur les Twips, AutoRedraw & Co. Pour dessiner dans une Form, il vous faut dans un premier temps obtenir l’objet où vous allez dessiner. Sous Win32, il était appelé Devicecontext. Sous MS.NET, c’est un objet Graphics qui fait partie de System.Drawing. C’est lui qui possède toutes les méthodes dont vous avez rêvé pour dessiner toutes les formes que vous voulez. Vous pourrez ainsi dessiner des lignes, des ellipses, des rectangles (classique, quoi) mais plus étonnant des courbes de Beziers, des camemberts, des images, des icônes, etc.

Comment l’obtenir ? La meilleure façon (et la plus sûre) pour récupérer le graphics d’une Form est d’utiliser l’événement Paint. Ce dernier vous renvoie l’objet e de type PaintEventArgs qui possède comme propriété l’objet Graphics ou vous souhaitez dessiner :

Public Sub Form1_Paint(ByVal sender As Object, ByVal e As System.WinForms.PaintEventArgs) Handles Form1.Paint
Dim gForm as Graphics
gForm = e.graphics

End Sub

Il existe une autre méthode que vous utiliserez dans ce projet qui obtient l’objet Graphics d’un objet à partir de son Handle :

Dim gForm as Graphics
gForm = Graphics.FromHWND(mForm.Handle)

Il est très important d’obtenir cet objet juste avant le moment où l’on va s’en servir car il change en permanence notamment quand vous redimensionnez la form. Vous comprenez maintenant pourquoi l’objet Form est une propriété de votre classe cAppli.

Maintenant, vous allez devoir dessiner des rectangles pleins en noir (pour les zones vides) et des cercles pleins (pour les bonus). Pour cela, vous devrez utilisez des Pens (stylos) et des Brushes (pinceaux).

Toutes les méthodes de Graphics qui dessinent des lignes commencent par Draw et utilisent un Pen.

Toutes les méthodes qui dessinent des formes pleines commencent par Fill et utilisent un Brush. Un Pen de couleur noire se défini ainsi :

Dim oPen as New Pen(Color.Black)

Puis pour dessiner une ligne noire du point (10,10) au point (50,50) :

gForm.DrawLine(oPen,10,10,50,50)

Dans votre cas, ce sont des zones remplies donc vous allez travailler avec des Brushes. Par exemple, pour un cercle de 10 de rayon au point (5,5), vous devez écrire :

gForm.DrawEllipse(New SolidBrush(color.Black), 5, 5, 10, 10)

Le pinceau utilisé est solide, cela signifie que le remplissage est plein, mais vous pouvez aussi utiliser des textures grâce à la classe TextureBrush. C’est ce que vous ferez pour dessiner les murs. Pour cela, le constructeur d’un TextureBrush attend un objet Image qui peut être créé à partir d’un fichier bitmap :

Dim mBitmapMur as New Bitmap(“mur.bmp”)
e.FillRectangle(New TextureBrush(mBitmapMur), 0, 0, 50, 50)

Dans ce cas, on texture un rectangle de 50 pixels de large et de hauteur à partir du fichier mur.bmp.