salut

En ce moment, j'apprends le purebasic, et j'aimerai réaliser un jeu en 2Diso.
Jusqu'à maintenant, tout se passe plutôt bien, mais je rencontre un problème pour faire le tri de mes sprites suivant y.
Par exemple, lorsque le personnage passe devant un arbre, il doit être affiché devant et non derrière .

Voici donc un essai de code pour du Z-order (ou depth) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
 
;{ **************** variable, constantes.****************** ..
Enumeration
  #arbre
  #perso
  #WINDOW_MAIN
EndEnumeration
 
ecranX = 1024
ecranY = 768
Global FPS_LIMIT = 120
Global quit = 0
 
Global scroll_x = 0
Global scroll_y = 0
 
Global room_width = 4000
Global room_height  = 3000
;}
 
;{ **************** Structures **************************** 
 
Structure objet
    x.l
    y.l
    newposition_x.l
    newposition_y.l
    centre_x.l
    centre_y.l
  EndStructure
 
  Global nombre_arbre = 500
 
  Global Dim tableau_obj.objet(nombre_arbre)
 
For i = 2 To nombre_arbre
  tableau_obj(i)\y = Random(room_height)
  tableau_obj(i)\x = Random(room_width )
  tableau_obj(i)\centre_y = 80
  tableau_obj(i)\centre_y = 180
  tableau_obj(i)\newposition_x = tableau_obj(i)\x - tableau_obj(i)\centre_x
  tableau_obj(i)\newposition_y = tableau_obj(i)\y - tableau_obj(i)\centre_y
Next i
 
tableau_obj(1)\centre_x = 17
tableau_obj(1)\centre_y = 80
tableau_obj(1)\x = ecranX/2
tableau_obj(1)\y = ecranY/2
 
tableau_obj(1)\newposition_x = tableau_obj(1)\x - tableau_obj(1)\centre_x
tableau_obj(1)\newposition_y = tableau_obj(1)\y - tableau_obj(1)\centre_y
 
;SortStructuredArray(tableau_obj(), #PB_Sort_Ascending, OffsetOf(objet\y), #PB_Sort_Long)
 
;}
 
Declare evenement()
Declare update()
 
;{ **************** initialisation ************************** 
 
InitSprite()
InitSprite3D()
InitKeyboard()
InitMouse()
UsePNGImageDecoder()
 
;}
 
 
;{ ********************** openWindow ************************ 
 
OpenWindow(#WINDOW_MAIN,150,150,EcranX,EcranY,"3 Arks - test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
OpenWindowedScreen(WindowID(#WINDOW_MAIN),0,0,EcranX,EcranY,0,0,0,#PB_Screen_WaitSynchronization ) 
;ClearScreen(RGB(128,128,128))
 
;}
 
;{ loading (sprites)
 
LoadSprite(#perso, "perso.png",#PB_Sprite_AlphaBlending|#PB_Sprite_Texture )
CreateSprite3D(#perso,#perso)
 
LoadSprite(#arbre, "arbre.png",#PB_Sprite_AlphaBlending|#PB_Sprite_Texture )
CreateSprite3D(#arbre,#arbre)
 
;}
Debug tableau_obj(1)\y
 
Repeat
 
Event.l = WindowEvent()
 evenement()
If (ElapsedMilliseconds() > CheckTime + 1000 / FPS_LIMIT)
            CheckTime = ElapsedMilliseconds()
            FlipBuffers()
            ClearScreen(RGB(128,128,128))
 
            update()                     
 
            Else
            Delay(1)
EndIf
 
 
 
Until Event = #PB_Event_CloseWindow Or quit = 1
 
 
;   
;   For k=0 To 50
 
;   Next
 
 
Procedure evenement()
  If ExamineKeyboard()
 
    If KeyboardPushed(#PB_Key_Up) ;And scroll_y >0
               scroll_y - 1
              EndIf
    If KeyboardPushed(#PB_Key_Right) ;And scroll_x < room_width 
              scroll_x + 1
              EndIf
    If KeyboardPushed(#PB_Key_Down) ;And scroll_y < room_height 
              scroll_y + 1
              EndIf
    If KeyboardPushed(#PB_Key_Left) ;And scroll_x >0
              scroll_x - 1
            EndIf
 
    If KeyboardPushed(#PB_Key_Escape)
              quit = 1
            EndIf
 
EndIf
 
 
 
EndProcedure
 
 
Procedure update()
 
  Start3D() 
 
  DisplaySprite3D(#perso, tableau_obj(1)\newposition_x,tableau_obj(1)\newposition_y)
 
  For i=2 To  nombre_arbre
    DisplaySprite3D(#arbre, tableau_obj(i)\newposition_x - scroll_x,tableau_obj(i)\newposition_y - scroll_y)
    ;DrawText(tableau_obj(i)\newposition_x - scroll_x,tableau_obj(i)\newposition_y- scroll_y,"")
  Next i
 
 Stop3D()
 
EndProcedure
savez-vous comment je peux réussir à faire un tri pour l'affichage de mes arbres et du personnage ?

Car si je laisse
Code : Sélectionner tout - Visualiser dans une fenêtre à part
SortStructuredArray(tableau_obj(), #PB_Sort_Ascending, OffsetOf(objet\y), #PB_Sort_Long)
le tri s'effectue, mais cela change les éléments du tableau (on le remarque avec le debuguer, car le y du personnage n'est plus égal à ecranX/2 (soit 512);

Et si j'enlève ce code, l'affichage des éléments est correct (leur emplacement défini après la structure), mais le Z-order n'est plus correct.

Théoriquement, j'ai trouvé la solution, mais je ne parviens pas à la mettre en pratique :
- je pense que je dois utiliser 2 tableaux (ou listes) : le premier tableau est le tableau que j'ai déjà, avec les objets et leur y.
- un 2ème tableau qui est classé en fonction du Y (ascendant) chaque élément du 1 er tableau.
Cela me fait penser aux pointeurs, mais je ne sais pas comment m'y prendre pour résoudre ce problème .

Cela dit, après, il faudrait que j'affiche les sprites dans l'ordre ascendant de leur y, et donc, j'aurai toujours un problème.

Donc, si quelqu'un sait comment je peux faire ce Z-order (ou depth, ou encore tri), n'hésitez pas à m'en informer .

Merci d'avance.

les images utilisées sont là :
http://blendman.free.fr/dev/pb/arbre.png
http://blendman.free.fr/dev/pb/perso.png