/* PREMIERE CHOSE A FAIRE: ouvrir avec un éditeur de texte et renommer ce fichier avec une extension .js Code pour le fonctionnement du canva Serpent (Snake). Création: Octobre 2020. Dernière modification: Novembre 2020 Auteur: Boris Chrismant Mail: contact[a]chrismantcreation.fr Le code est open source, citez moi quand même si vous en emprunter ;) Description: Le canva doit avoir l'attribut id="serpent" pour être utilisé. Les attributs width et height sont récupérés du fichier html. exemple: Le serpent se lance après le chargement du fichier serpent.js . Le lien vers le fichier serpent.js doit être placé après votre balise canva. On peut bien-sûr modifier plein de chose: largeur du serpent, motifs, évolutions, remise à zéro, forme ronde du canva, etc. A la guise de l'imaginaire. */ class Snake { // La class du serpent // le constructeur requiert la position de départ, par défaut le milieu du canva constructor (x, y) { this.repas = 0; // variable de décompte des fourmis mangées this.x = x; // coordonnée x this.y = y; // coordonnée y this.xspeed = 0; // progression de x this.yspeed = 0; // progression de y this.oeil_1 = [2,2]; // position initiale de l'Oeil 1 this.oeil_2 = [2,6]; // position initiale de l'Oeil 2 this.queue = [[this.x,this.y]]; // tableau qui contiendra l'ensemble des coordonnées du corps du serpent this.growth = 0; // croissance du serpent // style par défaut du corps encapsulé dans une fonction this.style = function() { for(var i=0;i 0 ? this.growth-- : this.queue.pop(); // croissance et décrémentation du facteur de croissance s'il est positif return ([this.x,this.y]); // renvoie la position de la tête } show() { // la fonction show dessine le serpent var e = this.style(); // dessine le corps // dessine la tête ctx.fillStyle = ('yellow'); ctx.fillRect(this.queue[0][0], this.queue[0][1],10,10); ctx.fillStyle = ('black'); ctx.fillRect(this.queue[0][0]+this.oeil_1[0], this.queue[0][1]+this.oeil_1[1],2,2); ctx.fillStyle = ('black'); ctx.fillRect(this.queue[0][0]+this.oeil_2[0], this.queue[0][1]+this.oeil_2[1],2,2); } dir(x,y) { // mise à jour du sens de progression du serpent et positionnement des yeux perpendiculairement à ce sens this.xspeed = x; this.yspeed = y; if (x==0 && y<=-1) { // vers le haut this.oeil_1 = [2,2]; this.oeil_2 = [6,2]; } if (x==0 && y>=1) { // vers le bas this.oeil_1 = [2,6]; this.oeil_2 = [6,6]; } if (x>=1 && y==0) { // vers la droite this.oeil_1 = [6,2]; this.oeil_2 = [6,6]; } if (x<=-1 && y==0) { // vers la gauche this.oeil_1 = [2,2]; this.oeil_2 = [2,6]; } } dir_ad(sp) { // fonction d'adaptation de la vitesse juste après qu'une fourmi soit mangée this.xspeed == 0 ? (this.yspeed > 0 ? this.dir(0,sp) : this.dir(0,-sp)) : (this.xspeed > 0 ? this.dir(sp,0) :this.dir(-sp,0)); } mange(gr) { // fonction de repas :) this.repas++; this.growth = gr; // facteur de croissance (nombre de cycles) // différentes évolutions en fonction du nombre de fourmis mangées switch(true) { case this.repas<40: break; case this.repas<80: this.style = function() { for(var i=0;i=160: // au-delà de 160 fourmis, le serpent recommence au début speed = 0; break; } } // fonction de choix de la direction en fonction de la position de la fourmi // la fonction est calibrée pour priviligier les mouvements rectilignes auto(fourmi,spd) { var delta_x = this.x - fourmi.x; var delta_y = this.y - fourmi.y; if ((Math.abs(delta_x) < Math.abs(delta_y) && (Math.abs(delta_x ) > spd)) || (Math.abs(delta_y) < spd)) { if (delta_x < 0) this.dir(spd,0); else this.dir(-spd,0); } else { if (delta_y < spd) this.dir(0,spd); else this.dir(0,-spd); } } } class Fourmi { // La classe des fourmis constructor () { // création de la fourmi de façon alétaoire dans la limite du canva this.x = Math.floor(Math.random() * Math.floor(cote_l-10)); this.y = Math.floor(Math.random() * Math.floor(cote_L-10)); // choix aléatoire de la couleur et de la valeur de croissance de la fourmi var e = Math.floor(Math.random() * 6) + 1; switch (e) { case 1: this.color = "blue"; this.value = 1; break; case 2: this.color = "cyan"; this.value = 2; break; case 3: this.color = "lime"; this.value = 3; break; case 4: this.color = "green"; this.value = 4; break; case 5: this.color = "red"; this.value = 5; break; case 6: this.color = "orange"; this.value = 6; break; } Fourmi.nb++; } show() { // fonction de dessin de la fourmi (un carré de 10 pixels) ctx.fillStyle = (this.color); ctx.fillRect(this.x,this.y,10,10); } check(a) { // fonction de vérification de croisement entre la fourmi et la tête du serpent var x_s = a[0]; var y_s = a[1]; if ((Math.abs(this.x - x_s) <10) && (Math.abs(this.y - y_s) <10)) return true; else return false; } } function setup() { // dessin du canva ctx.fillStyle = ('grey'); ctx.fillRect(0,0,cote_l,cote_L); s.show(); f.show(); } function draw_auto() { // fonction de routine setup(); if (f.check(s.update())) { s.mange(f.value); s.dir_ad(speed); f = new Fourmi(); } check_auto(); s.auto(f,speed); } function check_auto() { // fonction de relance de la partie auto if (!speed) { clearInterval(play); jouer_auto(); } } function jouer_auto() { // fonction de lancement de la partie auto, initialisation des variables de la partie s = new Snake(cote_l/2,cote_L/2); f = new Fourmi(); speed = 1; if (play) clearInterval(play); play = setInterval('draw_auto()',(100/number)); } function pause(){ // fonction de pause. Elle peut être appelée quand on clique sur le canvas par exemple. if (play) { // elle doit être appelée une nouvelle fois pour reprendre la partie auto clearInterval(play); play = null; } else play = setInterval('draw_auto()',(100/number)); } /* Variables de la partie */ var number = 10; // nombre de cycle dans une seconde var play; var s; var f; var speed; // variables de partie // variables du canva var canva = document.getElementById("serpent"); canva.style.cursor = "pointer"; var width = canva.getAttribute("width"); width.replace("px",""); var cote_l = parseInt(width); var height = canva.getAttribute("height"); width.replace("px",""); var cote_L = parseInt(height); var ctx = canva.getContext('2d'); // Lancement de la partie automatique jouer_auto();