Sujet 1

  1. Bienvenue aux TP de JavaScript BUT S4
    1. Aide mémoire
  2. Révisions HTML et CSS
    1. Rappel: HTML / Arbre
    2. Révision: arbre simple
    3. Révisions: Arbre d'un document complet
    4. Arbre vers HTML
    5. Rappel: "span" et "div"
    6. inline / block
    7. Révision : span
    8. Rappel: sélecteurs CSS, attribut style
    9. Révision CSS
    10. Révision CSS
    11. Révision CSS
    12. Révision CSS: sélecteur plus compliqué
    13. Révision CSS - inline
  3. Révisions JS
    1. Déclaration
    2. Boucle for
    3. Portée
    4. Fonctions
    5. Fonction simple
    6. Fonction anonyme
    7. Fonction fléchée
  4. Révisions DOM
    1. Chercher élément
    2. Gestionnaire d'événements
  5. Jeu poissons: 1ère partie
    1. Eau
    2. Correction
    3. Pingouin
    4. top
    5. Clavier
    6. Touches
    7. Position du pingouin
    8. Correction
    9. Limites mouvement pingouin
    10. Correction
  6. Jeu poissons: 2e partie
    1. Créer l'image
    2. Fichier image
    3. Insérer le poisson
    4. class="poisson"
    5. Correction
    6. CSS poisson
    7. Correction CSS poisson
    8. Défilement poisson : transitions CSS
    9. Plus de poissons
    10. Correction: plusieurs poissons
    11. Position aléatoire
    12. Correction position aléatoire
    13. Suppression du poisson
    14. Correction
  7. Jeu poissons: 3e partie
    1. Collision pingouin poisson
    2. Correction collision
    3. Afficher le score
    4. Améliorations
    5. Correction
    6. Collision / Fin d'animation
    7. Correction
    8. Le phoque
    9. Correction: fin

1. Bienvenue aux TP de JavaScript BUT S4

1.1 Bienvenue aux TP de JavaScript BUT S4

Les TP de JavaScript se déroulent sur ce logiciel appelé « Moodle ».

Vous devez travailler connectés (lien « Connexion » en haut à droite de la page). Sinon, vous rencontrerez des problèmes d'avancement et vous risquez d'être comptés absent. En étant connectés vous retrouverez l'endroit où vous en étiez à la séance suivante.

Dans ces TP, vous trouverez des explications à lire, des questions à répondre et des exercices plus libres.

Prenez le temps de réfléchir par vous même avant de répondre à une question. Le but n'est pas de trouver la bonne réponse, mais de comprendre et apprendre. Ne vous contentez pas de recopier les réponses de vos voisins.

Ces TP ne sont PAS notés. Les notes affichées par le logiciel ne comptent pas dans votre évaluation.

N'hésitez pas à appeler votre enseignant. Il est là pour vous aider.

Moodle permet à chacun d'évoluer à son propre rythme. Certains avanceront plus ou moins rapidement. Finissez chaque sujet avant de passer au suivant. Si vous sautez des questions, vous risquez de ne plus comprendre.

A gauche, en haut de la page vous trouverez un menu qui vous permet d’accéder aux différentes parties de chaque sujet.

Ces TP sont prévus pour Firefox sous Linux, pas pour Windows.

Bienvenue aux TP de JavaScript BUT S4

1.2 Aide mémoire

Ce sujet revoit les notions vues en S2.
L'aide mémoire du S2 se trouve ici:
https://moodle.iutv.univ-paris13.fr/mcustom/course-selected-pages.php?courseId=23

C'est une très bonne idée de le garder toujours ouvert dans un onglet. Vous en aurez souvent besoin!

2. Révisions HTML et CSS

2.1 Révisions HTML et CSS

Dans cette partie on va rapidement se rafraîchir la mémoire.

Révisions HTML et CSS

2.2 Rappel: HTML / Arbre

Le HTML est juste du texte. Le navigateur lit ce texte et le construit un arbre DOM.
En JS, on manipule cet arbre DOM.



Révisions HTML et CSS

2.3 Révision: arbre simple

Révision: arbre simple

http://moodle.iutv.univ-paris13.fr/img/web/webs1-cm-1-13-1.png

  <body>
    <p>
      Un exemple de page en html.<br/>
      <img src="photo.jpg" alt="photo"/>
    </p>
    <ul>
        <li>pomme</li>
        <li>fraise</li>
    </ul>
  </body>

Remarque: dans ces schémas, on ne tient pas compte du texte.

Révisions HTML et CSS

2.4 Révisions: Arbre d'un document complet

Révisions: Arbre d'un document complet

