Voici une petite source toute simple qui permet de découper des sprites de manière industrielle, efficace ...
Avant : A l'époque ...
Imaginons un petit RPG avec des sprites de bonhommes... Il faut les mettre dans une grille de 32x32, grille visible ou pas, peu importe, puis faire une boucle qui les découpe avec un pas prédéfini.
Avantage : Rapide
Inconvénients : Les sprites ont toujours la même taille, la préparation de la plaquette de sprites est plutôt longue.
Maintenant : Avec ma source ...
Vous créez une surface, vous collez vos sprites, là ou il y a de la place, vous pouvez par exemple, mettre votre petite épée juste entre les jambes du boss, pourquoi pas ...
Le programme va simplement extraire les pixels du sprite vers un nouveau bitmap, sans prendre des bouts d'autres sprites qui seraient dans la zone de découpage.
Source / Exemple :
Public Class Form1
Public Liste_Pixels_EnCours_Traitement As New List(Of Point)
Public Matrice_Pixels_Déjà_Traités(,) As Boolean
Public Couleur_Transparente As Color
Structure Sprite_Pixel_Information
Public Position As Point
Public Couleur As Color
End Structure
Public Liste_Pixels_Composant_Le_Sprite As New List(Of Sprite_Pixel_Information)
Public Sub SPLIT_IMAGES_FROM_SURFACE(ByVal Id_Debut_Image As Integer, ByVal Index_Image_Src As Integer)
' Crée le bitmap contenant la planche de sprite
Dim BitmapSrc As Bitmap = PictureBox1.Image
' Récupere la couleur transparente, dans le coin du bitmap
Couleur_Transparente = BitmapSrc.GetPixel(0, 0)
' Redimension la matrice des pixels traités
ReDim Matrice_Pixels_Déjà_Traités(BitmapSrc.Width - 1, BitmapSrc.Height - 1)
' Initialise la matrice comme une zone non traitée
For Ny = 0 To BitmapSrc.Height - 1
For Nx = 0 To BitmapSrc.Width - 1
Matrice_Pixels_Déjà_Traités(Nx, Ny) = False
Next
Next
' Boucle principal qui parcours la zone complete en recherchant un debut de sprite.
Dim X As Integer = 0, Y As Integer = 0
For Pos As Integer = 0 To (BitmapSrc.Width * BitmapSrc.Height) - 1
' Ignore les pixels déjà traités
If Matrice_Pixels_Déjà_Traités(X, Y) = False Then
' Recherche d'un nouveau sprite grace a une couleur non-transparente
If Not (BitmapSrc.GetPixel(X, Y) = Couleur_Transparente) Then
' Pixel trouvé, indique sur la matrice que le pixel a été traité
Matrice_Pixels_Déjà_Traités(X, Y) = True
' Initialise la liste des pixels en cours et ajoute le pixel précédemment trouvé.
Liste_Pixels_EnCours_Traitement.Clear()
Liste_Pixels_EnCours_Traitement.Add(New Point(X, Y))
' Initialise la zone de découpage du sprite au coordonnée du premier pixel
SpriteEnCours.X = X : SpriteEnCours.Y = Y
SpriteEnCours.Width = X : SpriteEnCours.Height = Y
' Lance le traitement, en cherchant tout les pixels composant le sprite
zSPLIT_Voisin(BitmapSrc)
' Verifie la validité du sprite grace a ses dimensions >0
If SpriteEnCours.Width - SpriteEnCours.X > 0 And SpriteEnCours.Height - SpriteEnCours.Y > 0 Then
' Crée un bitmap de destination
Dim BitmapDSt As New Bitmap(SpriteEnCours.Width - SpriteEnCours.X + 1, SpriteEnCours.Height - SpriteEnCours.Y + 1)
' Parcours la liste des pixels composants le sprite et reconstruit le sprite tout seul
For N = 0 To Liste_Pixels_Composant_Le_Sprite.Count - 1
BitmapDSt.SetPixel(Liste_Pixels_Composant_Le_Sprite(N).Position.X - SpriteEnCours.X, Liste_Pixels_Composant_Le_Sprite(N).Position.Y - SpriteEnCours.Y, Liste_Pixels_Composant_Le_Sprite(N).Couleur)
Next
' Affiche le resultat dans le deuxieme picturebox
PictureBox2.Image = BitmapDSt
PictureBox2.Update()
' Dodo 0.1 s
Threading.Thread.Sleep(100)
End If
End If
End If
' Incrémente la position de recherche de la boucle principal
If X >= BitmapSrc.Width - 1 Then X = 0 : Y += 1 Else X += 1
Next
End Sub
Public SpriteEnCours As New Rectangle
Sub zSPLIT_Voisin(ByRef BitmapSrc As Bitmap)
' Vide la liste des pixels qui composent le sprite.
Liste_Pixels_Composant_Le_Sprite.Clear()
Do
' Si plus de pixel à traiter, sortir de la boucle, le sprite est terminé.
If Liste_Pixels_EnCours_Traitement.Count = 0 Then Exit Do
' Récupére les coordonnées du premier pixel à traiter.
Dim X As Integer = Liste_Pixels_EnCours_Traitement(0).X
Dim Y As Integer = Liste_Pixels_EnCours_Traitement(0).Y
' Supprime le pixel de la liste des pixels à traiter
Liste_Pixels_EnCours_Traitement.RemoveAt(0)
' Ajoute les informations du pixel dans la liste des pixels qui compose le sprite
Dim Pixel As New Sprite_Pixel_Information
Pixel.Position = New Point(X, Y)
Pixel.Couleur = BitmapSrc.GetPixel(X, Y)
Liste_Pixels_Composant_Le_Sprite.Add(Pixel)
' Réajuste en temps réél la zone de découpage du sprite
If SpriteEnCours.X > X Then SpriteEnCours.X = X
If SpriteEnCours.Y > Y Then SpriteEnCours.Y = Y
If SpriteEnCours.Width < X Then SpriteEnCours.Width = X
If SpriteEnCours.Height < Y Then SpriteEnCours.Height = Y
' Controle les voisins Gauche, Droite, Bas, Haut
If X - 1 >= 0 Then ZVoisinRoutine(BitmapSrc, X - 1, Y)
If X + 1 < BitmapSrc.Width Then ZVoisinRoutine(BitmapSrc, X + 1, Y)
If Y - 1 >= 0 Then ZVoisinRoutine(BitmapSrc, X, Y - 1)
If Y + 1 < BitmapSrc.Height Then ZVoisinRoutine(BitmapSrc, X, Y + 1)
Loop
End Sub
Conclusion :
L'utilisation de SET PIXEL et GET PIXEL sont ici utilisés dans un but éducatif.
Je conseille de stocker le bitmap dans un tableau et de traiter le tout ! Class MARSHALL par exemple !
Le fait de placer les sprites n'importe où à l'inconvénient d'être difficile a exploiter lors d'une animation.
Je conseille de joindre un fichier qui fera une correspondance entre l'index du sprite découpé et son ordre dans une animation, ou indiquer des caractèristiques sûpplémentaires, tel offset ou autres ...
J'espère que cette première source vous servira ...
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.