Partage
  • Partager sur Facebook
  • Partager sur Twitter

Complexifié mon RPG (Javascript)

15 avril 2018 à 17:12:54

Bonjour,

Je suis en train de faire un jeu sur Javascript (fait à l'aide de ce tuto : https://openclassrooms.com/courses/creer-un-mini-rpg-en-javascript-avec-canvas/mise-en-place-des-bases ) et j'aimerai savoir si c'était possible de reproduire la même chose que ce jeu ici : https://www.youtube.com/watch?v=7iJ9Bj0E50E . En fait ce que j'essaye de reproduire c'est un personnage qui se déplace à l'aide de notre souris (première condition) et en dépassant "un chemin", le joueur se doit de recommencer la partie (deuxième condition). Le but est d'arrivé sur la ligne d'arriver pour gagner le jeu, sinon le jeu est perdu et recommencé. Tout cela sur Javascript. 

Voici un exemple en image pour ceux qui ne parviennent toujours pas à comprendre : https://image.noelshack.com/fichiers/2018/15/7/1523804882-exemple-du-jeu.png  l'image est tiré du même tutoriel : https://openclassrooms.com/courses/creer-un-mini-rpg-en-javascript-avec-canvas/les-personnages-1 .

D'ailleurs le code source est donné et fonctionnelle (CE N'EST PAS DIT MAIS IL NE FONCTIONNE PAS SUR MOZILLA FIREFOX) : https://github.com/Seb-C/sources-tuto-rpg-openclassrooms/tree/Partie2_persos . Pour ma part il est compris et manipulable au niveau des ressources (tilesets, sprites, map etc). Je ne sais juste pas comment ajouter de nouvelles conditions (comme celle que j'essaie de réaliser).

Donc, est-ce que c'est possible de faire cela ? Si oui, comment m'y prendre ? Merci ! 

EDIT : Voici le jeu original : http://www.playscarymazegame.net/play-scary-maze-game/ et son code source : view-source:http://www.playscarymazegame.net/maze1/index.html

-
Edité par Otakin 15 avril 2018 à 18:11:10

  • Partager sur Facebook
  • Partager sur Twitter
15 avril 2018 à 17:51:18

C'est possible (tu as l'exemple en vidéo), tu peux utiliser l'event mousemove (déplacement de la souris) pour récupérer la position de la sourie et déplacer ton personnage. Pour recommencer et déplacer ton personnage au point de départ tu peux jouer avec l'offset (je ne sais pas si il est possible de modifier directement la position de la souris, ça m'étonnerait).

let canvas = document.createElement('canvas'); // fenetre de dessin
let crayon = canvas.getContext('2d');
document.body.append(canvas);

let position_depart = { x: 50, y: 50 };
let offset_x = 0;
let offset_y = 0;
let perso = { x: position_depart.x, y: position_depart.y };
let stop = false; // true = arreter le jeu et quitter (définitif)
let game_over = true;
let id = 0;
let mouse_x = 0;
let mouse_y = 0;

canvas.onmousemove = (e) => {
   mouse_x = e.clientX;
   mouse_y = e.clientY;
};



function game_loop() {

    // game over = recommencer au début
    if (game_over) {
        offset_x = (position_depart.x - mouse_x);
        offset_y = (position_depart.y - mouse_y);
        game_over = false;
    }

    // effacer l'image precedente
    crayon.clearRect(0, 0, canvas.width, canvas.height);

    // mettre a jour la position du personnage 
    perso.x = mouse_x + offset_x;
    perso.y = mouse_y + offset_y;

    // dessiner le personnage, ici c'est juste un cercle rouge mais on peut mettre une image
    crayon.beginPath();
    crayon.fillStyle = 'red';
    crayon.arc(perso.x, perso.y, 20, 0, Math.PI * 360);
    crayon.fill();

    if (!stop) {
        id = requestAnimationFrame(game_loop);
    }
    else {
        cancelAnimationFrame(id);
        id = 0;
    }
}

canvas.onload = () => {
   id = requestAnimationFrame(game_loop);
}

Je n'ai pas testé le code mais ça te donne un apperçu de ce qu'il faut faire

  • Partager sur Facebook
  • Partager sur Twitter
21 avril 2018 à 7:50:51

Je n'y arrive pas.. lorsque je test mon code mon canvas disparaît, j'ai essayé plusieurs manip mais je dois oublier de faire quelque chose. Voici ce que j'ai essayé de faire en ce moment.

https://image.noelshack.com/fichiers/2018/16/6/1524289728-rpgsouris.png 

https://image.noelshack.com/fichiers/2018/16/6/1524289728-rpgsouris2.png

(position de la souris initial dans la deuxième image)

J'ai suivis les conseils de ce tutoriel : http://www.startyourdev.com/codes/code-position-curseur . Mon but c'est de récupérer l'objet personnage de mon jeu RPG afin qu'il suit les coordonnées de ma souris.

  • Partager sur Facebook
  • Partager sur Twitter
24 avril 2018 à 17:03:42

une des images est un lien mort. Si tu veux montrer du code utilise le bouton </> et sélectionne javascript.
  • Partager sur Facebook
  • Partager sur Twitter
24 mai 2018 à 7:37:26

Benevolar : Merci ! C'était cette image : https://image.noelshack.com/fichiers/2018/21/4/1527139885-bonnemap.png

Sinon en 1 mois je suis toujours bloqué. J'arrive à l'étape finale ou ma souris ne doit pas toucher les tiles d'herbes sinon elle retourne au point de départ.. 

J'ai voulu testé ton code Benevolar. Je n'espérais pas que ça marche du premier coup, mais je voulais voir comment cela réagirait avec ce que j'ai fais. Et le résultat c'est que la map est toujours intact par contre la souris réagit bizarrement, son animation n'est pas du tout fluide et au bout d'un moment le dessin de la souris disparaît.

Voici ton code mélangé avec ce que j'ai fait :

var position_depart = { x: 50, y: 50 };
var offset_x = 0;
var offset_y = 0;
var perso = { x: position_depart.x, y: position_depart.y };
var stop = false; // true = arreter le jeu et quitter (définitif)
var game_over = true;
var id = 0;
var mouse_x = 0;
var mouse_y = 0;


//Dessine le rond
function dessine() {
    
    canvas.onmousemove = (e) => {
    mouse_x = e.clientX;
    mouse_y = e.clientY;
    }
    
    // game over = recommencer au début
    if (game_over) {
        offset_x = (position_depart.x - mouse_x);
        offset_y = (position_depart.y - mouse_y);
        game_over = false;
    }
    
    // Clear
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    //dessin d'une partie de l'image en sélectionnant un "rectangle" source par ses coordonnées (x, y) 
    //et par sa taille 
    
    // mettre a jour la position du personnage
    perso.x = mouse_x + offset_x;
    perso.y = mouse_y + offset_y;
    
for (var x = 0; x < 15; x++) {
    for(var y = 0; y < 15; y++){
        if (x == 6){
            ts.dessinerTile(9, ctx, 32*x, 32*y);
        }
        else if (x == 7){
            ts.dessinerTile(10, ctx, 32*x, 32*y);
        }
        else if (x == 8){
            ts.dessinerTile(11, ctx, 32*x, 32*y);
        }
        else {
            ts.dessinerTile(2, ctx, 32*x, 32*y);
        }
    }
}
   
    
  // si mon curseur est dans le canvas
  // et que je dois accrocher la forme au curseur
  // alors je redessine ma forme
  // sinon je ne fait rien
  if(bInCanvas != false && bAccroche != false){ 
    // Draw Mob
    ctx.beginPath(); //On démarre un nouveau tracé.

    ctx.arc(posX, posY, rayon, 0, Math.PI*2); //On trace la courbe délimitant notre forme
    ctx.fill(); //On utilise la méthode fill(); si l'on veut une forme pleine
    ctx.closePath();
      
    if (!stop) {
        id = requestAnimationFrame(dessine);
    }
    else {
        cancelAnimationFrame(id);
        id = 0;  
      
  }//if
  }

  //Rejouer l'annimation dessine
  requestAnimationFrame(dessine);
  //il est possible d'optimiser 
  // en déclenchant requestAnimationFrame par  fctMouseenter
  //et stopée par fctMouseleave avec requestAnimationFrame().
  
}//fct

Est-ce qu'il y a un moyen d'expliquer ce phénomène et aussi de résoudre cela ? Pour arriver à ce que je veux faire ?

edit: pas d'erreur dans la console. J'ai aussi 2 autres js, un pour le chargement des tiles et un autre qui gère les fonctions de la souris (addEventListener) en plus de la création du context 2d.

La souris ne doit pas traverser les tiles (2eme du coup) de la map. 

Merci

-
Edité par Otakin 24 mai 2018 à 7:41:47

  • Partager sur Facebook
  • Partager sur Twitter
24 mai 2018 à 11:03:07

Je me permet de copier-coller le code mais avec l'indentation pour mieux voir.

// c'est mieux d'utiliser let et const plutôt que var
let position_depart = { x: 50, y: 50 };
let offset_x = 0;
let offset_y = 0;
let perso = position_depart; // c'est plus court écrit comme ça
let stop = false; // true = arreter le jeu et quitter (définitif)
let game_over = true;
let id = 0;
let mouse_x = 0;
let mouse_y = 0;

// pas besoin de mettre ça dans la fonction dessine
canvas.onmousemove = (e) => 
{ 
  mouse_x = e.clientX;
  mouse_y = e.clientY;
}
 
 
//Dessine le rond
function dessine() 
{
     
  // game over = recommencer au début
  if (game_over) 
  {
    offset_x = (position_depart.x - mouse_x);
    offset_y = (position_depart.y - mouse_y);
    game_over = false;
  }
     
  // Clear
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  //dessin d'une partie de l'image en sélectionnant un "rectangle" source par ses coordonnées (x, y)
  //et par sa taille
  
  // mettre a jour la position du personnage
  perso.x = mouse_x + offset_x;
  perso.y = mouse_y + offset_y;
     
  for (var x = 0; x < 15; x++) 
  {
    for(var y = 0; y < 15; y++) 
    {
      // le switch est mieux ici mais j'ai du mal à comprendre à quoi sert le 9, 10, 11
      // si c'est les différents tiles il vaut mieux faire : 
      // const herbe = 1;
      // const pierre = 2;
      // const eau = 3;
      // const sable = 4;
      // const terrain = [
      //   [3, 3, 2, 1, 1, 1, 2, 4, 2, 4],
      //   [3, 3, 2, 1, 1, 1, 2, 4, 2, 4],
      //   [3, 3, 2, 2, 1, 1, 3, 3, 2, 4],
      //   [3, 3, 2, 2, 1, 1, 3, 3, 2, 3],
      //   [3, 3, 2, 2, 1, 1, 2, 4, 3, 3]
      // ];
      // et
      // ts.dessinerTile(terrain[x][y], ctx, 32*x, 32*y); 
      switch(x) 
      {
        case 6 : ts.dessinerTile(9, ctx, 32*x, 32*y); 
          break;
        case 7 : ts.dessinerTile(10, ctx, 32*x, 32*y);
          break;
        case 8 : ts.dessinerTile(11, ctx, 32*x, 32*y);
          break;
        default : ts.dessinerTile(2, ctx, 32*x, 32*y);
          break;
      } // fin switch(x)
    } // for(var y = 0; y < 15; y++) 
  } // for (var x = 0; x < 15; x++) 
    
  // si mon curseur est dans le canvas
  // et que je dois accrocher la forme au curseur
  // alors je redessine ma forme
  // sinon je ne fait rien
  if(bInCanvas != false && bAccroche != false)
  {
    // Draw Mob
    ctx.beginPath(); //On démarre un nouveau tracé.
    ctx.arc(posX, posY, rayon, 0, Math.PI*2); //On trace la courbe délimitant notre forme
    ctx.fill(); //On utilise la méthode fill(); si l'on veut une forme pleine
    ctx.closePath();
    if (!stop) {
      id = requestAnimationFrame(dessine);
    }
    else {
      cancelAnimationFrame(id);
      id = 0; 
    }
  } // if(bInCanvas != false && bAccroche != false)
 
  // requestAnimationFrame(dessine); <= il faut supprimer cette ligne sinon on dessine 2 fois
  // requestAnimationFrame est très pratique car ça permet de limiter 
  // le nombre de dessin à 60 fps, si on utilisait une simple boucle infinie
  // on aurait 9999 images par secondes et ça ferait planter le navigateur
  // si on utilisait setInterval, on aurait 60 images par secondes mais 
  // sans tenir compte du temps de tracé donc suivant les cas on aurait un 
  // dessin moins fluide
  
   
}// function dessine() 

j'ai modifié légèrement, je ne sais pas si ça va changer quelque chose.

  • Partager sur Facebook
  • Partager sur Twitter
24 mai 2018 à 21:02:10

D'accord merci beaucoup de ton aide ! J'arrive au bout de mon projet, malheureusement il se passe un truc bizarre.. Le canvas et terrain[x] n'est pas défini. Pourtant j'ai bien essayé de le définir et cela ne marche pas !

[lien retiré]

-
Edité par Otakin 25 mai 2018 à 19:53:07

  • Partager sur Facebook
  • Partager sur Twitter
25 mai 2018 à 19:39:44

Mets ton code ici, le but d'un forum d'entre aide n'est pas qu'on code à ta place mais de te donner des conseils et orienter ta recherche pour résoudre un bug.
  • Partager sur Facebook
  • Partager sur Twitter
25 mai 2018 à 19:52:35

D'accord je m'en excuse !

Voici rpg.js et chemin.js

let ts = new Tileset("chemin.png");
let rayon = 5;
let posX = 10;
let posY = 10;
let ctx;
let canvas;

/* si le curseur est dans la zone du canvas
   par défaut on considère que la curseur est hors canvas
*/
window.onload = function() { 
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');
/* On attache divers ecouteurs sur le Canvas*/
  canvas.addEventListener('mouseenter', fctMouseenter);
  canvas.addEventListener('mouseleave', fctMouseleave);
  canvas.addEventListener('mousemove',  function(e) {
  mouse_x = e.clientX;
  mouse_y = e.clientY;
  });
  canvas.addEventListener('click',      fctClick);
    dessine();
}
    

let bInCanvas = false;
/* si on acroche le curseur au rond 
   par défaut la forme suit le curseur
*/
let bAccroche = true;

/* Fonction qui écoute si la souris rentre dans le Canvas
 * @param oEvent event
*/
function fctMouseenter(oEvent){
  //Si mon curseur entre dans le canvas
  //je réassigne la valeur de bInCanvas
  bInCanvas = true;
}//fct
/* Fonction qui écoute si la souris sort du Canvas
 * @param oEvent event
*/
function fctMouseleave(oEvent){
  //Si mon curseur sort du canvas 
  //je réassigne la valeur de bInCanvas
  bInCanvas = false;
}//fct
/* Fonction qui écoute si on clique dans Canvas
 * @param oEvent event
 */
function fctClick(oEvent){
  //Si mon curseur clique dans le canvas 
  //j'inverse la valeur de bAccroche
  bAccroche = !bAccroche;
}//fct

/*
 * Quand la souris bouge dans canvas 
 * on remet à jour posX et posY
 * @param oEvent event 
 */
function fctMousemove(oEvent){
  let oCanvas = oEvent.target, oRect = oCanvas.getBoundingClientRect();
  posX = (oEvent.clientX - oRect.left) / (oRect.right - oRect.left) * oCanvas.width;
  posY = (oEvent.clientY - oRect.top) / (oRect.bottom - oRect.top) * oCanvas.height;
}//fct
// c'est mieux d'utiliser let et const plutôt que var
let position_depart = { x: 50, y: 50 };
let offset_x = 0;
let offset_y = 0;
let perso = position_depart; // c'est plus court écrit comme ça
let stop = false; // true = arreter le jeu et quitter (définitif)
let game_over = true;
let id = 0;
let mouse_x = 0;
let mouse_y = 0;

 
// pas besoin de mettre ça dans la fonction dessine
//Du coup je l'ai mise dans le window.onload car ça créait des anomalies 
  
  
//Dessine le rond
function dessine()
{

  // game over = recommencer au début
  if (game_over)
  {
    offset_x = (position_depart.x - mouse_x);
    offset_y = (position_depart.y - mouse_y);
    game_over = false;
  }
      
  // Clear
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  //dessin d'une partie de l'image en sélectionnant un "rectangle" source par ses coordonnées (x, y)
  //et par sa taille
   
  // mettre a jour la position du personnage
  perso.x = mouse_x + offset_x;
  perso.y = mouse_y + offset_y;
      
  for (let x = 0; x < 15; x++)
  {
    for(let y = 0; y < 15; y++)
    {  
        const herbe = 2;
        const pierredroite = 9;
        const pierre = 10;
        const pierregauche = 11;
        const terrain = [
		[5 , 6  , 6  , 7 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2],
		[9 , 10 , 10 , 11, 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2],
		[9 , 10 , 10 , 11, 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2],
		[13, 16 , 12 , 15, 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2],
		[2 , 9  , 11 , 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2],
		[2 , 9  , 11 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2],
		[2 , 9  , 8  , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 2 , 2 , 2],
		[2 , 13 , 14 , 14, 14, 14, 14, 14, 14, 14, 16, 11, 2 , 2 , 2],
		[2 , 2  , 2  , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 9 , 11, 2 , 2 , 2],
		[2 , 2  , 2  , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 9 , 11, 2 , 2 , 2],
		[2 , 2  , 2  , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 9 , 11, 2 , 2 , 2],
		[2 , 2  , 2  , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 9 , 11, 2 , 2 , 2],
		[2 , 2  , 2  , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 9 , 11, 2 , 2 , 2],
		[2 , 2  , 2  , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 9 , 11, 2 , 2 , 2],
		[2 , 2  , 2  , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 9 , 11, 2 , 2 , 2]
	]
        
      ts.dessinerTile(terrain[x][y], ctx, 32*y, 32*x);
    }
  }
     
  // si mon curseur est dans le canvas
  // et que je dois accrocher la forme au curseur
  // alors je redessine ma forme
  // sinon je ne fait rien
  if(bInCanvas != false && bAccroche != false)
  {
    // Draw Mob
    ctx.beginPath(); //On démarre un nouveau tracé.
    ctx.arc(posX, posY, rayon, 0, Math.PI*2); //On trace la courbe délimitant notre forme
    ctx.fill(); //On utilise la méthode fill(); si l'on veut une forme pleine
    ctx.closePath();
    if (!stop) {
      id = requestAnimationFrame(dessine);
    }
    else {
      cancelAnimationFrame(id);
      id = 0;
    }
  }
  
  // requestAnimationFrame est très pratique car ça permet de limiterSS
  // le nombre de dessin à 60 fps, si on utilisait une simple boucle infinie
  // on aurait 9999 images par secondes et ça ferait planter le navigateur
  // si on utilisait setInterval, on aurait 60 images par secondes mais
  // sans tenir compte du temps de tracé donc suivant les cas on aurait un
  // dessin moins fluide
}
dessine()

J'ai cette erreur sur la console : 

Uncaught TypeError: Cannot read property 'clearRect' of undefined

    at dessine (Chemin.js:30)

    at Chemin.js:95

-
Edité par Otakin 25 mai 2018 à 19:59:20

  • Partager sur Facebook
  • Partager sur Twitter
26 mai 2018 à 15:39:29

Ta principale erreur repose sur le fait que tu ne comprends pas ce que tu code. 

règle N°1 : ne jamais copier/coller un code d'internet sans le comprendre

window.onload = function() {
  // ...
};

En ce qui concerne ce code, le but est d'attendre le fin du chargement de la page pour lancer une fonction. C'est utile lorsqu'on souhaite récupérer un élément de la page et travailler dessus. Dans ton cas, cette fonction est utile car tu utilise l'élément canvas. En revanche, à chaque fois que tu utilise ton cavas tu vas devoir mettre ton code dans cette fonction. (ta fonction dessine doit se trouver à l'intérieur)

let truc = 5;
const machin = 5;
var bidule = 5;

Le mot var permet de créer des variables. Le problème avec var c'est que dans pas mal de cas des variables inutilisées prennent de la place en mémoire inutilement. Utiliser let à la place de var permet une meilleure gestion de la mémoire. Le mot const est réservé aux constantes donc aux variables qui ne sont jamais modifiées. Le code suivant ne doit donc pas être placé dans des boucles for mais à côté de position_depart (par exemple). 

const herbe = 2;
const pierredroite = 9;
const pierre = 10;
const pierregauche = 11;

Il y a 2 variables offset dans le code. Offset signifie décalage. Le but de ces variables est de pouvoir replacer l'élément à sa position de départ en cas de game over. Ce n'est pas une obligation d'utiliser un offset, j'ai simplement mis ce code à titre d'exemple à toi de voir si l'offset t'aide ou si tu trouve un autre moyen plus simple de replacer les éléments après un game over.







  • Partager sur Facebook
  • Partager sur Twitter
26 mai 2018 à 17:48:06

Merci pour les conseils ! Je comprends mieux !

Ce que j'essaye de faire c'est de faire une event sur les tiles 2 de ma map ainsi lorsque ma souris va sur les tiles vertes.. Le map se ClearReact (facile) ou reload la page (moyen) ou fait un message d'erreur et repositionne la souris (plus dur).

Cependant.. Je n'y arrive pas.. 

Donc ce que j'ai pensé à faire c'est de gommer avec un photoshop les herbes sur mon image de base chemin.js. Ainsi à la place de l'herbe il y aura du transparent et dans css je fais un background noir. Du coup si la souris va dans le background noir, la map se ClearReact. L'avantage c'est que ça m'a l'air beaucoup plus facile et quand la map disparait dans sa totalité le joueur est forcé de recharger la page.

M'enfin.. J'ai pas encore essayé, vous savez comment faire ? 

  • Partager sur Facebook
  • Partager sur Twitter
26 mai 2018 à 20:26:49

Tu ne peux pas utiliser à la fois le canvas (clearRect) et le contact avec la souris (mouseenter, mouseleave). Le canvas créé un affichage automatique qui se répète 60 fois par seconde comme n'importe quel jeu vidéo. Les événements de survol avec la souris concerne des éléments html (div par exemple). Dans un jeu le système de collision est interne au jeu lui même et indépendant de la plateforme sur laquelle il s'exécute. Si ce n'était pas le cas, la totalité des jeux existant seraient forcés de tourner uniquement sur navigateur. Pour chaque tile spéciaux il faut calculer les collisions pour lancer une fonction. 

function win() {
  // ...
}

function collision(mouse, tile) {
  const test_x = mouse.x > tile.x && mouse.x < (tile.x + tile.w);
  const test_y = mouse.y > tile.y && mouse.y < (tile.y + tile.h);
  return test_x && test_y;
}

function dessine() {

  const tile = { x: 10, y: 10, w: 32, h: 32, type: "win" };
  const mouse = { x: mouse_x, y: mouse_y };
  if (collision(mouse, tile) {
    if (tile.type == "win") {
      // niveau suivant
      win();
    }
  }

}



  • Partager sur Facebook
  • Partager sur Twitter
30 mai 2018 à 19:44:15

Je ne comprends pas la constant mouse.. Je n'ai jamais créer de fonction mouse * - * Je dois reprendre les coordonnées de mon évenement onmousemove ? C'est cela que tu appelles mouses ?
  • Partager sur Facebook
  • Partager sur Twitter
30 mai 2018 à 20:59:34

J'ai donc tenté ce que tu m'as dit mais rien ne se passe, ni message d'erreur ni de message d'alerte qui me dit que si la souris va sur la tile numéro 10, le jeu dit "Yo".

function dessine1() {
    
//un "rectangle" source par ses coordonnées (x, y)
//et par sa taille
    const tilewin = 10
    const herbe = 2
    const terrain = [
        [1 , 2 , 2 , 2 , 2 , 5 , 6 , 6 , 6 , 6 , 6 , 7 , 2 , 2 , 1],
        [5 , 6 , 6 , 6 , 6 , 14, 14, 14, 14, 14, 14, 14, 14, 8 , 2],
        [9 , 11, 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 9 , 2],
        [9 , 11, 2 , 1 , 2 , 2 , 5 , 6 , 6 , 6 , 7 , 2 , 5 , 4 , 7],
        [9 , 11, 2 , 2 , 2 , 5 , 4 , 14, 2 , 2 , 8 , 2 , 13, 12, 15],
        [9 , 11, 2 , 5 , 6 , 12, 15, 2 , 2 , 2 , 13, 7 , 2 , 9 , 2],
        [9 , 11, 2 , 9 , 12, 15, 2 , 2 , 2 , 2 , 5 , 15, 2 , 9 , 2],
        [9 , 11, 2 , 9 , 11, 2 , 2 , 5 , 6 , 14, 15, 2 , 5 , 4 , 7],
        [9 , 11, 2 , 9 , 11, 2 , 2 , 9 , 11, 2 , 2 , 2 , 13, 12, 15],
        [9 , 11, 2 , 9 , 8 , 6 , 7 , 9 , 8 , 6 , 6 , 6 , 7 , 9 , 2],
        [9 , 11, 2 , 13, 14, 16, 11, 13, 16, 3 , 3 , 12, 15, 9 , 2],
        [9 , 8 , 6 , 7 , 2 , 9 , 11, 1 , 13, 14, 14, 15, 1 , 9 , 2],
        [9 , 4 , 8 , 11, 2 , 9 , 8 , 6 , 6 , 6 , 6 , 6 , 6 , 4 , 7],
        [9 , 16, 12, 11, 2 , 13, 14, 14, 14, 14, 14, 14, 14, 14, 15],
        [13, 14, 14, 15, 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 1]
    ]
    
    if (posX+posY === herbe){
        alert('vous ne pouvez pas passer');
    }
    for (var x = 0; x < 15; x++) {
        for(var y = 0; y < 15; y++) {
    // Méthode de dessin du tile numéro "numero" dans le contexte 2D "context" aux coordonnées x et y
            ts.dessinerTile(terrain[x][y], ctx, 32*y, 32*x);
        }
    }
    
function win() {
  alert('Yo');
}
 
function collision(mouse, tile) {
  const test_x = mouse.posX > tile.xDestination && mouse.posX < (tile.xDestination + tile.xSource);
  const test_y = mouse.posY > tile.xDestination && mouse.posY < (tile.xDestinatation + tile.ySource);
  return test_x && test_y;
}
 
    function dessine() {

      const tile = { xDestination: 10, yDestination: 10, xSource: 32, ySource: 32, type: "win" };
      const mouse = { posX: mouse_x, posY: mouse_y };
      if (collision(mouse, tile)) {
        if (tile.tilewin == "win") {
          // niveau suivant
          win();
        }
      }
    }
}


Je ne sais pas à quoi correspondent les numéro de cette ligne : 

const tile = { xDestination: 10, yDestination: 10, xSource: 32, ySource: 32, type: "win" };

Voici le codepen : https://codepen.io/GxStarDiablotin/pen/ERaQvr

Bizarrement quand je mets les codes bouts à bouts rien ne s'affiche alors que séparément oui (j'ai 5 fichiers js).

Sinon, tu as retrouvé ce codage où ? C'est toi qui la construit à partir de rien ? Ou tu t'en ai inspiré ? Tu fais comment pour être aussi intelligent ? Car je n'arrête pas de bouffer de la théorie sur js mais ça ne rentre pas.. Si tu t'en sens pas bien de dire ça en public, on peut toujours parler en mp ^^

Merci :)

-
Edité par Otakin 30 mai 2018 à 21:05:23

  • Partager sur Facebook
  • Partager sur Twitter
1 juin 2018 à 13:19:03

Ok, j'ai pigé le problème : tu n'as pas de bonne méthodologie de travail. Si tu veux un résultat tu dois procéder de façon itérative (= par étape). Commence par créer un nouveau projet vide sans ligne de code puis fixe toi un objectif simple (afficher une image dans le canvas par exemple) ensuite si ça marche et seulement si ça marche, passe à l'étape suivante et découpe ton image en tile pour tenter d'afficher juste un morceau. Ta manière de faire ressemble à la mienne dans mes débuts. Je ne suis pas plus intelligent ou quoi que ce soit, j'ai simplement commencé la programmation il y a 6 ans. Avec la pratique, on fini par avoir de bons réflexes (on sait ce qu'il faut regarder en premier quand ça marche pas pour corriger). Comme quand on fait une dictée et qu'on fait des fautes à confondre les "à" et les "a" ou les verbes en "er" et les verbes en "é". Si on sait qu'on a tendance à faire telle ou telle genre d'erreur, c'est celles qu'on vérifie en premier. D'ailleurs, même si c'est souvent une bonne chose de séparer dans plusieurs fichiers je ne te le conseille pas. C'est plus facile de se relire lorsqu'on a qu'un seul fichier.

