Collision directx, tuto tiles 5

Soyez le premier à donner votre avis sur cette source.

Vue 8 102 fois - Téléchargée 1 107 fois

Description

Salut, pour ce tuto j'utilise les connaissances de tout mes anciens tuto, sachant que j'ai modifier le systeme d'affichage indirect des tiles car il y avait un bug. D'ailleur je vais mettre a jour le tuto. Le bug en question oublier le dernier Tile en longueur et en hauteur des map.

Pour la collision on utilise une matrice de deux caracteres. Ce qui donne 100 possibilités de collision, voiçi les principales.

Perso passe
Perso et bloqué
Ennemi
Objet
Teleportation

Il est possible d'utilisé un systeme de collision pour bloqué le personnage plus évolué :
perso bloqué à droite avec cache du perso (feuille d'arbre)
perso bloqué à gauche avec cache du perso (feuille d'arbre)
perso bloqué en haut avec cache du perso (feuille d'arbre)
perso bloqué en bas avec cache du perso (feuille d'arbre)
perso bloqué à droite sans cache le perso (feuille d'arbre)
perso bloqué à gauche sans cache le perso (feuille d'arbre)
perso bloqué en haut sans cache le perso (feuille d'arbre)
perso bloqué en bas sans cache le perso (feuille d'arbre)

Enfin si vous ne voyez pas comment faire pour cette méthode plus evolué à la fin du tuto laisser un com et je ferais un tuto supplementaire.

Ici j'utiliserai seulement passe ou ne passe pas
passe = 00
ne passe pas = 01

Source / Exemple :


Quelque variable en plus :

La matrice de collision
Public Collision() As Integer

Un type qui nous facilitera la gestion de la collision pour le deplacement du personnage
Public Type Collision
    gauche As Boolean
    droite As Boolean
    haut As Boolean
    bas As Boolean
End Type

Ensuite aprés le chargement de la map, on appelle cette fonction :

Sub LoadCol()
'Les variables utilisés
Dim TempString As String, i As Long, x As Long, y As Long
    
    'On ouvre le fichier de collision en mode lecture
    Open Path & "map.col" For Input As #1
        x = 0
        y = 0
        'On recupere tout le fichier
        Do While Not EOF(1)
            'Ligne par ligne dans une variable temporaire
            Line Input #1, TempString
            'Du caractere 1 au dernier caractere et de 2 caracteres en 2 caracteres si la matrice est grande vous pouvez utiliser une variable à la place de Len(TempString), par exemple : NbrCaracter = Len(TempString)
            For i = 1 To Len(TempString) Step 2
                'On affecte la valeur du caractere à la position choisi à la matrice, ici la matrice de collision est en integer donc si il y à 01 on aura que 1 dans la case du tableau.
                Collision(x, y) = Mid$(TempString, i, 2)
                'On passe à la colonne suivante
                x = x + 1
            Next
            'On passe à la ligne suivante
            y = y + 1
            x = 0
        Loop
    'O ferme le fichier
    Close #1
End Sub

Ensuite avant e blt du perso donc dans la boucle d'affichage, vous faite appelle à cette fonction :
vous pouvez aussi l'appeler dans la fonction du clavier qui deplace le perso.

ReDim Collision(UBound(Map,1),UBound(Map,2))

'Verification du passage si = True alors on peux passer
Public Function Check_Collision() As Collision
    Dim x As Long, y As Long
    
    'On prend la position en x en pixel on divise par 32 on arrondie sans chiffres après  la virgule.
    x = Round((PersoX / 32), 0)
    'De même pour y
    y = Round((PersoY / 32), 0)
    y = y + 1
    
    'Si la matrice de collision au tile (x-1,y) donc un tile a gauche du joueur est à 0 alors on peut passer
    If Collision(x - 1, y) = 0 Then
        Check_Collision.gauche = True
    End If
    'De meme pour le reste
    If Collision(x + 1, y) = 0 Then
        Check_Collision.droite = True
    End If
    If Collision(x, y - 1) = 0 Then
        Check_Collision.haut = True
    End If
    If Collision(x, y + 1) = 0 Then
        Check_Collision.bas = True
    End If
End Function

Enfin vous devez modifier la fonction qui donne la valeur de deplacement au perso :

On ne fait que rajouter la condition de collision

'Si on peut passser alors on donne la valeur à la variable de deplacement
If DIstate.Key(DIK_LEFT) And Check_Collision.gauche = True Then
    Perso_Deplacement = 1
ElseIf DIstate.Key(DIK_UP) And Check_Collision.haut = True Then
    Perso_Deplacement = 2
ElseIf DIstate.Key(DIK_DOWN) And Check_Collision.bas = True Then
    Perso_Deplacement = 3
ElseIf DIstate.Key(DIK_RIGHT) And Check_Collision.droite = True Then
    Perso_Deplacement = 4
Else
    Perso_Deplacement = 0
End If

Voila, pas plus compliquer que cela.

Conclusion :


Bon, je précise se code n'est valable que pour des carte qui sont pas plus grande que l'ecran, donc pas de map de taille infini, cependant je vous promet un tuto sur la collision avec les map de taille infinie dans les jours qui viennent.

Il n'y a pas de bug connu, seul la finnesse de la collision ou la précision de votre matrice permet un rendu elegant.

Les prochains tuto et sources :
- Tuto tile 6 : Collision map infini
- Editeur de map, avec generateur de .map et .col
- Tuto tile 7 : Collision améliorée
- Tuto tile 8 : Utilisation de supermap

Si il y a un tuto que vous ne voyez pas l'utilité dites le moi, que je ne le fasse pas.

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
589
Date d'inscription
lundi 25 août 2003
Statut
Membre
Dernière intervention
18 juillet 2010
1
Le tuto sur les supermap est prés, je commente et le poste, bonne lecture, le prochain sera sur le drag n drop...
Messages postés
626
Date d'inscription
samedi 28 septembre 2002
Statut
Membre
Dernière intervention
18 mai 2009
4
Pour Kazuya :

Non c'est pas forcement beaucoup plus long...

Private Declare Function IntersectRect Lib "user32" (lpDestRect As RECT, lpSrc1Rect As RECT, lpSrc2Rect As RECT) As Long

Public Function Zone_Collision(ByRef Zone1 As RECT, ByRef Zone2 As RECT) As Boolean
Dim tmpRECT As RECT
If IntersectRect(tmpRECT, Zone1, Zone2) <> 0 Then
Zone_Collision = True
Else
Zone_Collision = False
End If
End Function
Messages postés
589
Date d'inscription
lundi 25 août 2003
Statut
Membre
Dernière intervention
18 juillet 2010
1
Oui, ce code est connu sous le nom de perfect collision, mais dans le cas d'utilisation de tile je trouve qu'il n'est pas trop adapté... Aprés a vous de choisir...
Messages postés
306
Date d'inscription
vendredi 21 février 2003
Statut
Membre
Dernière intervention
15 février 2016

Lol, ils ont inventés une API pour gérer les collisions entre 2 RECT. C'est ridicule, le code prends une ligne, tiends, preuve sous tes yeux

Function Collision(Surface1 As RECT, Surface2 As RECT) As Boolean
If Surface1.Top <= Surface2.Bottom And Surface1.Bottom >= Surface2.Top And Surface1.Left <= Surface2.Right And Surface1.Right >= Surface2.Left Then Collision = True
End Function
Messages postés
626
Date d'inscription
samedi 28 septembre 2002
Statut
Membre
Dernière intervention
18 mai 2009
4
Oui c'est pas mal mais personnellement je prefere l'utilisation de l'API IntersectRect qui permet de savoir si deux zones (RECT) se touchent ou non.
Apres c'est une question de gout.
Afficher les 26 commentaires

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.