Introduction
Ce billet fait suite au billet: http://blog.developpez.com/ducodeetdulibre/p12406/developpement/journal-de-bord-creation-dun-rts-en-html5-jour-3
Dans ce billet je vais vous détailler le fichier rts_Map.js, son utilisation, sa construction.
Faire une application HTML5/canvas: construire la Map
Dans ce jeux de stratégie, comme dans beaucoup d’autres jeux, la carte est trop grande pour être affichée dans son ensemble,.
Il faut donc afficher une partie de la carte, et permettre de visualiser ce que l’on regarde par rapport à la carte complète.
C’est là qu’intervient la classe Map (fichier rts_Map.js)
Comme pour la classe Game, nous allons ici voir bloc par bloc
Création de la map
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 | build:function(){ for(var y=0;y< maxY;y++){ for(var x=0;x< maxX;x++){ //decalage x/y en fonction du scrolling var x2=x+currentX; var y2=y+currentY; if(this.tMap[y2] && this.tMap[y2][x2]){ //si c'est un arbre if(this.tMap[y2][x2]==4){ //on dessine un case normale this.drawImage( 3 ,x,y); //puis on créé un objet arbre par dessus var oWood=new Wood(); oWood.x=x; oWood.y=y; oWood.build(); //on ajoute cette arbre au tableau des batiments //pour les reconstruire lors du scrolling oGame.tBuild.push(oWood); } //on dessine sur le canvas la valeur du tableau this.drawImage( this.tMap[y2][x2] ,x,y); } } } }, //la methode pour dessiner sur le canvas drawImage:function(iImg,x,y){ if(!this.tOImg[iImg]){ var oImg=new Image(); oImg.src='img3/'+this.tImg[iImg]; oImg._x=x; oImg._y=y; oImg.onload=function(){ oLayer_map.drawImage(this,this._x*widthCase,this._y*heightCase,widthCase,widthCase); } this.tOImg[iImg]=oImg; }else{ oLayer_map.drawImage(this.tOImg[iImg],x*widthCase,y*heightCase,widthCase,widthCase); } }, |
Petite parenthèse sur les images
Pensez bien que lorsque vous souhaitez dessiner une image sur un canvas, vous n’etes pas en local: les images de votre jeu ne sont pas chargées.
Pour gerer ce mode asynchrone: on créé un objet image, on lui assigne des propriétés comme ces coordonnées et enfin on lui indique du code à éxécuter au moment du chargement avec « onload »
Mais il faut également prévoir le fait que l’image ai déjà été chargée précédement.
C’est pour cela que je stoque ici l’objet image dans un tableau de propriété de la classe, ainsi, si l’objet existe on le dessine tout de suite.
En revanche si il n’existe pas on instancie avec les propriétés ainsi que la méthode onload.
Méthode de reconstruction
A chaque scroll, il faut redessiner la map: on se déplace sur la carte, mais il ne faut pas instancier de nouveaux objets arbres
C’est pour cela qu’il y a une méthode rebuild
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | rebuild:function(){ for(var y=0;y< maxY;y++){ for(var x=0;x< maxX;x++){ var x2=x+currentX; var y2=y+currentY; if(this.tMap[y2] && this.tMap[y2][x2]){ if(this.tMap[y2][x2]==4){ this.drawImage( 3 ,x,y); } this.drawImage( this.tMap[y2][x2] ,x,y); } } } }, |
La construction de l’aperçu
Il faut également afficher l’aperçu de la carte.
La methode buildApercu permet cela, cette méthode ressemble beaucoup à la méthode build
Les différences sont: on dessine les cases beaucoup plus petites, on dessine sur un calque supérieur un cadre indiquant ce que l’on voit en détail.
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 | //construction de l'apercu buildApercu:function(){ var maxMiniY=this.tMap.length; var maxMiniX=this.tMap[0].length; for(var y=0;y< maxMiniY;y++){ for(var x=0;x< maxMiniX;x++){ var x2=x; var y2=y; if(this.tMap[y2] && this.tMap[y2][x2]){ if(this.tMap[y2][x2]==4){ this.drawMiniImage( 3 ,x,y); } this.drawMiniImage( this.tMap[y2][x2] ,x,y); } } } oLayer_apercuBrouillard.fillRect(0,0,400,400,'#000000'); }, drawMiniImage:function(iImg,x,y){ oLayer_apercu.drawImage(this.tOImg[iImg],x*this.miniWidth,y*this.miniWidth,this.miniWidth,this.miniWidth); }, //dessin du cadre indiquant la partie affichée en détail buildApercuCadre:function(){ oLayer_apercuCadre.clear(); oLayer_apercuCadre.drawRectStroke(currentX*this.miniWidth,currentY*this.miniWidth,this.miniWidth*maxX,this.miniWidth*maxY,'#ff0000',2); }, |