Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

METHODE SUPERMAP, TUTO TILES 6 !


Information sur la source

Catégorie :Direct X Classé sous : tiles, directx, directdraw, jeu, tile Niveau : Initié Date de création : 04/05/2006 Vu / téléchargé: 4 867 / 831

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (13)
Ajouter un commentaire et/ou une note

Description

Cliquez pour voir la capture en taille normale
Oui oui, aprés tant d'attente, je met se code à votre disposition, en faite je l'avais fini il y a quelque temps, mais je n'ai pas eu le temps de le poster.
Avec ce type de map, on gere trois couches pour une carte, je m'explique :
Une couche pour le sol
Une couche pour les objets du sol utilisant une couleur transparente (colorkey)
Une couche pour les surfaces au dessus du personnage (feuilles d'arbre,...)

Pour se qui est du code, je ne commenterais pas tout car une majorité du code est la même que le tuto des map indirectes, d'animation (pour un perso), et de map de taille inifinie.

Donc le code principal, le chargement du fichier map et la création de la surface à afficher :
 

Source

  • 'Le type qu'on utilise pour la map, ça permet d'avoir toutes les variables sous la main
  • Public Type map
  • Matrice() As String 'Le sol
  • MatriceB() As String 'Le sol avec transparence
  • MatriceH() As String 'Par dessus le hero
  • MatCol() As String 'Non utilisez dans le zip, sert pour la collision
  • MapSource As DirectDrawSurface7 'Une image contenant tout les tiles
  • ddsdMapSource As DDSURFACEDESC2 'Sont descripteurs
  • MapName As String 'Le nom de la carte qu'on charge, inclu dans le fichier map
  • PathCol As String 'Le chemin de la matrice de collision
  • TileSize As String 'La taille d'un tile (en pixel), on peut utiliser diverse taille pour chaque map et ainsi faire des jeux de zoom....
  • SplitSize As String 'Le nombre de caractere définissant un tile dans la matrice (ex : SplitSize = 4 alors 0000 0000 0000)
  • End Type 'Fin du type :D
  • Public MapTest As map 'On défini une variable qui utilisera se type
  • Public Function LoadMap(MapPath As String) 'La fonction magique !!
  • '**********Chargement de la matrice *************
  • 'Déclaration des variables
  • Dim TempString As String 'Variable temporaire de type string
  • Dim i As Long, size As Integer, state As String
  • Dim File As Byte
  • 'Ouverture du fichier
  • File = FreeFile 'On cree un reference libre pour un fichier
  • Open MapPath For Input As #File 'On ouvre le fichier map que pour la lecture (input)
  • Line Input #File, MapTest.MapName 'On lit la premiere ligne : Le nom de la carte
  • Line Input #File, MapTest.TileSize 'On lit la deuxieme ligne : La taille d'un tile
  • Line Input #File, MapTest.SplitSize 'On lit la troisieme ligne : La taille de la chaine de caractere definissant un tile dans les matrices d'affichages (powaaaa la phrase !)
  • Do Until EOF(File) 'Tant qu'on est pas a la fin du fichier on recommence (avant j'utiliser Do While Not EOF c'est pareil)
  • 'Lecture d'une ligne
  • Line Input #File, TempString
  • If TempString <> "bas" And TempString <> "haut" And state = vbNullString Then 'On verifie que c'est la premiere couche, le sol
  • 'Decoupage matrice du sol
  • If TempString <> vbNullString Then 'Si TempString n'est pas vide
  • ReDim Preserve MapTest.Matrice((Len(TempString) \ MapTest.SplitSize) - 1, size) 'On dimensionne la matrice
  • End If
  • i = 0 'On initialise i
  • Do While Len(TempString) >= MapTest.SplitSize 'Tant que TempSttring et superieur à SplitSize
  • DoEvents 'On laisse calculer le processeur (evite les freeze)
  • MapTest.Matrice(i, size) = Left$(TempString, MapTest.SplitSize) 'On met le nombre de caractere correspondant à 1 tile dans la matrice
  • i = i + 1
  • TempString = Mid$(TempString, MapTest.SplitSize + 1) 'On enleve les caracteres deja pris (ci dessus)
  • Loop 'On recommence
  • size = UBound(MapTest.Matrice, 2) + 1 'On incremente size pour le redimensionnement plus haut
  • ElseIf state = "bas" And TempString <> "haut" Then 'Meme chose mais pour la couche du sol avec transparence
  • 'If TempString <> "haut" Then
  • 'Decoupage matrice du bas
  • If TempString <> vbNullString Then
  • ReDim Preserve MapTest.MatriceB((Len(TempString) \ MapTest.SplitSize) - 1, size)
  • End If
  • i = 0
  • Do While Len(TempString) >= MapTest.SplitSize
  • DoEvents
  • MapTest.MatriceB(i, size) = Left$(TempString, MapTest.SplitSize)
  • i = i + 1
  • TempString = Mid$(TempString, MapTest.SplitSize + 1)
  • Loop
  • size = UBound(MapTest.MatriceB, 2) + 1
  • 'End If
  • ElseIf state = "haut" Then 'Meme chose met pour la couche au dessus du hero
  • 'If TempString <> "bas" Then
  • 'Decoupage matrice du haut
  • If TempString <> vbNullString Then
  • ReDim Preserve MapTest.MatriceH((Len(TempString) \ MapTest.SplitSize) - 1, size)
  • End If
  • i = 0
  • Do While Len(TempString) >= MapTest.SplitSize
  • DoEvents
  • MapTest.MatriceH(i, size) = Left$(TempString, MapTest.SplitSize)
  • i = i + 1
  • TempString = Mid$(TempString, MapTest.SplitSize + 1)
  • Loop
  • size = UBound(MapTest.MatriceH, 2) + 1
  • 'End If
  • Else
  • state = TempString
  • size = 0
  • End If
  • Loop
  • Close #File
  • '*************************************************************************************************
  • 'Ici on a lu entierement le fichier, il faut creer la surface à afficher à partir de notre matrice
  • 'MapSource est la surface contenant les tiles
  • Set MapTest.MapSource = dd.CreateSurfaceFromFile(App.Path & "\" & MapTest.MapName, MapTest.ddsdMapSource) 'On assigne a la surface le fichier correspondant.
  • 'Creation de 3 surfaces vierges de la taille maximales
  • ddsdCSol.lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
  • ddsdCSol.ddscaps.lCaps = DDSCAPS_VIDEOMEMORY
  • ddsdCTransparent.lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
  • ddsdCTransparent.ddscaps.lCaps = DDSCAPS_VIDEOMEMORY
  • ddsdCDessus.lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
  • ddsdCDessus.ddscaps.lCaps = DDSCAPS_VIDEOMEMORY
  • 'On donne les dimensions a la surface
  • '**************************************************************************************
  • 'Dans mes tuto precedent il me semble qu'il y a une erreur sur la taille d'une map, dans le code ci present l'erreur est rectifier
  • '**************************************************************************************
  • 'On test pour verifier que notre carte n'est pas defini sur un tile horizontale ou un tile vertical seulement
  • 'Il y a trois surface vierge car il y a trois couches
  • If (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize <> 0 Then
  • ddsdCSol.lHeight = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize
  • ddsdCTransparent.lHeight = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize
  • ddsdCDessus.lHeight = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize
  • Else
  • ddsdCSol.lHeight = MapTest.TileSize
  • ddsdCTransparent.lHeight = MapTest.TileSize
  • ddsdCDessus.lHeight = MapTest.TileSize
  • End If
  • If (UBound(MapTest.Matrice, 1)) * MapTest.TileSize <> 0 Then
  • ddsdCSol.lWidth = (UBound(MapTest.Matrice, 1)) * MapTest.TileSize + MapTest.TileSize
  • ddsdCTransparent.lWidth = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize + MapTest.TileSize
  • ddsdCDessus.lWidth = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize + MapTest.TileSize
  • Else
  • ddsdCSol.lWidth = MapTest.TileSize
  • ddsdCTransparent.lHeight = MapTest.TileSize
  • ddsdCDessus.lHeight = MapTest.TileSize
  • End If
  • 'On assigne les descripteurs au surface correspondantes
  • Set CSol = dd.CreateSurface(ddsdCSol)
  • Set CTransparent = dd.CreateSurface(ddsdCTransparent)
  • Set CDessus = dd.CreateSurface(ddsdCDessus)
  • 'On rempli les surface de noir pour eviter les bug d'affichage
  • CTransparent.BltColorFill ddRect(0, 0, 0, 0), RGB(255, 0, 255) 'Couche du sol avec element transparent
  • CDessus.BltColorFill ddRect(0, 0, 0, 0), RGB(255, 0, 255) 'Couche au dessus du hero
  • 'Les variables utilisé dans les calcules suivant
  • Dim x As Integer, y As Integer
  • Dim sX1 As Long, sX2 As Long, sY1 As Long, sY2 As Long
  • Dim dX1 As Long, dX2 As Long, dY1 As Long, dY2 As Long
  • Dim temp As Long, Largeur As Long
  • 's signifie source et d destination
  • 'Si on a plusieurs Tiles on utilise un procédé un peu complexe de calcul de position correspondant a la position d'un tile sur l'image source et sur la destination (destination = notre map finale)
  • If ((UBound(MapTest.Matrice, 1)) * MapTest.TileSize <> 0) And (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize <> 0 Then
  • 'On defini la largeur de la map
  • Largeur = (MapTest.ddsdMapSource.lWidth \ MapTest.TileSize) * MapTest.TileSize
  • 'Pour chaque tile
  • For x = 0 To UBound(MapTest.Matrice, 1)
  • For y = 0 To UBound(MapTest.Matrice, 2)
  • 'On calcul les dimentsion de destination
  • dX1 = x * MapTest.TileSize
  • dX2 = dX1 + MapTest.TileSize
  • dY1 = y * MapTest.TileSize
  • dY2 = dY1 + MapTest.TileSize
  • 'Et les dimension de la source pour le sol
  • sX1 = MapTest.Matrice(x, y) * MapTest.TileSize
  • sX2 = sX1 + MapTest.TileSize
  • If sX1 > Largeur Then
  • sY1 = (sX1 \ Largeur)
  • sX1 = sX1 - (Largeur * sY1)
  • sX2 = sX1 + MapTest.TileSize
  • sY1 = sY1 * MapTest.TileSize
  • sY2 = sY1 + MapTest.TileSize
  • Else
  • sX1 = MapTest.Matrice(x, y) * MapTest.TileSize
  • sX2 = sX1 + MapTest.TileSize
  • sY1 = 0
  • sY2 = sY1 + MapTest.TileSize
  • End If
  • 'Avec les dimension calculé on blit le tile correspondant à la bonne position sur notre matrice du sol
  • CSol.Blt ddRect(dX1, dY1, dX2, dY2), MapTest.MapSource, ddRect(sX1, sY1, sX2, sY2), DDBLT_WAIT
  • 'On recommence pour la couche du sol avec des elements transparents
  • If MapTest.MatriceB(x, y) <> "----" Then
  • sX1 = MapTest.MatriceB(x, y) * MapTest.TileSize
  • sX2 = sX1 + MapTest.TileSize
  • If sX1 > Largeur Then
  • sY1 = (sX1 \ Largeur)
  • sX1 = sX1 - (Largeur * sY1)
  • sX2 = sX1 + MapTest.TileSize
  • sY1 = sY1 * MapTest.TileSize
  • sY2 = sY1 + MapTest.TileSize
  • Else
  • sX1 = MapTest.MatriceB(x, y) * MapTest.TileSize
  • sX2 = sX1 + MapTest.TileSize
  • sY1 = 0
  • sY2 = sY1 + MapTest.TileSize
  • End If
  • CTransparent.Blt ddRect(dX1, dY1, dX2, dY2), MapTest.MapSource, ddRect(sX1, sY1, sX2, sY2), DDBLT_WAIT
  • End If
  • 'Enfin pour la matrice au dessus du hero et des perso (feuille d'arbres, tunnel,...)
  • If MapTest.MatriceH(x, y) <> "----" Then
  • sX1 = MapTest.MatriceH(x, y) * MapTest.TileSize
  • sX2 = sX1 + MapTest.TileSize
  • If sX1 > Largeur Then
  • sY1 = (sX1 \ Largeur)
  • sX1 = sX1 - (Largeur * sY1)
  • sX2 = sX1 + MapTest.TileSize
  • sY1 = sY1 * MapTest.TileSize
  • sY2 = sY1 + MapTest.TileSize
  • Else
  • sX1 = MapTest.MatriceH(x, y) * MapTest.TileSize
  • sX2 = sX1 + MapTest.TileSize
  • sY1 = 0
  • sY2 = sY1 + MapTest.TileSize
  • End If
  • CDessus.Blt ddRect(dX1, dY1, dX2, dY2), MapTest.MapSource, ddRect(sX1, sY1, sX2, sY2), DDBLT_WAIT
  • End If
  • Next y
  • Next x
  • 'Si il n'y a qu'un Tile c'est plus simple, les coordonnées sont logiques
  • Else
  • sY1 = Round((MapTest.Matrice(x, y) * MapTest.TileSize) / MapTest.ddsdMapSource.lWidth, 0)
  • sY1 = sY1 * MapTest.TileSize
  • sY2 = sY1 + MapTest.TileSize
  • sX1 = MapTest.Matrice(x, y) * MapTest.TileSize
  • sX1 = sX1 - (MapTest.ddsdMapSource.lWidth * Round(((MapTest.Matrice(x, y) * MapTest.TileSize) / MapTest.ddsdMapSource.lWidth), 0))
  • sX2 = sX1 + MapTest.TileSize
  • dX1 = 0
  • dX2 = 16
  • dY1 = 0
  • dY2 = 16
  • CSol.Blt ddRect(dX1, dY1, dX2, dY2), MapTest.MapSource, ddRect(sX1, sY1, sX2, sY2), DDBLT_WAIT
  • End If
  • End Function
  • 'Voila nos surfaces sont pretes a etre affiche :
  • 'On distingue deux cas, ccelui ou la carte est inferieur à la taille de l'ecran (800*600 dans l'exemple), et celui ou c'est superieur
  • If ddsdCSol.lWidth <= 800 And ddsdCSol.lHeight <= 600 Then
  • 'Dans le cas inferieur, on fait un simple BltFast
  • Backbuffer.BltFast 0, 0, CSol, ddRect(0, 0, 0, 0), DDBLTFAST_WAIT
  • Backbuffer.BltFast 0, 0, CTransparent, ddRect(0, 0, 0, 0), DDBLTFAST_SRCCOLORKEY
  • Else
  • 'Dans l'autre cas on fait un Blt en utilisant des coordonnée de source et de destination
  • Backbuffer.Blt ddRect(0, 0, 800, 600), CSol, ddRect(X1Map, Y1Map, X2Map, Y2Map), DDBLT_WAIT
  • Backbuffer.Blt ddRect(0, 0, 800, 600), CTransparent, ddRect(X1Map, Y1Map, X2Map, Y2Map), DDBLT_KEYSRC Or DDBLT_WAIT
  • End If
  • 'On met le perso dessus les couches de sols mais avant la couche de dessus
  • Backbuffer.Blt ddRect(PersoX, PersoY, PersoX + 32, PersoY + 48), SPerso, ddRect(PersoSX1, PersoSY1, PersoSX2, PersoSY2), DDBLT_KEYSRC
  • 'Meme raisonnement en deux cas :
  • If ddsdCSol.lWidth <= 800 And ddsdCSol.lHeight <= 600 Then
  • Backbuffer.BltFast 0, 0, CDessus, ddRect(0, 0, 0, 0), DDBLTFAST_SRCCOLORKEY
  • Else
  • Backbuffer.Blt ddRect(0, 0, 800, 600), CDessus, ddRect(X1Map, Y1Map, X2Map, Y2Map), DDBLT_KEYSRC Or DDBLT_WAIT
  • End If
'Le type qu'on utilise pour la map, ça permet d'avoir toutes les variables sous la main

Public Type map
    
    Matrice() As String               'Le sol
    MatriceB() As String              'Le sol avec transparence
    MatriceH() As String              'Par dessus le hero
    MatCol() As String                'Non utilisez dans le zip, sert pour la collision
    MapSource As DirectDrawSurface7   'Une image contenant tout les tiles
    ddsdMapSource As DDSURFACEDESC2   'Sont descripteurs
    MapName As String                 'Le nom de la carte qu'on charge, inclu dans le fichier map
    PathCol As String                 'Le chemin de la matrice de collision
    TileSize As String                'La taille d'un tile (en pixel), on peut utiliser diverse taille pour chaque map et ainsi faire des jeux de zoom....
    SplitSize As String               'Le nombre de caractere définissant un tile dans la matrice (ex : SplitSize = 4 alors 0000 0000 0000)
End Type    'Fin du type :D

Public MapTest As map      'On défini une variable qui utilisera se type


Public Function LoadMap(MapPath As String)               'La fonction magique !!
    '**********Chargement de la matrice *************
    'Déclaration des variables
    Dim TempString As String                'Variable temporaire de type string
    Dim i As Long, size As Integer, state As String 
    Dim File As Byte

    'Ouverture du fichier
    File = FreeFile                      'On cree un reference libre pour un fichier
    Open MapPath For Input As #File                  'On ouvre le fichier map que pour la lecture (input)
            Line Input #File, MapTest.MapName        'On lit la premiere ligne : Le nom de la carte
            Line Input #File, MapTest.TileSize       'On lit la deuxieme ligne : La taille d'un tile
            Line Input #File, MapTest.SplitSize      'On lit la troisieme ligne : La taille de la chaine de caractere definissant un tile dans les matrices d'affichages (powaaaa la phrase !)
            Do Until EOF(File)     'Tant qu'on est pas a la fin du fichier on recommence (avant j'utiliser Do While Not EOF c'est pareil)
            'Lecture d'une ligne
                Line Input #File, TempString
                
                If TempString <> "bas" And TempString <> "haut" And state = vbNullString Then   'On verifie que c'est la premiere couche, le sol
                
                'Decoupage matrice du sol
 
                    If TempString <> vbNullString Then           'Si TempString n'est pas vide
                        ReDim Preserve MapTest.Matrice((Len(TempString) \ MapTest.SplitSize) - 1, size)   'On dimensionne la matrice
                    End If
                
                    i = 0     'On initialise i
                    Do While Len(TempString) >= MapTest.SplitSize         'Tant que TempSttring et superieur à SplitSize
                        DoEvents            'On laisse calculer le processeur  (evite les freeze)
                        MapTest.Matrice(i, size) = Left$(TempString, MapTest.SplitSize)    'On met le nombre de caractere correspondant à 1 tile dans la matrice
                        i = i + 1
                        TempString = Mid$(TempString, MapTest.SplitSize + 1)  'On enleve les caracteres deja pris (ci dessus)
                    Loop 'On recommence
                    size = UBound(MapTest.Matrice, 2) + 1  'On incremente size pour le redimensionnement plus haut
                                    
                ElseIf state = "bas" And TempString <> "haut" Then 'Meme chose mais pour la couche du sol avec transparence
                    
                    'If TempString <> "haut" Then
                        'Decoupage matrice du bas
                        If TempString <> vbNullString Then
                            ReDim Preserve MapTest.MatriceB((Len(TempString) \ MapTest.SplitSize) - 1, size)
                        End If
                
                        i = 0
                        Do While Len(TempString) >= MapTest.SplitSize
                            DoEvents
                            MapTest.MatriceB(i, size) = Left$(TempString, MapTest.SplitSize)
                            i = i + 1
                            TempString = Mid$(TempString, MapTest.SplitSize + 1)
                        Loop
                        size = UBound(MapTest.MatriceB, 2) + 1
                    'End If
                    
                ElseIf state = "haut" Then   'Meme chose met pour la couche au dessus du hero
                    
                    'If TempString <> "bas" Then
                        'Decoupage matrice du haut
                        If TempString <> vbNullString Then
                            ReDim Preserve MapTest.MatriceH((Len(TempString) \ MapTest.SplitSize) - 1, size)
                        End If
                
                        i = 0
                        Do While Len(TempString) >= MapTest.SplitSize
                            DoEvents
                            MapTest.MatriceH(i, size) = Left$(TempString, MapTest.SplitSize)
                            i = i + 1
                            TempString = Mid$(TempString, MapTest.SplitSize + 1)
                        Loop
                        size = UBound(MapTest.MatriceH, 2) + 1
                    'End If
                Else
                    state = TempString
                    size = 0
                End If
            Loop
    Close #File
'*************************************************************************************************    
'Ici on a lu entierement le fichier, il faut creer la surface à afficher à partir de notre matrice

'MapSource est la surface contenant les tiles
    Set MapTest.MapSource = dd.CreateSurfaceFromFile(App.Path & "\" & MapTest.MapName, MapTest.ddsdMapSource) 'On assigne a la surface le fichier correspondant.
    
    'Creation de 3 surfaces vierges de la taille maximales
    ddsdCSol.lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
    ddsdCSol.ddscaps.lCaps = DDSCAPS_VIDEOMEMORY
    
    ddsdCTransparent.lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
    ddsdCTransparent.ddscaps.lCaps = DDSCAPS_VIDEOMEMORY
    
    ddsdCDessus.lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
    ddsdCDessus.ddscaps.lCaps = DDSCAPS_VIDEOMEMORY
    
'On donne les dimensions a la surface 
'**************************************************************************************
'Dans mes tuto precedent il me semble qu'il y a une erreur sur la taille d'une map, dans le code ci present l'erreur est rectifier
'**************************************************************************************
'On test pour verifier que notre carte n'est pas defini sur un tile horizontale ou un tile vertical seulement
'Il y a trois surface vierge car il y a trois couches
    If (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize <> 0 Then
        ddsdCSol.lHeight = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize
        ddsdCTransparent.lHeight = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize
        ddsdCDessus.lHeight = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize
    Else
        ddsdCSol.lHeight = MapTest.TileSize
        ddsdCTransparent.lHeight = MapTest.TileSize
        ddsdCDessus.lHeight = MapTest.TileSize
    End If
    If (UBound(MapTest.Matrice, 1)) * MapTest.TileSize <> 0 Then
        ddsdCSol.lWidth = (UBound(MapTest.Matrice, 1)) * MapTest.TileSize + MapTest.TileSize
        ddsdCTransparent.lWidth = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize + MapTest.TileSize
        ddsdCDessus.lWidth = (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize + MapTest.TileSize
    Else
        ddsdCSol.lWidth = MapTest.TileSize
        ddsdCTransparent.lHeight = MapTest.TileSize
        ddsdCDessus.lHeight = MapTest.TileSize
    End If
    
    
    'On assigne les descripteurs au surface correspondantes
    Set CSol = dd.CreateSurface(ddsdCSol)
    Set CTransparent = dd.CreateSurface(ddsdCTransparent)
    Set CDessus = dd.CreateSurface(ddsdCDessus)
    
    'On rempli les surface de noir pour eviter les bug d'affichage
    CTransparent.BltColorFill ddRect(0, 0, 0, 0), RGB(255, 0, 255)  'Couche du sol avec element transparent
    CDessus.BltColorFill ddRect(0, 0, 0, 0), RGB(255, 0, 255)       'Couche au dessus du hero
    
    'Les variables utilisé dans les calcules suivant
    Dim x As Integer, y As Integer
    Dim sX1 As Long, sX2 As Long, sY1 As Long, sY2 As Long
    Dim dX1 As Long, dX2 As Long, dY1 As Long, dY2 As Long
    Dim temp As Long, Largeur As Long
    
    's signifie source et d destination

    'Si on a plusieurs Tiles on utilise un procédé un peu complexe de calcul de position correspondant a la position d'un tile sur l'image source et sur la destination (destination = notre map finale)
    If ((UBound(MapTest.Matrice, 1)) * MapTest.TileSize <> 0) And (UBound(MapTest.Matrice, 2) + 1) * MapTest.TileSize <> 0 Then
    'On defini la largeur de la map
    Largeur = (MapTest.ddsdMapSource.lWidth \ MapTest.TileSize) * MapTest.TileSize
        'Pour chaque tile
        For x = 0 To UBound(MapTest.Matrice, 1)
            For y = 0 To UBound(MapTest.Matrice, 2)
                    
                    'On calcul les dimentsion de destination
                    dX1 = x * MapTest.TileSize
                    dX2 = dX1 + MapTest.TileSize
                    dY1 = y * MapTest.TileSize
                    dY2 = dY1 + MapTest.TileSize
                    
                'Et les dimension de la source pour le sol
                    sX1 = MapTest.Matrice(x, y) * MapTest.TileSize
                    sX2 = sX1 + MapTest.TileSize
                
                If sX1 > Largeur Then
                
                    sY1 = (sX1 \ Largeur)
                    
                    sX1 = sX1 - (Largeur * sY1)
                    sX2 = sX1 + MapTest.TileSize
                    sY1 = sY1 * MapTest.TileSize
                    sY2 = sY1 + MapTest.TileSize
                    
                Else
                    sX1 = MapTest.Matrice(x, y) * MapTest.TileSize
                    sX2 = sX1 + MapTest.TileSize
                    sY1 = 0
                    sY2 = sY1 + MapTest.TileSize
                End If
                'Avec les dimension calculé on blit le tile correspondant à la bonne position sur notre matrice du sol
                CSol.Blt ddRect(dX1, dY1, dX2, dY2), MapTest.MapSource, ddRect(sX1, sY1, sX2, sY2), DDBLT_WAIT
                
 
                'On recommence pour la couche du sol avec des elements transparents
                If MapTest.MatriceB(x, y) <> "----" Then
                    sX1 = MapTest.MatriceB(x, y) * MapTest.TileSize
                    sX2 = sX1 + MapTest.TileSize
                
                    If sX1 > Largeur Then
                
                        sY1 = (sX1 \ Largeur)
                    
                        sX1 = sX1 - (Largeur * sY1)
                        sX2 = sX1 + MapTest.TileSize
                        sY1 = sY1 * MapTest.TileSize
                        sY2 = sY1 + MapTest.TileSize
                    
                    Else
                        sX1 = MapTest.MatriceB(x, y) * MapTest.TileSize
                        sX2 = sX1 + MapTest.TileSize
                        sY1 = 0
                        sY2 = sY1 + MapTest.TileSize
                    End If
                    CTransparent.Blt ddRect(dX1, dY1, dX2, dY2), MapTest.MapSource, ddRect(sX1, sY1, sX2, sY2), DDBLT_WAIT
                End If
                
                'Enfin pour la matrice au dessus du hero et des perso (feuille d'arbres, tunnel,...)
                If MapTest.MatriceH(x, y) <> "----" Then
                    sX1 = MapTest.MatriceH(x, y) * MapTest.TileSize
                    sX2 = sX1 + MapTest.TileSize
                
                    If sX1 > Largeur Then
                
                        sY1 = (sX1 \ Largeur)
                    
                        sX1 = sX1 - (Largeur * sY1)
                        sX2 = sX1 + MapTest.TileSize
                        sY1 = sY1 * MapTest.TileSize
                        sY2 = sY1 + MapTest.TileSize
                        
                    Else
                        sX1 = MapTest.MatriceH(x, y) * MapTest.TileSize
                        sX2 = sX1 + MapTest.TileSize
                        sY1 = 0
                        sY2 = sY1 + MapTest.TileSize
                    End If
                    CDessus.Blt ddRect(dX1, dY1, dX2, dY2), MapTest.MapSource, ddRect(sX1, sY1, sX2, sY2), DDBLT_WAIT
                End If
            Next y
            
        Next x
    'Si il n'y a qu'un Tile c'est plus simple, les coordonnées sont logiques
    Else
        sY1 = Round((MapTest.Matrice(x, y) * MapTest.TileSize) / MapTest.ddsdMapSource.lWidth, 0)
        sY1 = sY1 * MapTest.TileSize
        sY2 = sY1 + MapTest.TileSize
        sX1 = MapTest.Matrice(x, y) * MapTest.TileSize
        sX1 = sX1 - (MapTest.ddsdMapSource.lWidth * Round(((MapTest.Matrice(x, y) * MapTest.TileSize) / MapTest.ddsdMapSource.lWidth), 0))
        sX2 = sX1 + MapTest.TileSize
        
        dX1 = 0
        dX2 = 16
        dY1 = 0
        dY2 = 16
        
        CSol.Blt ddRect(dX1, dY1, dX2, dY2), MapTest.MapSource, ddRect(sX1, sY1, sX2, sY2), DDBLT_WAIT
        
    End If
   
End Function

'Voila nos surfaces sont pretes a etre affiche :
'On distingue deux cas, ccelui ou la carte est inferieur à la taille de l'ecran (800*600 dans l'exemple), et celui ou c'est superieur
        If ddsdCSol.lWidth <= 800 And ddsdCSol.lHeight <= 600 Then
            'Dans le cas inferieur, on fait un simple BltFast
            Backbuffer.BltFast 0, 0, CSol, ddRect(0, 0, 0, 0), DDBLTFAST_WAIT
            Backbuffer.BltFast 0, 0, CTransparent, ddRect(0, 0, 0, 0), DDBLTFAST_SRCCOLORKEY
        
        Else
            'Dans l'autre cas on fait un Blt en utilisant des coordonnée de source et de destination
            Backbuffer.Blt ddRect(0, 0, 800, 600), CSol, ddRect(X1Map, Y1Map, X2Map, Y2Map), DDBLT_WAIT
            Backbuffer.Blt ddRect(0, 0, 800, 600), CTransparent, ddRect(X1Map, Y1Map, X2Map, Y2Map), DDBLT_KEYSRC Or DDBLT_WAIT
            
        End If
        'On met le perso dessus les couches de sols mais avant la couche de dessus
        Backbuffer.Blt ddRect(PersoX, PersoY, PersoX + 32, PersoY + 48), SPerso, ddRect(PersoSX1, PersoSY1, PersoSX2, PersoSY2), DDBLT_KEYSRC
        
'Meme raisonnement en deux cas :
        If ddsdCSol.lWidth <= 800 And ddsdCSol.lHeight <= 600 Then
            
            Backbuffer.BltFast 0, 0, CDessus, ddRect(0, 0, 0, 0), DDBLTFAST_SRCCOLORKEY
            
        Else
        
            Backbuffer.Blt ddRect(0, 0, 800, 600), CDessus, ddRect(X1Map, Y1Map, X2Map, Y2Map), DDBLT_KEYSRC Or DDBLT_WAIT
            
        End If

Conclusion

Voila, c'est à peu pret la totalité du code qui permet d'afficher des supermap.
Pour un exemple concret regarder dans le zip, le code du zip n'est pas commenté.

Pour faire cette map j'ai utilisé un editeur de tile supermap, cependant il est blindé de bug donc je ne pense pas le publié sur ce site si il n'y a pas de demande.

J'ai encadré le personnage dans la capture d'ecran.

J'ai failli oublié, la méthode qui permet le deplacement de personnage est un peu different de celle présenté dans mon tuto précédent, en faite j'utilise une image au lieu de plusieurs et je change les coordonnees de source.
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Commentaires et avis

signaler à un administrateur
Commentaire de Renfield le 05/05/2006 10:19:53 administrateur CS

il pourrait etre sympa de faire un chargement dynamique....
de sorte a n'avoir en mémoire que les zones sises autour du personnage.

on pourrais ainsi avoir des cartes gigantesques, pour presque pas de mémoire

signaler à un administrateur
Commentaire de ciberrique le 05/05/2006 11:51:41

Je suis pas sur de comprendre, quand tu dis dynamique c'est en faite pour une carte plus grande que l'ecran on charge que la partie qui nous interresse (qui est visible) ?

signaler à un administrateur
Commentaire de NHenry le 05/05/2006 12:16:00

Oui, mais je conseillerais en légerement plus grand, pour pouvoir charger les images en asynchrone, sans que l'utilisateur ne voit la saccade durant le chargement des zonnes qui pourraient être affichées peu de temps après.

signaler à un administrateur
Commentaire de ciberrique le 05/05/2006 12:21:35

Oui c'est une idée, je vais y reflechir.

signaler à un administrateur
Commentaire de diiplayer le 23/05/2006 02:12:44

C'est bien intéressant ce tuto.De plus, j'ai travaillé un peu de mon coté, car j'ai une bibliothèque de 2 milliers de tiles ... et tout les loaders en meme temps prenait du temps et beaucoup de CPU, donc j'ai mit au point quelque ligne qui analyse le fichier .map pour trouvé le numéro des tiles utilisés et ainsi on peut charger que le nécéssaire. Je vous donnerais bien le code, mais puisqu'il utilise un petit control bien simple que je me suis faite (simplement pour aller cherché et mettre en Tableau les tiles de la map) sa ne serais pas trop clair pour vous. Il s'agit ici simplement de mettre en mémoire les numéros de Tiles qu'il voit, par la suite, a l'aide d'une boucle For, il va aller lire ces données pour loader l'essentiel.

Je ne sais pas si l'un de vous aurais une solution a mon problème. Étant donné que je suis un mauvais graphiste et que les jeux de nos jours, hélas, requiert un minimun de beauté, ben je me suis dit que j'pourrais bien aller chercher des tilesets sur internet ... mais le 3/4 est en iso, quelqu'un aurait-il une solution pour sa? (je doit avouer que pour les collisions et les tiles, la gérance en utilisant un tableau me semble un peu inadapté pour en vue iso)

signaler à un administrateur
Commentaire de ciberrique le 23/05/2006 16:27:53

Salut, cherche du coté de rpgmaker pour les tiles, il y en a des 100aines et tous trés beau !

Autrement pour la méthode d'affichage supermap je travaille sur une version 2 qui est beaucoup plus rapide au chargement et beaucoup plus puissante et beaucoup moins lourde au niveau du fichier map...

A venir...

signaler à un administrateur
Commentaire de diiplayer le 23/05/2006 22:00:40

D'accord, je chercherai donc de ce coté. Je risque également de me lancé dans la confection d'un éditeur de Map sans bug puisque j'en aurai énormément besoin pour mon jeu (qui soit dit en passant, j'avais posté hier mais il semble qu'on l'aille supprimé car puisque la source était trop grosse, j'Avais seulement mit un lien pour la downloader ailleur :'( ) Donc si tu aimerais de quoi en particulier dans l'editeur, fait moi en part :)

signaler à un administrateur
Commentaire de ciberrique le 23/05/2006 22:07:48

Mon ancien editeur fonctionnait a 90% mais par contre il ne prend pas en charge la nouvelle version supermap, toutfois il le prendra, de plus mon editeur gere les collisions aussi. Si tu le souhaite je peux te l'envoyer une fois adapter au supermap v2.

signaler à un administrateur
Commentaire de diiplayer le 24/05/2006 15:11:05

Ce n'Est pas toi qui a dit que ton editeur était rempli de bug? Pour ce qui est des collisions, je prévoie évidemment de faire mon editeur en fonction de ces dernieres, de plus pour ta Supermap V2, il me faudrais simplement un model de cette version (dont je présume qui est dans ta source actuelle).

signaler à un administrateur
Commentaire de gwen49 le 19/07/2006 01:05:55

bien joué je vois que tu as bien avancé depuis les début avec le zelda ;). vraiment bravo

signaler à un administrateur
Commentaire de ciberrique le 19/07/2006 02:20:19

Merci beaucoup, meme si maintenant je ne travaille presque plus que sur la 3d, meme si j'ai toujours un tuto en cour mais j'ai pas le temps de le finir.
Merci.

signaler à un administrateur
Commentaire de Tearjeacker le 04/12/2006 21:27:18

Au risque de me faire caillasser j'arive vraiment pas a ouvrir/complier quoi que ce soit C'est vrais que le code est vraiment intéressant mais mois je nage dans...

signaler à un administrateur
Commentaire de ciberrique le 04/12/2006 21:49:48

*le caillasse*

Combien de fois faudra t il encore le dire ! Un message d'erreur s'il vous plait, sinon on ne repondra pas !

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Découper des tiles avec DirectX? [ par Antitrust ] Bonjour,Je voudrais, avec VB & DirectX, je ne sais pas ce dont je vais avoir besoin, utiliser qu'une partie d'une grande image (en comportant de nombr Gérer les colision d'un perso avec DirectX [ par Charles Racaud ] SalutG commencé à faire un jeu style 'Mario'Pour cela, G utiliser DirectX.G réussi à faire bouger le jeu mais je ne parviens pas à gérer les collision Directx Strategie [ par bilaloch ] Svpje voudrais demander si pour faire un jeu type warcraft3 il fallait utiliser directdraw pour les menus,barre du jeu, etc... et direct3D pour le jeu aide jeu sans directx [ par sammy918 ] bonsoir, premi&#232;rement, comment on fait pour quand tu appui sur la fl&#232;che gauche tel image ce d&#233;place vers la gauche, pour fl&#232;che d DX 7 8 9 ??? [ par Stephane ] Salut a tous voila, il y a quelques temps j'avais fait quelques jeux en DirectX7 qui utilisait DirectDraw Aujourd'hui, je me lance dans un nouveau j DirectDraw DirectX [ par CiscoFun ] Bonjour,Voila je débute dans la programmation graphique et j'aimerais que quelqu'un me donne l'adresse d'un site (j'en ai deja testé plusieur mais rie vb6 - directX, directDraw, openGL,... [ par mstarsup5 ] Bonjour,Je souhaiterais commencer à écrire des programmes en utilsant directX pour pouvoir faire des jeux plus rapides, mais j'aurais quelques questio VB 2005 ou C/C++ ? [ par Kite37 ] Bonjour !Souhaitant avec des amis nous lancer dans un projet de jeu assez conséquent, nécessitant l'utilisation de DirectX 9.0, nous sommes confrontés Directdraw couleur transparente [ par dester ] Bon j'ai comme un bleme.Voila je me suis dis : "hopla je me met a developper en directX"Et tout a coup ont surgis quelque problemes (loleu)Alors prem Créer son premier jeu avec DirectX 9 et Visual Basic 2008 Express [ par Diable11 ] Bonjour,Quelqu'un peut m'aider à créer mon propre premier jeu avec DirectX 9 et Visual Basic 2008 Express ?Je ne sais pas comment on utilise les DLL d


Nos sponsors

Sondage...

CalendriCode

Janvier 2009
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

Consulter la suite du CalendriCode