Quand je code, je code souvent à partir de rien. Le but de la programmation c'est de traduire un objectif (ici afficher ton jeu) en ligne de code. Si je me contentais de copier/coller des trucs, je n'aurais pas forcément le résultat que j'attends.

if (posX+posY === herbe){
  alert('vous ne pouvez pas passer');
}

Cette ligne (au dessus) par exemple, n'a aucun sens. L'idée (j'imagine) est de tester si on a une case qui contient de l'herbe pour indiquer qu'on de peut pas passer. posX et posY représentent la position de quelque chose sur le terrain. Pour tester si telle ou telle case est une case d'herbe il faut écrire : 

if (terrain[posX][posY] === herbe) {
  // faire quelque chose ici quand on a de l'herbe...
}

Mais ne copie pas bêtement ce code, demande toi avant si écrire cette ligne est nécessaire pour te permettre de faire fonctionner ton jeu ou si ça ne sert à rien. Et je penses que cette ligne ne sert à rien (en tout cas, si elle sert elle n'est pas placée au bon endroit).

window.onmousemove = e => console.log("x : " + e.clientX + " y : " + e.clientY);

// dans mon code j'utilise la syntaxe ES6 (la dernière version de javascript)
// si tu utilise une ancienne version ce que je viens d'écrire peut aussi 
// s'écrire : 

window.onmousemove = function (e) {
  console.log("x : " + e.clientX + " y : " + e.clientY);
};

// C'est la même chose mais écrit de 2 façons différentes. 
// C'est pareil pour l'utilisation de prototype et de class
// ton code : 

function Tileset(url) {
  // Chargement de l'image dans l'attribut image
  this.image = new Image();
  this.image.referenceDuTileset = this;
  this.image.onload = function() {
    if(!this.complete) throw new Error("Erreur de chargement du tileset nommé \"" + url + "\".");
    // Largeur du tileset en tiles
    this.referenceDuTileset.largeur = this.width / 32;
  }
  this.image.src = "tilesets/" + url;
}

// Méthode de dessin du tile numéro "numero" dans le contexte 2D "context" aux coordonnées x et y
Tileset.prototype.dessinerTile = function(numero, ctx, xDestination, yDestination) {
  var xSourceEnTiles = numero % this.largeur;
  if(xSourceEnTiles == 0) xSourceEnTiles = this.largeur;
  var ySourceEnTiles = Math.ceil(numero / this.largeur);
  xSource = (xSourceEnTiles - 1) * 32;
  ySource = (ySourceEnTiles - 1) * 32;
  ctx.drawImage(this.image, xSource, ySource, 32, 32, xDestination, yDestination, 32, 32);
}

// peut aussi s'écrire avec une classe : 

class Tileset {

  constructor(url) {
    // Chargement de l'image dans l'attribut image
    this.image = new Image();
    this.image.referenceDuTileset = this;
    this.image.onload = function() {
      if(!this.complete) {
        throw new Error("Erreur de chargement du tileset nommé \"" + url + "\".");
      }
      // Largeur du tileset en tiles
      this.referenceDuTileset.largeur = this.width / 32;
    }
    this.image.src = "tilesets/" + url;
  }

  dessinerTile(numero, ctx, xDestination, yDestination) {
    const xSourceEnTiles = (numero % this.largeur == 0) ? this.largeur : numero % this.largeur;
    const ySourceEnTiles = Math.ceil(numero / this.largeur);
    xSource = (xSourceEnTiles - 1) * 32;
    ySource = (ySourceEnTiles - 1) * 32;
    ctx.drawImage(this.image, xSource, ySource, 32, 32, xDestination, yDestination, 32, 32);
  }

}

// au passage, j'ignore si ce code est juste ou non. Il est juste syntaxiquement mais 
// il est possible que ce code ne corresponde pas à l'objectif qu'il est censé faire. 
// Si tu veux écrire une fonction qui te donne le double d'un nombre (par exemple) 
// et que tu écris : 
function double (nombre) {
  return nombre - 10;
}
// Le code est juste syntaxiquement car il fonctionne mais il est faux 
// car il ne fait pas ce pour quoi il a été créé.





  • Partager sur Facebook
  • Partager sur Twitter