http://moodle.iutv.univ-paris13.fr/img/web/webs1-tp-1-14.png

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>Exemple</title>
  </head>
  <body>
    <h1>Bonjour!</h1>
  </body>
</html>
(<!DOCTYPE> n'est pas dans l'arbre)

Révisions HTML et CSS

2.5 Arbre vers HTML

Écrivez le HTML correspondant à cet arbre.
(n'oubliez pas de fermer les balises)

Révisions HTML et CSS

2.6 Rappel: "span" et "div"

Les balises <span> et <div> servent à regrouper du texte et des balises.
<span> est "inline" et <div> est "block" (on verra ces notions bientôt)
Pour simplifier:
<span> est utilisé lorsqu'on veut regrouper des petits bouts de texte (à l'intérieur d'une même ligne).
<div> est utilisé lorsqu'on veut regrouper de plus grands blocks, qui s'affichent sur plusieurs lignes.

Par exemple :

L'utilisateur <span class="utilisateur">Wang</span> est connecté depuis 3h.
<div id="presentation">
   <h2>Pingouins</h2>
   <p>Les pingouins cherchant leur nourriture dans les eaux maritimes et océaniques froides</p>
</div>

Révisions HTML et CSS

2.7 inline / block


Certains éléments HTML prennent au moins une ligne entière. On les appelle des éléments "block". Si vous mettez plusieurs éléments block d'affilé, ils seront  affichés sur des lignes différentes.

D'autres éléments HTML s'affichent à l'intérieur d'un ligne, de gauche à droite (inline), comme du texte.

Parmi les éléments suivants, lesquels prennent au moins toute une ligne (block) ?

Révisions HTML et CSS

2.8 Révision : span


HTML:

<p>
La souris se trouve à la position
x=<AAA class="coord">123</AAA>,
y=<AAA class="coord">432</AAA>
</p>


Dans cet exemple, quelle balise conviendrait le mieux, à la place de "AAA" ?

Révisions HTML et CSS

2.9 Rappel: sélecteurs CSS, attribut style

http://moodle.iutv.univ-paris13.fr/img/web/webs1-cm-1-17-1.png

js-cm-1-cm-update-552.png

On peut aussi spécifier directement du CSS à l’intérieur du HTML en utilisant l'attribut style:

<h1 style="background-color: blue">Bonjour!</h1>

Ceci n'est pas très utilisé quand on écrit du HTML, mais est très utilisé quand on manipule le DOM en JS.

r


Révisions HTML et CSS

2.10 Révision CSS

Révision CSS 

<p>
  <span id="velo">Vélo</span>,
  <span id="voiture">Voiture</span>,
  <span id="avion">Avion</span>
</p>
Que faut-il écrire dans le fichier CSS pour afficher "Voiture" en rouge ?
(réponse en une seule ligne)

Révisions HTML et CSS

2.11 Révision CSS

Révision CSS 
HTML:
<p>
  <span AAA="aliment">Chocolat</span>,
  <span AAA="vehicule">Vélo</span>,
  <span AAA="aliment">Fraise</span>,
  <span AAA="vehicule">Voiture</span>,
  <span AAA="vehicule">Avion</span>
  <span AAA="aliment">Poire</span>
</p>
CSS:
.aliment
{
color: red;
}

Que faut-il écrire à la place de "AAA" pour afficher "Chocolat" "Fraise" et "Poire" en rouge ?

Révisions HTML et CSS

2.12 Révision CSS

Révision CSS 

<h2>Choisir</h2>
<p>
  <span>Chocolat</span>, <span>Fraise</span>
</p>
Que faut-il écrire dans le fichier CSS pour afficher "Choisir" en rouge ?
(réponse en une seule ligne)

Révisions HTML et CSS

2.13 Révision CSS: sélecteur plus compliqué


<h2>Joueurs</h2>
<p id="gagnant">
  <span class="nom">Saidi</span>, <span class="prenom">Ahmed</span>
</p>
<p>
<span class="nom">Dubois</span>, <span class="prenom">Stéphane</span>
</p>
Que faut-il écrire dans le fichier CSS pour afficher "Saidi" en rouge ? (uniquement "Saidi")
(réponse en une seule ligne)

Révisions HTML et CSS

2.14 Révision CSS - inline

Révision CSS 

<h2>Ingrédients</h2>
<p>
  <span>Chocolat</span>, <span AAA>Fraise</span>
</p>
Que faut-il écrire à la place de "AAA" pour afficher "Fraise" en rouge ?
(réponse en une seule ligne)

3. Révisions JS

3.1 Révisions JS

Variables :

Les variables en JS ne sont pas déclarées avec un type. On utilise const, let et var pour les déclarer:

const a="bonjour";
let b=123;
var c=456;
Boucles:

Boucle numérique:

for(let i=0; i < 10 ; i++) {
...
}

Boucle tableau:

const joueurs=['Ahmed','Dubois', 'Chen' ];
for(let joueur of joueurs) {
console.log(joueur);
}
Portée

Les accolades { ... } définissent des blocs. La portée des variables s'étend aux sous-blocs.

function xyz() {
   let a=abc();
   if(a>5) {
let b=456;
      console.log(a); // OK
console.log(b); // OK
  }
console.log(b); // Erreur !
}

La portée des variables définies par let et const ne "monte" pas aux blocs contenants.
  

Révisions JS

3.2 Déclaration

Déclarez une variable appelée pi contenant le nombre 3.141592
La valeur de cette variable ne changera pas.

Révisions JS

3.3 Boucle for

Écrivez, en une seule ligne, une boucle for sur la variable n qui affiche dans la console les nombres de 18 à 35 (35 compris) .


Révisions JS

3.4 Portée

{
let x=1;
if(x>0){
let x=2;
}
console.log(x);
}

Qu'est-ce qui est affiché dans la console ?

Révisions JS

3.5 Fonctions

Les fonctions en JS ont des particularités très utilisées.

Fonction simple:

function exemple(x,y){
...
}

Fonctions anonymes:
Les fonctions en JS sont des objets qui peuvent être mis dans des variables ou passés à d'autres fonctions.
C'est très utilisé pour définir des actions qu'il faudra exécuter plus tard. Par exemple, on veut donner au navigateur une fonction qu'il faudra appeler, plus tard, quand l'utilisateur clique sur quelque-chose.

const f=function () { ... };
x.addEventListener('click',function(e){console.log('coucou',e);});

Les fonctions anonymes sont tellement utilisées, que le JS fournit un raccourci: Les fonctions fléchées.
(Elles ont aussi une gestion de "this" différente)

const f=()=>{...};
x.addEventListener('click',e=>console.log('coucou',e));

Révisions JS

3.6 Fonction simple

Écrivez, en une seule ligne, une fonction appelée « ok » qui ne prend pas de paramètres et qui affiche « ok » dans la console.
(n'utilisez pas de fonction anonyme)

Révisions JS

3.7 Fonction anonyme

let compteur=0;
document.querySelector('#augmenter').addEventListener('click',XYZ);

Quand l'utilisateur clique sur #augmenter, on veut augmenter compteur de 1.
Que faut-il écrire à la place de XYZ ?
N'utilisez pas de fonction fléchée.

Révisions JS

3.8 Fonction fléchée

Traduisez ceci en fonction fléchée

function(e){return e.target.id;}

(Rappel des règles simplification, plus de détails)

4. Révisions DOM

4.1 Révisions DOM

Voici les grandes lignes suivies par la plupart de nos programmes JS vus au S2:

1) Ils s’exécutent au chargement de la page pour:
a) chercher des éléments DOM (par exemple: document.querySelector)
b) enregistrer des fonctions ("gestionnaires d'événements") sur ces éléments DOM (par exemple: titre.addEventListener(...)).
Ces fonctions ne sont pas appelées tout de suite.
c) Notre programme a fini et rend la main au navigateur qui continue le chargement de la page.

2) Plus tard, l'utilisateur déclenche un événement (par exemple en cliquant) sur un élément (par exemple le <h1>)
La fonction enregistrée est appelée.
Elle modifie l'affichage en manipulant le DOM (par exemple paragraphe.style.color='green')

Exemple  complet:

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Exemple</title>
</head>
<body>
<h1>Cliquez-moi!</h1>
<p>Bonjour!</p>
<script>
let titre=document.querySelector('h1');
titre.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
let paragraphe=document.querySelector('p');
paragraphe.style.color='green';
}
</script>
</body>
</html>
(plus de détails)

Révisions DOM

4.2 Chercher élément

Que faut-il écrire à la place de XYZ pour créer une variable "abc" et y mettre une référence vers le paragraphe "Bonjour!" ?

	<body>
<p>Bienvenue</p>
<p class="b">Bonjour!</p>
<p>Au revoir!</p>
<script>
XYZ;
</script>
</body>

Révisions DOM

4.3 Gestionnaire d'événements

Que faut-il écrire à la place de XYZ pour qu'une fonction appelée « exemple » soit appelée lorsque l'utilisateur clique sur "Bonjour!".
(Utilisez la variable abc)

	<body>
<p>Bienvenue</p>
<p class="b">Bonjour!</p>
<p>Au revoir!</p>
<script>
const abc=document.querySelector('.b');
XYZ;
function exemple()
{
console.log('Ca marche!');
}
</script>
</body>

5. Jeu poissons: 1ère partie

5.1 Jeu poissons: 1ère partie

On va écrire un petit programme JS pour faire un jeu où un pingouin mange des poissons.

Créez un répertoire (attention à ce qu'il ne soit pas perdu à la fin de la séance!).

Images

Enregistrez les images suivantes
pingouin.svg
poisson.svg

eau.svg

Fichiers

Créez les fichiers suivants:
jeu.html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Jeu poissons</title>
<link rel="stylesheet" href="jeu.css"/>
</head>
<body>
<h1>Jeu poissons</h1>
<script src="jeu.js"></script>
</body>
</html>
jeu.css
/* vide pour l'instant */
jeu.js
// vide pour l'instant





Jeu poissons: 1ère partie

5.2 Eau

Jeu poissons: 1ère partie

5.3 Correction

jeu.html

		<h1>Jeu poissons</h1>
<div id="eau">
</div>

<script src="jeu2.js"></script>

jeu.css

#eau {
position: relative;
width: 800px;
height: 450px;
background-image: url(eau.svg);

overflow: hidden;
}

Jeu poissons: 1ère partie

5.4 Pingouin

Dans le HTML, ajoutez l'image pingouin.svg à l'intérieur du <div id="eau"> et donnez lui le id "pingouin".

Jeu poissons: 1ère partie

5.5 top

Dans le CSS, ajoutez:

#pingouin {
  top: 20px;
}

Normalement, ça ne marche pas.
Que faut-il ajouter pour que "top: 20px" puisse fonctionner ?

Jeu poissons: 1ère partie

5.6 Clavier

On voudrait déplacer le pingouin avec le clavier.
Pour ça, on doit enregistrer une fonction que le navigateur appellera plus tard quand une touche sera appuyée. Cette fonction, qu'on va écrire, est appelée "gestionnaire d'événements".
Habituellement, on enregistre cette fonction sur un élément précis, mais, ici, on veut obtenir les événements clavier où qu'ils surviennent sur la page. On va donc écouter directement sur "document", l'objet qui se trouve tout en haut de l'arbre DOM. Les événements y remontent par bubbling.

Écrivez le code nécessaire pour faire en sorte que "Touche appuyée" soit affiché sur la console chaque fois l'utilisateur enfonce une touche, où que ce soit sur la page.
Indications:

Jeu poissons: 1ère partie

5.7 Touches

document.addEventListener('keydown',function(){console.log('Touche appuyée')})

On voudrait changer la position du pingouin quand l'utilisateur appuie sur les flèches.
La fonction anonyme ci-dessus est appelée par le navigateur quelque soit la touche enfoncée.
Le navigateur l'appelle avec un paramètre. On le nomme souvent "event".
event.code va nous indiquer quelle touche a été enfoncée.

Dans jeu.js, affichez event.code dans la console et regardez le résultat.
En regardant la console, que vaut event.code quand l'utilisateur appuie sur la flèche vers le bas ?

Jeu poissons: 1ère partie

5.8 Position du pingouin

Position du pingouin


On va gérer la propriété CSS "top", dans le DOM, plutôt que dans le fichier CSS.
Dans le CSS enlevez "top: 20px" au pingouin et ajoutez style="top: 0px" dans le HTML:

            <img id="pingouin" style="top: 0px" src="pingouin.svg"/>

En début de votre programme JS, ajoutez les lignes suivantes.

const pingouin =document.getElementById('pingouin');
const eau =document.getElementById('eau' );

Elles permettront d’accéder simplement à "pingouin" et "eau".

La variable "pingouin" contient un élément DOM. Il permet d’accéder à la propriété style, qui elle même a une propriété top:

pingouin.style.top
Faites monter et descendre le pingouin quand l'utilisateur appuie sur les flèches vers le haut et vers le bas.
Conseils:
Écrivez le code, vérifiez qu'il fonctionne dans votre navigateur, puis copiez-le ici pour que votre enseignant puisse le relire plus tard:

Jeu poissons: 1ère partie

5.9 Correction

const pingouin =document.getElementById('pingouin');
const eau =document.getElementById('eau' );

document.addEventListener('keydown',function(event){
console.log('Touche appuyée',event.code);
console.log('pingouin.style.top:',pingouin.style.top);
let top=parseInt(pingouin.style.top);
if(event.code ==="ArrowUp" ){top-=30;}
if(event.code ==="ArrowDown"){top+=30;}
pingouin.style.top=top+'px';
});

Jeu poissons: 1ère partie

5.10 Limites mouvement pingouin

Limites mouvement pingouin

Faites en sorte que le le pingouin ne puisse pas dépasser le haut, ni le bas.
Tenez compte du fait que l'eau fait 450px de haut et le pingouin fait 60px de haut.

Dans le CSS, pour rendre le mouvement plus fluide, ajoutez au pingouin:

    transition: top 1s;

Écrivez le code, vérifiez qu'il fonctionne dans votre navigateur, puis copiez-le ici pour que votre enseignant puisse le relire plus tard:

Jeu poissons: 1ère partie

5.11 Correction

const pingouin =document.getElementById('pingouin');
const eau =document.getElementById('eau' );

document.addEventListener('keydown',function(event){
let top=parseInt(pingouin.style.top);
if(event.code ==="ArrowUp" ){top-=30;}
if(event.code ==="ArrowDown"){top+=30;}
if(top<0 ){top=0;}
if(top>450-60){top=450-60;}

pingouin.style.top=top+'px';
});

6. Jeu poissons: 2e partie

6.1 Jeu poissons: 2e partie


Notre pauvre pingouin nage tout seul ... et a faim!

On veut ajouter un poisson qui défile de droite à gauche. Le poisson est une image.
Pour ça, il faudra:

  1. créer l'image en JS (pas en HTML) et l’insérer dans le document
  2. la positionner à droite de l'eau
  3. la faire défiler vers la gauche
Commençons par 1.
Lisez ce rappel sur la création d'éléments


Jeu poissons: 2e partie

6.2 Créer l'image

Que faut-il écrire pour créer, en JS, une image et la mettre dans une variable appelée "poisson" ?
(Pour l'instant on ne l'insère pas encore dans le document)

Jeu poissons: 2e partie

6.3 Fichier image

const poisson=document.createElement('img')

Dans "poisson" on a un objet DOM img, mais on n'a pas encore spécifié de fichier.
Comment indiquer qu'on veut utiliser poisson.svg ?

Jeu poissons: 2e partie

6.4 Insérer le poisson

const poisson=document.createElement('img');
poisson.src='poisson.svg';
Pour l'instant le poisson est hors de l'eau. Il n'aime pas ça.
Que faut-il écrire pour insérer le poisson dans l'élément ayant pour id "eau" ?
Utilisez la variable "eau" qu'on a déjà définie.
Essayez dans jeu.js avant de répondre ici.

Jeu poissons: 2e partie

6.5 class="poisson"

On veut ajouter la classe "poisson" au poisson. Utilisez la propriété className.

Jeu poissons: 2e partie

6.6 Correction

Pour l'instant votre code JS doit ressembler à ceci:

const pingouin =document.getElementById('pingouin');
const eau =document.getElementById('eau' );

document.addEventListener('keydown',function(event){
// La position verticale du haut du pingouin.
// On utilisez parseInt pour passer de la chaîne "123px" au nombre 123.
let top=parseInt(pingouin.style.top);
if(event.code ==="ArrowUp" ){top-=30;}
if(event.code ==="ArrowDown"){top+=30;}
// Éviter que le pingouin ne sorte de l'eau
if(top<0 ){top=0;}
if(top>450-60){top=450-60;}
// Mettre à jour la position
pingouin.style.top=top+'px';
});

// Création d'une image. Elle n'est pas encore dans l'arbre DOM.
const poisson=document.createElement('img');
poisson.src='poisson.svg';
poisson.className='poisson';
// On insère l'image dans l'arbre DOM, dans l'élément eau (c'est ce que les poissons aiment).
eau.append(poisson);
Vous devriez voir un poisson  affiché en haut à gauche de l'eau.

Jeu poissons: 2e partie

6.7 CSS poisson

En vous inspirant de ce qui a été fait pour le pingouin, placez le poisson en haut à droite de l'eau.
Remarquez que le poisson à la class "poisson". En effet, plus tard, on ajoutera d'autres poissons.
L'eau fait 800px de large et le poisson 40px.
Utilisez la propriété CSS left et pas la propriété right.

Jeu poissons: 2e partie

6.8 Correction CSS poisson

.poisson {
position: absolute;
left: 760px;
}

Jeu poissons: 2e partie

6.9 Défilement poisson : transitions CSS

On voudrait animer la propriété "left", pour que le poisson défile de la droite vers la gauche.

Les transitions CSS permettent de dire qu'un changement doit être fait lentement.
Normalement, si on fait:

poisson.style.left='0px';

le poisson se colle à gauche de l'eau immédiatement.
Avec une transition, on peux dire que le passage de "left: 760px" à "left: 0px" doit se faire en 2 secondes.

Ajoutez donc les deux lignes suivantes :

    transition: left 2s;
    transition-timing-function: linear;

(explication transitions)

Maintenant, dans votre code JS. Ajoutez les lignes suivantes:

window.getComputedStyle(poisson).top;
poisson.style.left=0;

