210 lines
6.4 KiB
JavaScript
210 lines
6.4 KiB
JavaScript
// 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);
|
|
}
|