// Customize Array to be use as coordinates Object.defineProperty(Array.prototype, "x", { get: function () { return this[0] }, set: function (x) { this[0] = x} }) Object.defineProperty(Array.prototype, "y", { get: function () { return this[1] }, set: function (y) { this[1] = y} }) Array.prototype.plus = function(other) { return this.map((x, i) => x + other[i]) } const DIRECTION = { "BAS": 0, "GAUCHE": 1, "DROITE": 2, "HAUT": 3 } const MOUVEMENT = { "ARRET": [0, 0], "BAS": [0, 1], "HAUT": [0, -1], "GAUCHE": [-1, 0], "DROITE": [1, 0] } const ACTIONS = { "ArrowUp": {"direction": DIRECTION.HAUT, "mouvement": MOUVEMENT.HAUT}, "ArrowDown": {"direction": DIRECTION.BAS, "mouvement": MOUVEMENT.BAS}, "ArrowLeft": {"direction": DIRECTION.GAUCHE, "mouvement": MOUVEMENT.GAUCHE}, "ArrowRight": {"direction": DIRECTION.DROITE, "mouvement": MOUVEMENT.DROITE}, } const TYPE = { "MUR": 1, "SOL": 2, "PAS": 3 } const DIRECTIONS_LABYRINTHE = [MOUVEMENT.BAS, MOUVEMENT.HAUT, MOUVEMENT.GAUCHE, MOUVEMENT.DROITE] const TAILLE_TUILE = 15 function dessinerTuile(context, image, x, y) { context.drawImage(image, TAILLE_TUILE*x, TAILLE_TUILE*y); } class Labyrinthe extends Array { constructor(largeur, hauteur, context, tuiles) { super() this.hauteur = hauteur this.largeur = largeur this.context = context this.tuiles = tuiles for (var ligne=0; ligne < hauteur; ligne++) { this.push(Array(largeur).fill(TYPE.MUR)) } this.positionInitiale = [1, 1] this.positionFinale = [largeur - 2, hauteur - 2] this.creuse(this.positionFinale) this.construit(this.positionFinale) } construit(position) { for (var direction of Array.from(DIRECTIONS_LABYRINTHE).sort(x => .5 - Math.random())) { var pas1 = position.plus(direction) var pas2 = pas1.plus(direction) if (this.type(pas2) == TYPE.MUR) { this.creuse(pas1) this.creuse(pas2) this.construit(pas2) } } } creuse(position) { this[position.y][position.x] = TYPE.SOL } type(position) { if (0 <= position.x && position.x < this.largeur && 0 <= position.y && position.y < this.hauteur) { return this[position.y][position.x] } else { return -1 } } dessiner() { this.forEach((ligne, y) => { ligne.forEach((type, x) => { dessinerTuile(this.context, this.tuiles[type], x, y) }) }) } } class Souris { constructor(position, context, sprites) { this.position = position this.context = context this.sprites = sprites this.futurePosition = this.position this.direction = DIRECTION.DROITE this.mouvement = MOUVEMENT.ARRET this.tailleSprite = 48 this.animationSprite = 0 this.animation = 0 } bouger(touche, labyrinthe) { if (touche in ACTIONS) { this.direction = ACTIONS[touche].direction this.mouvement = ACTIONS[touche].mouvement var futurePosition = this.position.plus(this.mouvement) if ([TYPE.SOL, TYPE.PAS].includes(labyrinthe.type(futurePosition))) { labyrinthe[this.position.y][this.position.x] = TYPE.PAS this.futurePosition = futurePosition return true } else { this.mouvement = MOUVEMENT.ARRET this.animation = 0 return false } } else { return False } } dessiner() { this.context.drawImage( this.sprites, this.tailleSprite * this.animationSprite, this.tailleSprite * this.direction, this.tailleSprite, this.tailleSprite, TAILLE_TUILE * this.position.x - 17 + this.mouvement.x * this.animation, TAILLE_TUILE * this.position.y - 12 + this.mouvement.y * this.animation, this.tailleSprite, this.tailleSprite ); } } window.onload = function() { var canvas = document.getElementById('canvas') var ctx = canvas.getContext('2d') var fromage = document.getElementById("fromage"); var sourisSprites = document.getElementById("souris"); var tuiles = {} tuiles[TYPE.MUR] = document.getElementById("mur") tuiles[TYPE.SOL] = document.getElementById("sol") tuiles[TYPE.PAS] = document.getElementById("pas") var touchesPressees = new this.Set() var largeur = Math.floor(window.innerWidth / TAILLE_TUILE) largeur = largeur - ((largeur+1) % 2) var hauteur = Math.floor(window.innerHeight / TAILLE_TUILE) hauteur = hauteur - ((hauteur+1) % 2) canvas.width = largeur * TAILLE_TUILE; canvas.height = hauteur * TAILLE_TUILE; var labyrinthe = new Labyrinthe(largeur, hauteur, ctx, tuiles) var souris = new Souris(labyrinthe.positionInitiale, ctx, sourisSprites) window.onkeydown = function(event) { if (event.key in ACTIONS) { touchesPressees.add(event.key) return false } else { return true } } window.onkeyup = function(event) { if (event.key in ACTIONS) { touchesPressees.delete(event.key) return false } else { return true } } var timerID timerID = setInterval(function() { if (touchesPressees.size > 0) souris.animationSprite = (souris.animationSprite + 1) % 3 if (souris.mouvement != MOUVEMENT.ARRET) { souris.animation += 5 if (souris.animation >= TAILLE_TUILE) { souris.animation = 0 souris.position = souris.futurePosition if (souris.position.x == labyrinthe.positionFinale.x && souris.position.y == labyrinthe.positionFinale.y) { window.alert("Miam miam !") clearInterval(timerID) } } } if (souris.animation == 0) { souris.mouvement = MOUVEMENT.ARRET for (touche of Array.from(touchesPressees).reverse()) { if (souris.bouger(touche, labyrinthe)) break } } labyrinthe.dessiner() dessinerTuile(ctx, fromage, labyrinthe.positionFinale.x, labyrinthe.positionFinale.y) souris.dessiner() }, 40); }