L'utilité de la première ligne est un peu compliquée à comprendre. En gros, elle force le navigateur à prendre en compte la position actuelle (left: 760px), avant de changer à "left: 0px". Ceci lui permet de voir qu'il faut déclencher la transition.

Recopiez ce code et vérifiez que le poisson défile bien.

Jeu poissons: 2e partie

6.10 Plus de poissons

Plus de poissons

Le pingouin a faim. Il va lui falloir plus de poissons.

Avec la fonction window.setInterval, on peut appeler une fonction toutes les 500 millisecondes:

window.setInterval(function(){
    console.log('Coucou',Date.now());
},500);

Essayez ce code.
En vous en inspirant, créez un poisson qui défile toutes les 500 ms.


Écrivez le code, vérifiez qu'il fonctionne dans votre navigateur, puis copiez-le ici pour que votre enseignant puisse le relire plus tard:

Jeu poissons: 2e partie

6.11 Correction: plusieurs poissons

 
window.setInterval(function(){
const poisson=document.createElement('img');
poisson.src='poisson.svg';
poisson.className='poisson';
eau.append(poisson);
window.getComputedStyle(poisson).top;
poisson.style.left=0;
},500);


Jeu poissons: 2e partie

6.12 Position aléatoire

Position aléatoire

Les poissons sont tous crées en haut.
La fonction Math.random() fournit un nombre aléatoire entre 0 et 1.
L'eau fait 450px de haut et le poisson en fait 18.
Faites en sorte que le poisson apparaisse à une hauteur aléatoire.

Écrivez le code, vérifiez qu'il fonctionne dans votre navigateur, puis copiez-le ici pour que votre enseignant puisse le relire plus tard:


Jeu poissons: 2e partie

6.13 Correction position aléatoire


window.setInterval(function(){
const poisson=document.createElement('img');
poisson.src='poisson.svg';
poisson.className='poisson';
eau.append(poisson);
poisson.style.top=(Math.random()*(450-18))+'px';
window.getComputedStyle(poisson).top;
poisson.style.left=0;
},500);


Jeu poissons: 2e partie

6.14 Suppression du poisson

Suppression du poisson

Quand le poisson arrive à gauche de l'eau, il y reste.
On voudrait le supprimer.
On sait que le défilement (la transition) dure deux secondes.
On doit donc supprimer le poisson deux secondes après sa création.
La fonction window.setTimeout permet d’exécuter une fonction dans n millisecondes.

Pour supprimer un élément il suffit d'utiliser .remove() :

poisson.remove();

Faites en sorte que les poissons soient supprimés.

Écrivez le code, vérifiez qu'il fonctionne dans votre navigateur, puis copiez-le ici pour que votre enseignant puisse le relire plus tard:

Jeu poissons: 2e partie

6.15 Correction

window.setInterval(function(){
const poisson=document.createElement('img');
poisson.src='poisson.svg';
poisson.className='poisson';
eau.append(poisson);
poisson.style.top=(Math.random()*(450-18))+'px';
window.getComputedStyle(poisson).top;
poisson.style.left=0;
window.setTimeout(function(){
poisson.remove();
},2000);

},500);

7. Jeu poissons: 3e partie

7.1 Jeu poissons: 3e partie

Le pingouin ne peut pas encore manger. Il a toujours faim !

Dans le HTML, ajoutez un affichage du score:

		<p>Score:<span id="score">-</span>

Vers le haut du fichier JS créez:

let score=0;

La variable "score" permettra de compter les poissons mangés.

Jeu poissons: 3e partie

7.2 Collision pingouin poisson

Collision pingouin poisson

On va déterminer si le pingouin touche le poisson, quand le poisson arrive à gauche de l'eau.
La fonction getBoundingClientRect() permet de connaître le rectangle qu'occupent le poisson et le pingouin.

    const rectPingouin=pingouin.getBoundingClientRect();
const rectPoisson =poisson.getBoundingClientRect();

Ces rectangles ont des propriétés top et bottom. A l'aide de top et bottom, affichez "miam" dans la console, quand le pingouin touche un poisson.

Écrivez le code, vérifiez qu'il fonctionne dans votre navigateur, puis copiez-le ici pour que votre enseignant puisse le relire plus tard:

Jeu poissons: 3e partie

7.3 Correction collision

window.setInterval(function(){
console.log('Création poisson');
const poisson=document.createElement('img');
poisson.src='poisson.svg';
poisson.className='poisson';
eau.append(poisson);
poisson.style.top=(Math.random()*(450-18))+'px';
window.getComputedStyle(poisson).top;
poisson.style.left=0;
window.setTimeout(function(){
const rectPingouin=pingouin.getBoundingClientRect();
const rectPoisson =poisson.getBoundingClientRect();
if(rectPingouin.bottom>rectPoisson.top && rectPingouin.top<rectPoisson.bottom)
{
console.log('miam');
}
poisson.remove();
},2000);
},500);

