IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Raycasting en javascript


Sujet :

JavaScript

  1. #1
    Futur Membre du Club
    Inscrit en
    Septembre 2013
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Septembre 2013
    Messages : 12
    Points : 8
    Points
    8
    Par défaut Raycasting en javascript
    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 =).

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 079
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 079
    Points : 44 663
    Points
    44 663
    Par défaut
    Bonjour et bienvenue sur DVP,
    Mon moteur calcul affiche des murs qui n'existent pas (...) Normalement il doit juste m'afficher une salle vide.
    je dois admettre que je ne saisie pas ce que tu as comme problème.

  3. #3
    Futur Membre du Club
    Inscrit en
    Septembre 2013
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Septembre 2013
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    En fait, j'ai programmer le moteur. j'ai charger une map vide entourré de murs, et pourtant il m'affiche des murs qui n'existe pas. De mon point de vue j'ai l'impression qu'il trouve des murs à chaque intersection de la matrice. Je sais pas si c'est plus parlant comme je l'ai dis.

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 079
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 079
    Points : 44 663
    Points
    44 663
    Par défaut
    Je commence à entrevoir mais je pense qu'un dessin de ce que tu souhaites et de ce que tu obtiens serait un plus visuel.

  5. #5
    Futur Membre du Club
    Inscrit en
    Septembre 2013
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Septembre 2013
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Et bien ma map est censé être une pièce vide, donc normalement je ne devrai voir que les 4 murs de celle-ci. Hors mon moteur dessine des murs qui n'existent pas et je ne sais pas pourquoi.

    Par exemple ici j'ai un mur bleu en face qui est dessiner alors qu'il ne devrait pas :
    http://img19.imageshack.us/img19/9277/58x9.png

    La j'ai deux murs rose qui sont dessiner alors qu'ils n'existent pas :
    http://img30.imageshack.us/img30/3586/srk4.png

    Merci en tout cas de prêté attention à mon problème =)
    Images attachées Images attachées   

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 079
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 079
    Points : 44 663
    Points
    44 663
    Par défaut
    Je vois plutôt une scène qui déborde sur la droite et qui trace des détails qui effectivement n'appartient pas à celle ci.

    PS: pas regardé le code.

  7. #7
    Futur Membre du Club
    Inscrit en
    Septembre 2013
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Septembre 2013
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Je n'arrive pas à trouver pourquoi ça fait cela. J'ai verifier plusieurs fois mes algo et je ne trouve pas de problème. Et les boucles sont censé s’arrêter dès qu'ils trouvent un mur. Je ne vois pas pourquoi il me dessine des murs qui n'existent pas.

  8. #8
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 079
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 079
    Points : 44 663
    Points
    44 663
    Par défaut
    Peux être devrais tu regarder du coté de ce tuto pour javascript http://dev.opera.com/articles/view/c...-html-5-can-1/

  9. #9
    Futur Membre du Club
    Inscrit en
    Septembre 2013
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Septembre 2013
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Je vais essayé. Sur la plupart des tutoriaux que j'ai lu, ils se basent tous sur les recherches de Permadi et son tuto mais utilise un système de vecteur et non d'angle de vu dont j'ai du mal à comprendre le fonctionnement. De plus Permadi n'est pas cohérent entre le tuto qu'il a rédiger et le code source qu'il donne à la fin. Mais c'est pas grave je vais continuer à cherche en regardant le lien que tu ma donner merci =). Puis si je trouve la solution je la donnerai.

Discussions similaires

  1. Les meilleurs livres pour apprendre le JavaScript
    Par vermine dans le forum Livres
    Réponses: 23
    Dernier message: 10/06/2019, 18h58
  2. JavaScript<---->ActionScript
    Par crazypiou dans le forum Flash
    Réponses: 21
    Dernier message: 17/04/2009, 17h14
  3. Construire chemin sur bouton avec évt Javascript
    Par Ph. B. dans le forum XMLRAD
    Réponses: 4
    Dernier message: 27/05/2003, 10h26
  4. appel xmlservice via fonction javascript
    Par pram dans le forum XMLRAD
    Réponses: 2
    Dernier message: 06/05/2003, 14h24
  5. JavaScript de vérification de formulaire
    Par [DreaMs] dans le forum XMLRAD
    Réponses: 6
    Dernier message: 26/02/2003, 13h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo