Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/howler/1.1.28/howler.min.js"></script>
</head>
<body>
  <canvas id="myCanvas" width=300 height=300></canvas>
  <div id="fps"></div>
  <audio id="music1" src="http://mainline.i3s.unice.fr/mooc/guitarRiff1.mp3" loop ></audio>
</body>
</html>
#myCanvas {
  border:1px solid black;
  /*background-color:pink;*/
}
 
// bonne pratique: on déclare ces variables globales
var canvas, ctx, w, h, fpsContainer;
// Etats des touches, de la souris, etc
var inputStates = {};
// les balles
var tableauDesBalles = [];
var nbBallesVivantes;
var nbBalles = 5;
// son
var plop;
// projectile
var projectile = {
  x:0,
  y:0,
  angle:0,
  dead:true,
  vitesse:10,
  direction:0,
  draw:function() {
    if(this.dead) return;
    
    ctx.save();
    console.log('draw projectile');
    ctx.fillRect(this.x, this.y, 5, 5);
    ctx.restore();
  },
  move: function() {
    this.x += this.vitesse*Math.sin(-this.angle);
    this.y += this.vitesse*Math.cos(this.angle);
  },
};
// objet singleton
var monstre = {
  x: 100, 
  y: 100,
  speed: 3, // vitesse en pixels/image
  speedX : 0,
  speedY: 0,
  width: 50,
  height: 50,
  angle: 0,
  couleur: "yellow",
  
  move: function(x, y) {
    //this.x += this.speedX;
    //this.y += this.speedY;
    //this.y = y;
    if(!this.angle) return;
    this.x += 1*Math.sin(-this.angle);
    this.y += 1*Math.cos(this.angle);
  },
  
  draw: function() {
     // bonne pratique obligatoire !!!
     ctx.save(); // on sauvegarde le contexte
     ctx.translate(this.x, this.y);
     ctx.rotate(this.angle);
             ctx.scale(0.5, 0.5);
     //ctx.translate(-50,-50);
      ctx.shadowColor = "black"; // color
ctx.shadowBlur = 5; // blur level
ctx.shadowOffsetX = 5; // horizontal offset
ctx.shadowOffsetY = 5; // 
     // tete
    ctx.beginPath();
     ctx.arc(0, 0, 50, 0, Math.PI*2);
    ctx.stroke();
    
    ctx.fillRect(-20, -20, 5, 5);
    ctx.fillRect(20, -20, 5, 5);
    /*
     ctx.fillStyle = this.couleur;
     ctx.fillRect(0, 0, 100, 100);
     ctx.lineWidth = 5;
     ctx.strokeRect(0, 0, 100, 100);
  
     this.drawYeux();
  
     // nez
     ctx.fillStyle = "green";
     ctx.fillRect(40, 50, 10, 25);
     ctx.strokeRect(40, 50, 10, 25);
     // bouche
     ctx.fillRect(20, 80, 50, 10);
     ctx.strokeRect(20, 80, 50, 10);
     ctx.fillStyle = "black";
     ctx.fillRect(25, 80, 5, 10);
     ctx.fillRect(40, 80, 5, 10);
     ctx.fillRect(55, 80, 5, 10);
  */
     // on restaure le contexte
     ctx.restore();
   },
   drawYeux: function() {
     // oeil gauche
     ctx.lineWidth = 3;
     ctx.strokeRect(10, 20, 20, 20);
     ctx.fillStyle="red";
     ctx.fillRect(17, 27, 10, 10);
  
     // oeil droit
     ctx.save();
     ctx.translate(50, 0);
     ctx.lineWidth = 3;
     ctx.strokeRect(10, 20, 20, 20);
     ctx.fillStyle="red";
     ctx.fillRect(17, 27, 10, 10);
     ctx.restore();
   }
};
window.onload = init;
function init() {
  console.log("page chargée");
  
  canvas = document.querySelector("#myCanvas");
  ctx = canvas.getContext("2d");
  w = canvas.width;
  h = canvas.height;
  
  // Pour l'affichage du nombre d'images/s
  fpsContainer = document.querySelector("#fps");
  
  // on déclare des écouteurs pour les touches
  // on va déplacer le monstre avec les fleches
  document.addEventListener("keydown", traiteToucheEnfoncee, false);
  document.addEventListener("keyup", traiteToucheRelachee, false);
  // ecouteur pour la souris
  canvas.addEventListener("mousemove", traiteSourisDeplacee, false);
  
  // On démarre le jeu
  //monstre.speedX = monstre.speed;
  
  // On créer les balles
  nbBallesVivantes = nbBalles;
  creerDesBalles(nbBalles);
  
  // On charge le son des balles qui touches les murs
  plop = new Howl({
  urls: ['http://mainline.i3s.unice.fr/mooc/plop.mp3']
});
  
  
  mainloop();
  //ctx.fillRect(150, 150, 100, 100);
}
// ----- BOUCLE D'ANIMATION
function mainloop(time) {
  measureFPS(time);
  
  // 1 On efface le contenu du canvas
  ctx.clearRect(0, 0, w, h);
  
  // 2 On dessine le monstre et les ennemis
  //drawBall(100, 100, 15, "blue");
  dessinerToutesLesBalles();
  // angle entre le monstre la souris...
  var dx = monstre.x - inputStates.mouseX;
  var dy = monstre.y - inputStates.mouseY;
  var angle = Math.atan2(dy, dx);
  monstre.angle = angle+Math.PI/2;
  monstre.draw();
  
  // 3 On deplace
  monstre.move();
  testeCollisionsAvecMurs();
  testCollisionsBallesAvecMurs();
  testCollisionsBallesAvecJoueur();
  
  // Regarder si le niveau est fini 
  // (toutes les balles mortes)
  verifierFinNiveau();
  
  // On vérifie l'état des touches, souris, gamepad etc.
  checkInputStates();
  
  // 4 On rappelle la boucle 60 fois par seconde
  requestAnimationFrame(mainloop);
}
function checkInputStates() {
  monstre.speedX = monstre.speedY = 0;
  
  if(inputStates.right) {
    monstre.speedX = monstre.speed;
  }
   if(inputStates.left) {
    monstre.speedX = -monstre.speed;
  }
   if(inputStates.up) {
    monstre.speedY = -monstre.speed;
  }
   if(inputStates.down) {
    monstre.speedY = monstre.speed;
  }
  if(inputStates.space) {
    if(projectile.dead) {
    projectile.x = monstre.x   ;   
    projectile.y = monstre.y;
    projectile.angle = monstre.angle; 
      projectile.dead = false;
    }
  } else {
    projectile.move();
    projectile.draw();
    if((projectile.x > w) ||  (projectile.x < 0) ||
       (projectile.y > h) ||  (projectile.y < 0))
       {
      projectile.dead = true;
    }
  }
}
function verifierFinNiveau() {
  // on a fini le niveau si toutes les balles
  // sont mortes
  if(nbBallesVivantes === 0) {
    // On passe au niveau suivant, on crée
    // deux balles de plus
    nbBalles += 2;
    nbBallesVivantes = nbBalles;
    creerDesBalles(nbBalles);
  }
}
function testCollisionsBallesAvecJoueur() {
  var collision = false;
   for(var i=0;i < tableauDesBalles.length; i++) {
     var b = tableauDesBalles[i];
     
     if(!b.dead) {
     
     if(circRectsOverlap(monstre.x, monstre.y, monstre.width, monstre.height, 
                         b.x, b.y, b.r)) {
      collision=true;
      b.dead = true;
      nbBallesVivantes--;
     }
   }
  
  if(collision) {
    monstre.couleur = "green";
  } else {
    monstre.couleur = "yellow";
  }
   }
}
function testeCollisionsAvecMurs() {
  if((monstre.x + monstre.width) >= w) {
    monstre.speedX = 0;
    monstre.x = w - monstre.width;
  }
  if(monstre.x <= 0) {
    monstre.speedX = 0;
    monstre.x = 0;
  }
    if((monstre.y + monstre.height) >= h) {
    monstre.speedY = 0;
    monstre.y = h - monstre.height;
  }
  if(monstre.y <= 0) {
    monstre.speedY = 0;
    monstre.y = 0;
  }
}
// ------ les balles ----
function Balle(x, y, rayon, couleur, vitesseX, vitesseY) {
  this.x = x;
  this.y = y;
  this.r = rayon;
  this.couleur = couleur;
  this.speedX = vitesseX;
  this.speedY = vitesseY;
  this.dead = false;
  
  this.move = function() {
    this.x += this.speedX;
    this.y += this.speedY;
  };
  
  this.draw = function() {
     ctx.save();
  
     // On remet à zero le buffer des ordres de 
     // dessin dans le chemin/Path
     ctx.beginPath();
     ctx.arc(this.x, this.y, this.r, 0, 2*Math.PI);
  
     ctx.fillStyle = this.couleur;
     ctx.strokeStyle = "red";
     ctx.lineWidth = 3;
     // On va dessiner les ordres dans le path
     // une fois en plein et une fois en fil de fer
    ctx.save();
      ctx.shadowColor = "#bbbbbb"; // color
ctx.shadowBlur = 5; // blur level
ctx.shadowOffsetX = 5; // horizontal offset
ctx.shadowOffsetY = 5; // 
     ctx.fill();
    ctx.restore();
    
     ctx.stroke();
  
     ctx.restore();
   };
}
function creerDesBalles(n) {
  for(var i=0;i < n; i++) {
    var x = Math.random() * w;
    var y = Math.random() * h;
    var r = 10;
    var couleur = "black";
    var speedX = -5 + Math.random()*10;
    var speedY = -5 + Math.random()*10;
    var b = new Balle(x, y, r, couleur, speedX, speedY);
    
    
    
    // Do not create a ball on the player. We augmented the ball radius 
    // to sure the ball is created far from the monster. 
    if (!circRectsOverlap(monstre.x, monstre.y,
                    monstre.width, monstre.height,
                    b.x, b.y, b.r * 3)) {
       // On rajoute la balle au tableau
      tableauDesBalles.push(b);
    } else {
                i--;
    }   
  }
}
function dessinerToutesLesBalles() {
  for(var i=0;i < tableauDesBalles.length; i++) {
 
    
    var b = tableauDesBalles[i];
    
    if(!b.dead) {
       b.move();
       b.draw();
    }
  }
}
function testCollisionsBallesAvecMurs() {
  for(var i=0;i < tableauDesBalles.length; i++) {
    var b = tableauDesBalles[i];
    
    if(!b.dead){
    
    // mur droit
    if((b.x + b.r) > w) {
      b.speedX = -b.speedX;
      b.x = w - b.r;
      plop.play();
    }
    // mur gauche
     if(b.x-b.r <0) {
      b.speedX = -b.speedX;
       b.x = b.r;
       plop.play();
    }
        // mur bas
    if((b.y + b.r) > h) {
      b.speedY = -b.speedY;
      b.y = h - b.r;
      plop.play();
    }
    // mur haut
     if(b.y-b.r <0) {
      b.speedY = -b.speedY;
       b.y = b.r;
       plop.play();
    }
    }
  }
}
// ------- Mesurer le nombre d'images/s
 // vars for counting frames/s, used by the measureFPS function
    var frameCount = 0;
    var lastTime;
    var fpsContainer;
    var fps; 
  
    var measureFPS = function(newTime){
      
         // test for the very first invocation
         if(lastTime === undefined) {
           lastTime = newTime; 
           return;
         }
      
        //calculate the difference between last & current frame
        var diffTime = newTime - lastTime; 
        if (diffTime >= 1000) {
            fps = frameCount;    
            frameCount = 0;
            lastTime = newTime;
        }
        //and display it in an element we appended to the 
        // document in the start() function
       fpsContainer.innerHTML = 'FPS: ' + fps; 
       frameCount++;
    };
