Bonjour tout le monde.
Je souhaite développer un moteur simple en raycasting pour jouer dans un navigateur (canvas/javascript). J'ai suivie l'excellent tuto que beaucoup connaissent qui est :

http://www.permadi.com/tutorial/raycast/

Mais voilà, je bloque et cela fait une semaine que je cherche la solution mais en vain. Mon moteur calcul affiche des murs qui n'existent pas, et je n'arrive pas à comprendre pourquoi et d'où cela vient. Normalement il doit juste m'afficher une salle vide. Si quelqu'un parmi vous a déjà réalisé un moteur comme cela et peut me dire où je me suis tromper je lui en serais très reconnaissant.

Le code de ma map :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
var mapX = 6;
var mapY = 4;
 
var map = [[1,1,1,1,1,1,1],
	[1,0,0,0,0,0,1],
	[1,0,0,0,0,0,1],
	[1,0,0,0,0,0,1],
	[1,1,1,1,1,1,1]];
Le code de mon html :
Code html : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
    <head>
        <title>Moteur Raycasting</title>
        <script src="map.js"></script>
        <script src="engine.js"></script>
    </head>
    <body>
        <canvas id="mon_canvas" width="800" height="600">
            Message pour les navigateurs ne supportant pas encore canvas.
        </canvas>
 
    </body>
</html>

