Bonjour à tous !
Je tente actuellement de créer un mini jeu vidéo en 3d à l'aide de la librairie ogre3d.
Ce jeu est un minecraft-like, cela implique donc que le terrain est constitué de blocs.
Mais, je peine actuellement sur l'algorithme d'affichage des blocs.
En effet, j'enregistre actuellement le terrain dans des tableaux en 3 dimensions et, le terrain est divisé en 9 partie(chunk) contenant chacun un tableau de string de 10*32*10 (x,y,z) blocs. 32 étant la hauteur maximale du terrain pour le moment.
Mon algorithme considère que un bloc n'est pas visible si au dessus, en dessous, à droite, à gauche, devant et derrière lui il y a un bloc.
C'est extrêmement facile de faire une vérification à l'intérieur de chaque chunk mais, lorsque je me trouve sur les bords d'un des chunk il faut que je trouve celui à coté pour vérifier si le bloc à coté de celui-ci est vide ou non.
J'ai donc un terrain constitué de cette façon :
0 0 0
0 0 0
0 0 0
Et pour éviter que des blocks s'affiche inutilement sur les bords du terrain en dessous des blocs visible, j'ai virtuellement entouré le terrain avec des chunks plein de cette façon :
v v v
v 0 0 0 v
v 0 0 0 v
v 0 0 0 v
v v v
Avec chaque chunk contenant un tableau de pointeurs vers les quatre chunk l'entourant.
Mon problème survient lorsque je tente d'accéder pour la première fois à ce chunk virtuel.
En débogage, j'obtiens l'erreur suivante :
received signal sigsegv segmentation fault
L'erreur survient lorsque a = 6079 ou 6080.
À ce moment j'appel une méthode de la classe chunk pour tester ce qui ne vas pas.
Toujours du côté débogage, l'érreur survient sur la méthode checkX(x=10, y=0, z=0) avec comme local variable : ch = 0x5.
J'espère avoir bien expliqué...
Voici le code :
Main.cpp :
planet.cpp :Code:
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 #include <iostream> #include <vector> #include "planet.h" #include "./chunk.h" using namespace std; int main() { int a =0; planet *terrain = new planet(); std::vector <Chunk *> chunks = terrain->getChunk(); for(int v = 0; v < chunks.size(); v++){ for(int i = 0; i < CHWIDTH; i++){ for(int j = 0; j < CHHEIGHT; j++){ for(int k = 0; k < CHWIDTH; k++){ if(a >= 6079 && a < 6080){ if(chunks[v]->isVisible(i,j,k,1)){ cout << a << endl; a++; } }else{ if(chunks[v]->isVisible(i,j,k)){ a++; } } } } } } return 0; } </code> planet.h : <code type="cpp"> #ifndef PLANETE_H #define PLANETE_H #include <string> #include <vector> class Chunk; class planet { public: planet(); virtual ~planet(); std::vector <Chunk *> getChunk(); private: int m_seed; std::string m_path; std::vector <Chunk *> m_Chunks; }; #endif // PLANETE_H
Chunk.h :Code:
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 #include <iostream> #include <string> #include "./ChunkGenerator.h" #include "./Chunk.h" #include "./planet.h" planet::planet() { for(int x = 0;x<3;x++) { for(int z = 0; z < 3; z++) { Chunk *ch = new Chunk(); ch->setX(x); ch->setZ(z); m_Chunks.push_back(ch); } } //see m_ChunkList doc Chunk *ch = new Chunk(0,0); for(int x = 0;x<3;x++) { for(int z = 0; z < 3; z++) { if(x+1 < 3){ m_Chunks[x+z]->m_ChunkList.push_back(m_Chunks[x+3+z]); }else{ m_Chunks[x+z]->m_ChunkList.push_back(ch); } if(z-1 >= 0){ m_Chunks[x+z]->m_ChunkList.push_back(m_Chunks[x+z-1]); }else{ m_Chunks[x+z]->m_ChunkList.push_back(ch); } if(x-1 >= 0){ m_Chunks[x+z]->m_ChunkList.push_back(m_Chunks[x-3+z]); }else{ m_Chunks[x+z]->m_ChunkList.push_back(ch); } if(z+1 < 3){ m_Chunks[x+z]->m_ChunkList.push_back(m_Chunks[x+z+1]); }else{ m_Chunks[x+z]->m_ChunkList.push_back(ch); } } } } std::vector <Chunk *> planet::getChunk() { return m_Chunks; } planet::~planet() { //dtor }
Chunk.cpp :Code:
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 #ifndef CHUNK_H #define CHUNK_H #include <string> #include <vector> #define CHWIDTH 10 #define CHHEIGHT 32 class planet; class Chunk { public: Chunk(); Chunk(int x, int z); virtual ~Chunk(); bool isVisible(int x, int y, int z); bool isVisible(int x, int y, int z, int a); void setBlockAt(std::string block, int x, int y, int z); int getX() {return m_x;} void setX(int val) {m_x = val;} int getZ() {return m_z;} void setZ(int val) {m_z = val;} std::string m_map[CHWIDTH][CHHEIGHT][CHWIDTH]; std::vector <Chunk* > m_ChunkList;//Chunks around //0 to 3 in circular order start at x+1 protected: private: int m_x; int m_z; std::string m_index; bool checkX(int x, int y, int z); bool checkY(int x, int y, int z); bool checkZ(int x, int y, int z); Chunk* getChunkAt(std::string index); bool freeAt(int x, int y, int z, Chunk* ch); }; #endif // CHUNK_H
PS : dans la méthode isVisible(4 arguments) le code plante pour la fonction getX(). De plus cette méthode est juste pour les tests !Code:
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 #include "./Chunk.h" #include <iostream> #include <fstream> #include "./planet.h" Chunk::Chunk(){ for(int x = 0; x < CHWIDTH; x++){ for(int y = 0; y < CHHEIGHT; y++){ for(int z = 0; z < CHWIDTH; z++){ m_map[x][y][z] = "a"; } } } } Chunk::Chunk(int x, int z) { m_x = x; m_z = z; for(int x = 0; x < CHWIDTH; x++){ for(int y = 0; y < CHHEIGHT; y++){ for(int z = 0; z < CHWIDTH; z++){ m_map[x][y][z] = "a"; } } } } Chunk::~Chunk() { for(int i = 0; i < 4; i++){ delete m_ChunkList[i]; } } bool Chunk::isVisible(int x, int y, int z){ if(m_map[x][y][z].compare("") == 0){ return false; } if(checkX(x+1, y, z) || checkX(x-1, y, z) || checkY(x, y+1, z) || checkY(x, y-1, z) || checkZ(x, y, z+1) || checkZ(x, y, z-1)){ return true; }else{return false;} } bool Chunk::isVisible(int x, int y, int z, int a){ if(m_map[x][y][z].compare("") == 0){ return false; } Chunk* ch = m_ChunkList[2]; std::cout << ch->getX() << std::endl; if(ch->m_map[0][y][z].compare("") == 0){ std::cout << "0" << std::endl; } std::cout << "1" << std::endl; } bool Chunk::checkX(int x, int y, int z){ if(x >= CHWIDTH){ Chunk* ch = m_ChunkList[0]; if(freeAt(0, y, z, ch)){return false;} else{return true;} }else if(x < 0){ Chunk* ch = getChunkAt(std::string("x-1")); if(freeAt(CHWIDTH-1, y, z, ch)){return false;} else{return true;} }else{ if(freeAt(x, y, z, this)){return false;} else{return true;} } } bool Chunk::checkZ(int x, int y, int z){ if(z >= CHWIDTH){ Chunk* ch = getChunkAt(std::string("z+1")); if(freeAt(x, y, 0, ch)){return false;} else{return true;} }else if(x < 0){ Chunk* ch = getChunkAt(std::string("z-1")); if(freeAt(x, y, CHWIDTH-1, ch)){return false;} else{return true;} }else{ if(freeAt(x, y, z, this)){return false;} else{return true;} } } bool Chunk::checkY(int x, int y, int z){ if(y >= CHHEIGHT){ return true; }else if(y < 0){ return false; }else{ if(freeAt(x, y, z, this)){return false;} else{return true;} } } Chunk* Chunk::getChunkAt(std::string index){ if(index.compare("x+1")){ return m_ChunkList[0]; } else if(index.compare("x-1")){ return m_ChunkList[2]; } else if(index.compare("z+1")){ return m_ChunkList[1]; } else if(index.compare("z-1")){ return m_ChunkList[3]; } } void Chunk::setBlockAt(std::string block, int x, int y, int z) { m_map[x][y][z] = block; } bool Chunk::freeAt(int x, int y, int z, Chunk* ch){ if((ch->m_map[x][y][z]).compare("") == 0){ return true; } return false; }
J'espère que vous comprendrez mon code malgré le manque de commentaires.
Si vous avez des question n'hésitez pas !
Merci d'avance pour votre aide !