// ------- DETECTION COLLISIONS
    // Collisions between rectangle and circle
    function circRectsOverlap(x0, y0, w0, h0, cx, cy, r) {
        var testX = cx;
        var testY = cy;
        if (testX < x0)
            testX = x0;
        if (testX > (x0 + w0))
            testX = (x0 + w0);
        if (testY < y0)
            testY = y0;
        if (testY > (y0 + h0))
            testY = (y0 + h0);
        return (((cx - testX) * (cx - testX) + (cy - testY) * (cy - testY)) < r * r);
    }
// ------- ECOUTEURS ------
// Les écouteurs de touches, maintenant ils sont génériques
function traiteToucheEnfoncee(evt) {
  console.log("touche enfoncee code= " + evt.keyCode);
  switch(evt.keyCode) {
    case 39:
      // fleche à droite
      inputStates.right = true;
      break;
    case 37:
      // fleche à gauche
      inputStates.left = true;
      break;
    case 40:
      // fleche en bas
      inputStates.down = true;
      break;
    case 38:
      // fleche en haut
      inputStates.up = true;
      break;
    case 32:
      // espace
      inputStates.space = true;
      break;
  }
}
function traiteToucheRelachee(evt) {
  console.log("touche relachee");
  switch(evt.keyCode) {
    case 39:
      // fleche à droite
      inputStates.right = false;
      break;
    case 37:
      // fleche à gauche
      inputStates.left = false;
      break;
    case 40:
      // fleche en bas
      inputStates.down = false;
      break;
    case 38:
      // fleche en haut
      inputStates.up = false;
      break;
    case 32:
      // space
      inputStates.space = false;
      break;
  }
}
function traiteSourisDeplacee(evt) {
  //console.log("souris deplacee");
  var rect = canvas.getBoundingClientRect();
  var x = evt.clientX - rect.left;
  var y = evt.clientY - rect.top;
  inputStates.mouseX = x;
  inputStates.mouseY = y;
  }
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
micbuffapro
0viewers