Et enfin le code de mon moteur :
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
//*********************************************************
//**********Initialisation de la fenetre de rendu**********
//*********************************************************
window.onload = function()
{
    var canvas = document.getElementById("mon_canvas");
        if(!canvas)
        {
            alert('Impossible de récupérer le canvas');
            return;
        }
 
    var context = canvas.getContext("2d");
        if(!context)
        {
            alert('Impossible de récupérer le context du canvas');
            return;
        }
 
	context.fillStyle="black";
	context.fillRect(0,0,resWidth,resHeight); // Dessin du fonc Noir
 
 
 
//*********************************************
//**********Variable global du moteur**********
//*********************************************
	// Taille de la fenêtre de rendu.
	var resWidth=800;
	var resHeight=600;
 
	// Position du joueur et vitesse.
	var posX=115;
	var posY=120;
	var speed=2;
	// Angles du joueur.
	var fov=60; // champ de vision du joueur
	var camAngle=20; // Angle de vision du joueur
 
	// Taille arbitraire des murs en pixels (Longueur=Largeur=Hauteur).
	var bloc=64;
 
	// Troncature du nombre Pi pour gagner du temps de calcul
	var pi= 3.141;
 
	// Variables de test d'intersection
		// Les points d'intersections Horizontal et Vertical
			var pointYY;
			var pointYX;
			var pointXY;
			var pointXX;
 
		// Les distances qui sépare le points suivant en Horizontal et Vertical
			var YYdist;
			var YXdist;
			var XYdist;
			var XXdist;
 
		// Coordonné des points dans la matrice
			var gridYY;
			var gridYX;
			var gridXY;
			var gridXX;
 
	// Variables d'information sur le mur à dessiner
	var p1=0; // Distance mur Horizontal rencontré
	var p2=0; // Distance mur Vertical rencontré
	var rayAngle; // Angle des rayons envoyés
	var distWall; // Distance du mur le plus proche du joueur
	var anglePas=fov/resWidth;
	var heightWall; // Hauteur de ce mur à dessiner
	var distCam=Math.floor((resWidth/2)/Math.tan((pi*(fov/2))/180)); // Distance Joueur/Ecran de projection(canvas)
	var maxValue=99999;
//****************************************************************
//****************************************************************
 
 
 
//***********************************************************
//********************Boucle du moteur***********************
//***********************************************************
function engine()
{
	// 4 étapes du moteur de rendu:
		// Test intersection Horizontal
		// Test intersection Vertical
		// Calcul de la distance du mu
		// Dessiner le mur
 
	// Raffraichie le canvas entre chaque image.
	context.clearRect(0, 0, canvas.width, canvas.height);
 
	// Le nombre de rayons à lancer est egal à la variable resWidth.
	for (var i=0; i<resWidth; i++)
	{
 
	// On initialise les différents variable de test entre chaque lancé de rayon
	pointYY=0;
	pointYX=0;
	pointXY=0;
	pointXX=0;
	YYdist=0;
	YXdist=0;
	XYdist=0;
	XXdist=0;
 
	// On balaye les rayons de gauche à droite.
	// La formule (fov/800) correspond à la valeur à ajouter à chaque fois pour
	// obtenir l'angle du rayon suivant.
	rayAngle= (camAngle+(fov/2)) - ((fov/resWidth)*i);
 
	if (rayAngle < 0)
	{
		rayAngle = rayAngle + 360;
	}
	else if (rayAngle > 360)
	{
		rayAngle = rayAngle - 360;
	}
	rayAngle=rayAngle.toFixed(2);
 
	//*****************************************************
	//************Test Intersection Horizontal*************
	//*****************************************************
 
		// Si le rayon va en bas (angle entre 0° et 179°)
		if (rayAngle>0 && rayAngle<180)
		{
			pointYY=(posY/bloc)*(bloc) + bloc; // Coordonnée en Y du premier point d'intersection
			YYdist=bloc; // Calcul de la distance en Y entre deux points sur l'axe Horizontal (taille d'un bloc)
		}
		else // Si le rayon va en bas
		//(angle entre 180 et 359)
		{
			pointYY=(posY/bloc)*(bloc) -1; // Coordonnée en Y du premier point d'intersection
			YYdist=-bloc; // Calcul de la distance en Y entre deux points sur l'axe Horizontal (taille d'un bloc)
		}
 
		// Calcul de la position en X du point d'intersection Horizontal (qu'importe si le rayon va vers le haut ou le bas)
		pointYX=posX + ((posY-pointYY)/Math.tan((pi * rayAngle)/180));
 
		// Calcul de la distance en X entre deux points sur l'axe Horizontal (toujours le même pour un même rayon)
		YXdist=YYdist/Math.tan((pi * rayAngle) / 180);
 
 
		gridYY=Math.floor(pointYY/bloc);
		gridYX=Math.floor(pointYX/bloc);
 
			while(map[gridYY] && map[gridYY][gridYX] == 0)
			{
				pointYY+=YYdist;
				pointYX+=YXdist;
 
				gridYY=Math.floor(pointYY/bloc);
				gridYX=Math.floor(pointYX/bloc);
			}
 
 
 
	//*****************************************************
	//*************Test Intersection Vertical**************
	//*****************************************************
 
		// Si le rayon va vers la droite (angle 0° à 89°  et  270° à 359°)
		if ((rayAngle<90) || (rayAngle>270 ))
		{
			pointXX=Math.floor(posX/bloc) * (bloc) + bloc; // Coordonnée en X du premier point d'intersection
			XXdist=bloc; // Calcul de la distance en X entre deux points sur l'axe Vertical (taille d'un bloc)
		}
		else // Si le rayon va vers la gauche (angle 90° à 269°)
		{
			pointXX=Math.floor(posX/bloc) * (bloc) -1;
			XXdist=-bloc; // Calcul de la distance en X entre deux points sur l'axe Vertical (taille d'un bloc)
		}
 
		// Calcul de la position en Y du point d'intersection Vertical (qu'importe si le rayon va vers la gauche ou la droite)
		pointXY=posY + (posX-pointXX) * Math.tan((pi*rayAngle)/180);
 
		// Calcul de la distance en Y entre deux points sur l'axe Vertical (toujours le même pour un même rayon)
		XYdist=XXdist*Math.tan((pi*rayAngle)/180);
 
		gridXY=Math.floor(pointXY/bloc);
		gridXX=Math.floor(pointXX/bloc);
 
		while(map[gridXY] && map[gridXY][gridXX] == 0)
		{
 
			pointXY+=XYdist;
			pointXX+=XXdist;
 
			gridXY=Math.floor(pointXY/bloc);
			gridXX=Math.floor(pointXX/bloc);
 
		}
 
 
	//*****************************************************
	//***************Calcul Distance du mur****************
	//*****************************************************
		// On utilise pythagore pour connaitre la distance des deux murs trouver en Horizontal et Vertical
		p1=Math.sqrt(Math.pow((posX-pointYX),2) + Math.pow((posY-pointYY),2));
		p2=Math.sqrt(Math.pow((posX-pointXX),2) + Math.pow((posY-pointXY),2));
 
		// On determine le mur le plus proche du joueur pour le dessiner
		if (p1<p2)
		{
			context.fillStyle='rgb(150,150,255)';
			distWall=p1;
		}
		else
		{
			context.fillStyle='rgb(255,150,150)';
			distWall=p2;
		}
 
	//*****************************************************
	//*******************Dessiner le mur*******************
	//*****************************************************
 
		// On calcul la hauteur du mur selon sa distance par rapport au joueur
		// Et la distance entre le joueur et le mur de projection(canvas)
		heightWall=Math.floor((bloc/distWall)*distCam);
 
		// Fonction pour dessiner le trait du mur
 
		context.fillRect(i,((resHeight/2)-(heightWall/2)),1,heightWall);
	}// Fin de la boucle des rayons
 
 
	//***********************************
	//**********Affichage Admin**********
	//***********************************
    context.font = "20pt Calibri,Geneva,Arial";
    context.strokeStyle = "rgb(0,0,0)";
    context.fillStyle = "rgb(0,20,180)";
    context.fillText("posX:=" + posX, 10, 60);
    context.fillText("posY:=" + posY, 10, 80);
    context.fillText("camAngle:=" + camAngle, 10, 100);
 
}// Fin fonction engine
//***************************************************************************
//***************************************************************************
 
 
 
//************************************
//**********Boucle Principal**********
//************************************
 
// Cette fonction créer le rafraichissement de l'image du joueur
// Elle appelle 30 fois par seconde la fonction engine
// Donc en une seconde, on dessine 30 fois la vision du joueur
var myInterval = setInterval(engine, 1000/30);
 
document.addEventListener('keydown', function(event) {
    if(event.keyCode == 38) { // Touche Haut du clavier
        posX = posX + ((Math.cos((pi*camAngle)/180)) * speed);
        posY = posY + ((Math.sin((pi*camAngle)/180)) * speed);
    }
    if(event.keyCode == 40) { // Touche Bas du clavier
        posX = posX - ((Math.cos((pi*camAngle)/180)) * speed);
        posY = posY - ((Math.sin((pi*camAngle)/180)) * speed);       
    }
    if(event.keyCode == 37) { // Touche Gauche du clavier
    	camAngle=camAngle+10;
    	if (camAngle > 360)
    	{
    		camAngle = camAngle - 360;
    	}
    }
    if(event.keyCode == 39) { // Touche Droit du clavier
    	camAngle=camAngle-10;
    	if (camAngle < 0)
    	{
    		camAngle = camAngle + 360;
    	}
    }
});
 
}; // Fin du programme (windows.onload)
Merci d'avance =).