Jeu poissons: 3e partie

7.4 Afficher le score

Quand le pingouin a touché le poisson on peut augmenter le score:

score++;

Ensuite, on veut l'afficher. Que faut-il écrire pour afficher score dans le span prévu ?
Essayez dans votre code avant de répondre.

(n'utilisez pas de variable intermédiaire)

Jeu poissons: 3e partie

7.5 Améliorations

L'animation est n'est pas fluide parce que le poisson apparaît dans eau entièrement visible et qu'il disparaît alors qu'il est entièrement visible.

Faites en sorte que le poisson

Rappel: l'eau fait 450px de large et le poisson 40px

Jeu poissons: 3e partie

7.6 Correction

JS

window.setInterval(function(){
console.log('Création poisson');
const poisson=document.createElement('img');
poisson.src='poisson.svg';
poisson.className='poisson';
eau.append(poisson);
poisson.style.top=(Math.random()*(450-18))+'px';
window.getComputedStyle(poisson).top;
poisson.style.left='-40px';
window.setTimeout(function(){
const rectPingouin=pingouin.getBoundingClientRect();
const rectPoisson =poisson.getBoundingClientRect();
if(rectPingouin.bottom>rectPoisson.top && rectPingouin.top<rectPoisson.bottom)
{
console.log('miam');
score++;
document.getElementById('score').textContent=score;
}
poisson.remove();
},2000);
},500);

CSS

.poisson {
position: absolute;
left: 840px;
transition: left 2s;
transition-timing-function: linear;
}

Jeu poissons: 3e partie

7.7 Collision / Fin d'animation


Collision / Fin d'animation

On supprime le poisson au bout de 2 secondes.
Avec nos changements, à 2 secondes, le poisson se trouve derrière les pieds du pingouin.
Un pingouin mange avec son bec ... pas avec ses pieds !
Le poisson se trouve près du bec vers 1650 millisecondes.

On doit donc utiliser deux window.setTimeout différents.

Séparez en deux.
Supprimez aussi le poisson si le pingouin l'attrape.

Écrivez le code, vérifiez qu'il fonctionne dans votre navigateur, puis copiez-le ici pour que votre enseignant puisse le relire plus tard:

Jeu poissons: 3e partie

7.8 Correction

const pingouin=document.getElementById('pingouin');
const eau =document.getElementById('eau' );

let score=0;

document.addEventListener('keydown',function(event){
let top=parseInt(pingouin.style.top);
if(event.code ==="ArrowUp" ){top-=30;}
if(event.code ==="ArrowDown"){top+=30;}
if(top<0 ){top=0;}
if(top>450-60){top=450-60;}
pingouin.style.top=top+'px';
});

window.setInterval(function(){
console.log('Création poisson');
const poisson=document.createElement('img');
poisson.src='poisson.svg';
poisson.className='poisson';
eau.append(poisson);
poisson.style.top=(Math.random()*(450-18))+'px';
poisson.style.left='840px';
window.getComputedStyle(poisson).top;
poisson.style.left='-40px';
// On sait que le poisson atteindra la gauche de l'écran dans 2 secondes.
window.setTimeout(function(){
poisson.remove();
},2000);
// On sait que le poisson atteindra le bec du pingouin dans 1650 millisecondes.
window.setTimeout(function(){
// Voir si le pingouin touche le poisson.
const rectPingouin=pingouin.getBoundingClientRect();
const rectPoisson =poisson.getBoundingClientRect();
// Si oui, on augmente le score.
if(rectPingouin.bottom>rectPoisson.top && rectPingouin.top<rectPoisson.bottom)
{
score++;
document.getElementById('score').textContent=score;
poisson.remove();
}
},1650);
},500);


Jeu poissons: 3e partie

7.9 Le phoque

Comme vous pouvez le voir, le phoque est un terrifiant prédateur du pingouin.

Créez le fichier phoque.svg

En vous inspirant de ce qui est fait pour les poissons, créez, toutes les 4 secondes un phoque qui défile de droite à gauche en 2s.
Le phoque est gros (et a faim aussi) ... il fait 121 px de large et 117 px de haut.

Si le phoque touche le pingouin affichez:

      alert('Mangé par le phoque!');


Jeu poissons: 3e partie

7.10 Correction: fin

jeu.js (commenté)

const pingouin=document.getElementById('pingouin');
const eau =document.getElementById('eau' );

let score=0;

// Réagir quand l'utilisateur appuie sur une touche.
// Tous les évènements remontent (bubbling) jusqu'à document.
// Donc, quand on veut attraper un événement où qu'il survienne sur la page, on peut écouter sur document.
document.addEventListener('keydown',function(event){
// La position verticale du haut du pingouin.
// On utilisez parseInt pour passer de la chaîne "123px" au nombre 123.
let top=parseInt(pingouin.style.top);
if(event.code ==="ArrowUp" ){top-=30;}
if(event.code ==="ArrowDown"){top+=30;}
// Éviter que le pingouin ne sorte de l'eau
if(top<0 ){top=0;}
if(top>450-60){top=450-60;}
// Mettre à jour la position
pingouin.style.top=top+'px';
});

// On crée un poisson à intervalles réguliers. C'est à dire tous les ? millisecondes.
window.setInterval(function(){
console.log('Création poisson');
// Création d'une image. Elle n'est pas encore dans l'arbre DOM.
const poisson=document.createElement('img');
poisson.src='poisson.svg';
poisson.className='poisson';
// On insère l'image dans l'arbre DOM, dans l'élément eau (c'est que les poissons aiment).
eau.append(poisson);
// Position verticale aléatoire. L'eau fait 450 px de haut, et le poisson 18px.
poisson.style.top=(Math.random()*(450-18))+'px';
poisson.style.left='840px';
// Compliqué. On demande au navigateur de prendre en compte la situation actuelle.
// Ceci va permettre de déclencher l'animation du poisson à la ligne suivante (transition CSS).
window.getComputedStyle(poisson).top;
// Ceci ne se fait pas immédiatement. La transition CSS dit que ca se fera en 2 secondes.
// C'est ce qui crée le défilement du poisson.
poisson.style.left='-40px';
// On sait que le poisson atteindra la gauche de l'écran dans 2 secondes.
// On utilise setTimeout pour exécuter la fonction dans 2000 millisecondes (2 secondes).
window.setTimeout(function(){
// On fait disparaître le poisson en l'enlevant de l'arbre DOM.
poisson.remove();
},2000);
// On sait que le poisson atteindra le bec du pingouin dans 1650 millisecondes.
window.setTimeout(function(){
// Voir si le pingouin touche le poisson.
const rectPingouin=pingouin.getBoundingClientRect();
const rectPoisson =poisson.getBoundingClientRect();
// Si oui, on augmente le score.
if(rectPingouin.bottom>rectPoisson.top && rectPingouin.top<rectPoisson.bottom)
{
score++;
document.getElementById('score').textContent=score;
// On fait disparaître le poisson en l'enlevant de l'arbre DOM.
poisson.remove();
}
},1650);
},500);


// On crée un phoque à intervalles réguliers.
window.setInterval(function(){
console.log('Création phoque');
const phoque=document.createElement('img');
phoque.src='phoque.svg';
phoque.className='phoque';
eau.append(phoque);
// Position verticale aléatoire. L'eau fait 450 px de haut, et le phoque 117px.
phoque.style.top=(Math.random()*(450-117))+'px';
phoque.style.left='920px';
// Compliqué. On demande au navigateur de prendre en compte la situation actuelle.
// Ceci va permettre de déclencher l'animation du phoque à la ligne suivante (transition CSS).
window.getComputedStyle(phoque).top;
// Ceci ne se fait pas immédiatement. La transition CSS dit que ca se fera en 2 secondes.
// C'est ce qui crée le défilement du phoque.
phoque.style.left='-120px';
// On sait que le phoque atteindra la gauche de l'écran dans 2 secondes.
// On utilise setTimeout pour exécuter la fonction dans 2000 millisecondes (2 secondes).
window.setTimeout(function(){
// On fait disparaître le phoque en l'enlevant de l'arbre DOM.
phoque.remove();
},2000);
// On sait que le phoque atteindra le bec du pingouin dans 1625 millisecondes.
window.setTimeout(function(){
// Voir si le pingouin touche le phoque.
const rectPingouin=pingouin.getBoundingClientRect();
const rectPhoque =phoque.getBoundingClientRect();
// Si oui, on perd
if(rectPingouin.bottom>rectPhoque.top && rectPingouin.top<rectPhoque.bottom)
{
alert('Mangé par le phoque!');
}
},1625);
},4000);

jeu.css

#eau {
position: relative;
width: 800px;
height: 450px;
background-image: url(eau.svg);
overflow: hidden;
}

#pingouin {
position: absolute;
z-index: 10;
transition: top 1s;
}

.poisson {
position: absolute;
left: 840px;
transition: left 2s;
transition-timing-function: linear;
}

.phoque {
position: absolute;
left: 780px;
transition: left 2s;
transition-timing-function: linear;
}