/* 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();