Technologies avancées du eLearning 2/exercices/Score basketball
De GBLL, TAL, ALAO, etc.
< Cours:Technologies avancées du eLearning 2
Dans cet exercice, on veut créer une interface pour faire l'affichage des scores d'un match de basket.
Spécifications
Pour gérer le match de basket, on va créer 2 classes :
Ces deux classes vont permettre d'associer un nom à chaque équipe et d'avoir une liste de boutons pour chaque équipe pour chaque point qu'elles marquent. Il peut s'agir :
- d'un lancer franc : 1 point ;
- d'un panier normal : 2 points ;
- d'un panier à 3 points : 3 points.
À chaque fois qu'une équipe marque un panier, il faudra mettre à jour le score du match.
Une statistique utilisée est le nombre de « changements d'avantage » ou lead changes. Le premier panier du match ne compte pas comme un lead changes. Sinon, à chaque fois qu'une équipe qui ne menait pas au score marque et prend l'avantage, on considère qu'il y a un lead change.
Code
code de départ à modifier pour satisfaire les spécifications
- Questions subsidiaires (ne faisant pas partie de l'exercice) :
- Comment changerait-on le nom des équipes ?
- Comment changerait-on leur couleur ?
Fichier html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="classes.js"></script>
<link type="text/css" rel="stylesheet" href="style.css" />
<script type="text/javascript">
function init(){
var match = new Match(new Equipe("team1", "La première équipe"),
new Equipe("team2", "La seconde équipe"));
}
window.onload = init;
</script>
</head>
<body>
<main><article id="team1">
<h1>Nom Équipe 1</h1>
<menu><table><tr><td class="ft">LF</td><td class="two">2pts</td><td class="three">3pts</td></tr></table></menu>
<div class="score">79</div>
</article><!--
--><article id="team2">
<h1>Nom Équipe 2</h1>
<menu><table><tr><td class="ft">LF</td><td class="two">2pts</td><td class="three">3pts</td></tr></table></menu>
<div class="score">77</div>
</article></main>
<article id="vainqueur"><menu>Vainqueur</menu>
<p></p>
</article>
</body>
</html>
JavaScript à modifier
class Equipe{
constructor(id, nom){
this.elt = document.getElementById(id) ;
this.nom = nom;
this.elt.querySelector("h1").innerHTML = this.nom ;
this.score = 0;
this.scoreElt = this.elt.querySelector(".score");
this.displayScore();
}
returnElt(){
return this.elt;
}
displayScore(){
//affiche le score dans l'élément contenu dans l'attribut scoreElt
}
getScore(){
//renvoie le score
}
getNom(){
//renvoie le nom de l'équipe
}
addShot(type){
//si type est "FT" (lancé franc), ajouter 1 point au score
//si type est "2pts", ajouter 2 points au score
//si type est "3pts", ajouter 3 points au score
}
}
class Match{
constructor(equipe1, equipe2){
//À modifier, pour que l'équipe qui est devant soit automatiquement mise à jour à chaque fois qu'on ajoute des points à une équipe.
this.equipes = [equipe1, equipe2];
//pour la déclaration des “listeners” la liste des paramètres de la fonction addShot et la liste des classes des éléments qui vont appeler la fonction
var shots = ["FT", "2pts", "3pts"] ;
var eltClasses = [".ft", ".two", ".three"] ;
//Dans les fonctions déclenchées par les fonctions déclarées ci-dessous (qui ne sont pas des méthodes des objets en question), this se référera à l'objet DOM qui aura déclenché l'événement click.
//pour éviter l'erreur qui se produirait, on stocke le présent objet temporairement dans une variable et on utilise celle-ci au sein de la fonction.
let self = this;
//création des fonctions et des listeners associés
for(let i=0;i<shots.length;i++){
for(let j=0; j<this.equipes.length; j++){
//déclaration d'une fonction associée à l'événement “onclick” pour chaque bouton du tableau de chaque équipe
this.equipes[j].returnElt().querySelector(eltClasses[i]).onclick = function(){self.equipes[j].addShot(shots[i]);};
}
}
//attribut où on va stocker l'élément qui contiendra le nom de l'équipe qui mène
this.vainqueurElt = document.getElementById("vainqueur").querySelector("p");
//déclaration du listener pour le bouton qui doit afficher l'équipe qui mène.
document.getElementById("vainqueur").querySelector("menu").onclick = function(){self.showVainqueur();};
}
showVainqueur(){
//détecte l'équipe qui est devant et affiche le nom de son équipe dans l'élément contenu dans l'attribut vainqueurElt
}
leadChanges(){
//renvoie le nombre de “lead changes” dans le match.
//Une fois que le premier point (panier ou lancer franc) a été marqué on considère qu'un “lead change” se produit à chaque fois qu'une équipe marque et passe devant l'autre (que le score ait été équitable ou en faveur de l'autre équipe juste avant.)
}
}
Voir une correction
1 class Equipe{
2 constructor(id, nom){
3 this.elt = document.getElementById(id) ;
4 this.nom = nom;
5 this.elt.querySelector("h1").innerHTML = this.nom ;
6 this.score = 0;
7 this.scoreElt = this.elt.querySelector(".score");
8 this.displayScore();
9 }
10
11 returnElt(){
12 return this.elt;
13 }
14
15 displayScore(){
16 this.scoreElt.innerHTML = this.score;
17 }
18
19 getScore(){
20 return this.score;
21 }
22
23 getNom(){
24 return this.nom;
25 }
26
27 addShot(type){
28 if(type=="FT"){
29 this.score += 1;
30 }
31 else if(type=="2pts"){
32 this.score += 2;
33 }
34 else if(type=="3pts"){
35 this.score += 3;
36 }
37 else{
38 console.error("Basket type error : " + type);
39 }
40 this.displayScore();
41 }
42 }
43
44 class Match{
45 constructor(equipe1, equipe2){
46 this.equipes = [equipe1, equipe2];
47 this.leader = false;
48 this.leadChanges = 0;
49 var shots = ["FT", "2pts", "3pts"] ;
50 var eltClasses = [".ft", ".two", ".three"] ;
51 //Dans les fonctions déclenchées par les fonctions ci-dessous (qui ne sont pas des méthodes des objets en question), this se référera à l'objet DOM qui aura déclenché l'événement click.
52 //pour éviter l'erreur qui se produirait, on stocke le présent objet temporairement dans une variable et on utilise celle-ci au sein de la fonction.
53 let self = this;
54
55 for(let i=0;i<shots.length;i++){
56 for(let j=0; j<this.equipes.length; j++){
57 this.equipes[j].returnElt().querySelector(eltClasses[i]).onclick = function(){
58 self.equipes[j].addShot(shots[i]);
59 self.showVainqueur();
60 };
61 }
62 }
63 this.vainqueurElt = document.getElementById("vainqueur").querySelector("p");
64
65 document.getElementById("vainqueur").querySelector("menu").onclick = function(){self.showVainqueur();};
66 }
67
68 showVainqueur(){
69 if(this.equipes[0].getScore() > this.equipes[1].getScore()){
70 if((this.leader !== 0) && (this.leader !== false)){
71 this.leadChanges++ ;
72 }
73 this.leader = 0;
74 this.vainqueurElt.innerHTML = this.equipes[0].getNom()+
75 "<br /><emph>" + this.leadChanges + "</emph> <i>lead changes</i>";
76 }
77 else if(this.equipes[0].getScore() < this.equipes[1].getScore()){
78 if((this.leader !== 1) && (this.leader !== false)){
79 this.leadChanges++ ;
80 }
81 this.leader = 1;
82 this.vainqueurElt.innerHTML = this.equipes[1].getNom()+
83 "<br /><emph>" + this.leadChanges + "</emph> <i>lead changes</i>";
84 }
85 else{
86 this.vainqueurElt.innerHTML = "Match nul"+
87 "<br /><emph>" + this.leadChanges + "</emph> <i>lead changes</i>";
88 this.leader = -1;
89 }
90 }
91
92 leadChanges(){
93 return this.leadChanges;
94 }
95 }
Feuille de style
body{
margin:0;
padding:0;
}
main{
position:relative;
background-color: lightgrey;
margin-right:auto;
margin-left:auto;
padding:1em;
}
[id^=team]{
display: inline-block;
width:50%;
margin:0;
padding:1em;
position:relative;
text-align: center;
box-sizing: border-box;
}
#team1{
color:blue;
}
#team2{
color:red;
}
[id^=team] .score{
position:absolute;
font-size:25px;
font-weight:bold;
text-align:center;
line-height: 50px;
height:50px;
width:100px;
top:0;
color:white;
}
#team1 .score{
right:2em;
background-color:blue;
}
#team2 .score{
left:2em;
background-color:red;
}
table{
margin-left: auto;
margin-right: auto;
}
#team1 td{
background-color:blue;
}
#team2 td{
background-color:red;
}
[id^=team] td{
width:50px;
text-align:center;
font-weight:bold;
color:white;
}
td:active, #vainqueur menu:active {
filter: invert(100%);
}
menu{
cursor:pointer;
padding:0;
}
#vainqueur{
font-weight: bold;
padding:0;
text-align:center;
}
#vainqueur menu{
background-color:darkgrey;
color:white;
padding:1em;
width:250px;
margin-left:auto;
margin-right:auto;
}