تبسيط البرمجة ب JavaScript باستخدام jQuery


الدرس: TP: لعبة جمع الفضاء


الصفحة السابقة
لإنهاء هذا الجزء ، أقترح إنشاء لعبة في jQuery . مهمتك ، إذا وافقت ، ستكون نقل سفينة الفضاء إلى اللوحة الرقمية وجمع العناصر التي تظهر بشكل عشوائي على الشاشة. ولكن حذار ، هناك نوعان من العناصر: العناصر الجيدة (الأبقار) والعناصر السيئة ( Men In Black cars ) . السابق يضيف 5 نقاط إلى درجاتك ، في حين أن الأخير يزيل 5 نقاط.

تعليمات لتنفيذ TP


قبل البداية ، أقترح عليك أن تنظر إلى الشكل التالي لترى كيف ستبدو اللعبة.
jQuery web
تقوم مفاتيح الأسهم الثمانية الموجودة على لوحة المفاتيح الرقمية بتوجيه الصحن الطائر . وسترى أنها ليست ترفًا: حيث يتم لعب اللعبة بسرعة كبيرة والإزاحة القطرية تعد إضافة حقيقية.
لجعلك تفكر أكثر من ذلك بقليل ، أطلب منك إضافة موسيقى خلفية إلى اللعبة ، وستبدأ في بداية الصفحة وتنتهي إلى ما لا نهاية. يمكنك استخدام أي موسيقى بتنسيقات MP3 و OGG . من جهتي ، استخدمت الموسيقى التي تم تنزيلها مجانًا BabyPleaseDontGo.mp3 .
يجب أن تكون قادرًا على كتابة جميع الكود دون أي نصيحة مني. ومع ذلك ، سأزودك بالملفات التي ستحتاج إليها ، وسأقدم لك ، في عبارتين ، نصيحتين أو ثلاث نصائح تساعدك على البدء.
فيما يلي الموارد المستخدمة في هذه اللعبة:
jQuery web
fond.png : 600 × 400 pixels
jQuery web
soucoupe.png : 125 × 177 pixels
jQuery web
bon.png : 50 × 116 pixels
jQuery web
mauvais.png : 56 × 113 pixels
يعرض الجدول التالي رموز ASCII لمفاتيح لوحة المفاتيح. سيكون مفيدًا عند كتابة إجراء الحدث keydown() :
مفتاح كود ASCII
اليمين 39
اليسار 37
الاسفل 40
الأعلى 38
قطري العلوي واليسار 36
قطريا صعودا واليمين 33
أسفل قطري واليسار 35
أسفل قطري واليمين 34
في الفصل السابق ، تعلمت تشغيل صوت عند حدوث تصادم. لتشغيل الموسيقى الخلفية ، ستستخدم نفس المبدأ ، ولكن هنا ستقوم بتنشيط الموسيقى بمجرد فتح الصفحة عن طريق تعيين القيمة autoplay إلى سمة autoplay للعلامة <audio> . وبالمثل ، ستقوم بتعيين القيمة loop إلى سمة loop للعلامة <audio> للموسيقى لتكرارها بنفسها:

<audio preload="auto" id="musiqueFond" autoplay="autoplay" loop="loop">
  <source src="BabyPleaseDontGo.mp3" type="audio/mp3">
  <source src="BabyPleaseDontGo.mp3" type="audio/ogg">
</audio>
والآن ، الكرة في معسكرك. في لوحات المفاتيح الخاصة بك ، والمتعة!

الاصلاح


آمل أن كل شيء سار على ما يرام. لتسهيل التصحيح ، سنمضي في خطوات متتالية. تأكد من اجتياز كل خطوة بنجاح ، وإذا كنت في شك ، فقم بمقارنة كود الاصلاح بالكود الخاص بك. كما هو الحال دائمًا في البرمجة ، لا يوجد حل ولكن هناك العديد من الحلول التي تؤدي إلى العديد من الاكواد ، وأحيانًا تكون مختلفة جدًا. إذا كان الكود الخاص بك لا يشبه للحل الذي قدمته لك ولكنه يعمل ، فلا يهم. هذا يعني ببساطة أنك ذهبت في اتجاه آخر. ما يهم أكثر هو أنه يعمل.
بنية HTML وتنسيق CSS
الخطوة الأولى هي إعداد إطار HTML للوثيقة. هنا هو الرمز الذي استخدمته:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>jeu</title>
  <style type="text/css">
    #jeu
    {
      width: 600px;
      height: 400px;
      border: 2px black solid;
      background: url('fond.png');
    }
    #soucoupe{
      z-index: 200; 
      position: absolute; 
      top: 20px; 
      left: 70px;
    }
    #bon{
      z-index: 100; 
      position: absolute; 
      display: none;
    }
    #mauvais{
      z-index: 100; 
      position: absolute; 
      display: none;
    }
  </style>
</head>

<body>
  <div id="jeu">
    <img id="soucoupe" src="soucoupe.png">
    <img id="bon" src="bon.png">
    <img id="mauvais" src="mauvais.png">
  </div>
  جيد : <span id="info1">0</span> سيء : <span id="info2">0</span> النتيجة : <span id="info3">0</span> 
  <audio preload="auto" id="musiqueFond" autoplay="autoplay" loop="loop">
    <source src="BabyPleaseDontGo.mp3" type="audio/mp3">
    <source src="BabyPleaseDontGo.ogg" type="audio/ogg">
  </audio>

  <script src="jquery.js"></script>
  <script>
    // code jQuery 
  </script>
</body>
</html>
كما ترون ، لا يوجد شيء استثنائي حول هذه الخطوط. الملعب يتوافق مع العلامة
. تستضيف هذه العلامة ثلاث صور: الخلفية ( soucoupe.png) والعنصر (bon.png) الذي يجب جمعه والعنصر الذي يجب عدم جمعه ( mauvais.png (
يتم عرض ثلاث قطع من المعلومات أسفل منطقة اللعب:
  • 1. عدد الأشياء الجيدة التي تم جمعها ( #info1) ؛
  • 2. عدد الأشياء السيئة التي تم جمعها ( #info2) ؛
  • 3. النتيجة التي حصل عليها اللاعب ( #info3) .
أخيرًا ، يتم استخدام علامة<audio> للموسيقى الخلفية.
لا يقدم كود CSS أي صعوبة. مساحة اللعب بحجمها وإطارها وتعرض صورة في الخلفية . z-index تتم تهيئة الصحن الطائر إلى 200 بحيث يتم عرضه دائمًا في المقدمة. المعرفات #bon و #mauvais لديها z-index 100 . ولذلك تظهر بين صورة الخلفية وصحن طائر. يتم وضعهم على absolute ويتم تهيئة الخاصية display على noneلتكون غير مرئية في بداية الصفحة.
حركة الصحن الطائر
هذه الخطوة الثانية سوف تعطي الحياة لمفاتيح الوحة الرقمية. في بضع دقائق ، يمكنك نقل الصحن الطائر أينما تريد.
هنا هو كود المستخدم:

$(document).keydown(function(e){
  if (e.which == 39) // Vers la droite
  {
    posX = parseInt($('#soucoupe').css('left'));
    if (posX < 470)
      $('#soucoupe').css('left', posX+30);
  }     
  if (e.which == 37) // Vers la gauche
  {
    posX = parseInt($('#soucoupe').css('left'));
    if (posX > 20)
      $('#soucoupe').css('left', posX-30);
  }     
  if (e.which == 40) // Vers le bas
  {
    posY = parseInt($('#soucoupe').css('top'));
    if (posY < 230)
      $('#soucoupe').css('top', posY+30);
  }     
  if (e.which == 38) // Vers le haut
  {
    posY = parseInt($('#soucoupe').css('top'));
    if (posY > 20)
      $('#soucoupe').css('top', posY-30);
  }     
  if (e.which == 36) // Vers le haut et la gauche
  {
    posX = parseInt($('#soucoupe').css('left'));
    posY = parseInt($('#soucoupe').css('top'));
    if ((posY > 20) && (posX > 20))
      $('#soucoupe').css('left', posX-30).css('top', posY-30);
  }     
  if (e.which == 33) // Vers le haut et la droite
  {
    posX = parseInt($('#soucoupe').css('left'));
    posY = parseInt($('#soucoupe').css('top'));
    if ((posY > 20) && (posX < 470))
      $('#soucoupe').css('left', posX+30).css('top', posY-30);
  }     
  if (e.which == 35) // Vers le bas et la gauche
  {
    posX = parseInt($('#soucoupe').css('left'));
    posY = parseInt($('#soucoupe').css('top'));
    if ((posX > 20) && (posY < 230))
      $('#soucoupe').css('left', posX-30).css('top', posY+30);
  }     
  if (e.which == 34) // Vers le bas et la droite
  {
    posX = parseInt($('#soucoupe').css('left'));
    posY = parseInt($('#soucoupe').css('top'));
    if ((posY < 230) && (posX < 470))
      $('#soucoupe').css('left', posX+30).css('top', posY+30);
  }
});
لا تنخدع بعدد الإرشادات الموجودة في الطريقة keydown() . إذا كنت تبدو أقرب قليلاً ، فسترى أنه يحتوي على ثماني كتل من التعليمات البرمجية المخصصة لمعالجة ثمانية مفاتيح على لوحة المفاتيح الرقمية. خذ على سبيل المثال الكود الذي يتعامل مع مفتاح 9 لوحة المفاتيح. يجب أن يحرك هذا المفتاح الصحن الطائر قطريًا إلى أعلى وإلى اليمين.

if (e.which == 33) // Vers le haut et la droite
{
  posX = parseInt($('#soucoupe').css('left'));
  posY = parseInt($('#soucoupe').css('top'));
  if ((posY > 20) && (posX < 470))
    $('#soucoupe').css('left', posX+30).css('top', posY-30);
}
العبارات الأولتين تهيئان المتغيرات posX و posY مع إحداثيات الصحن الطائر. إذا سمحت هذه الإحداثيات ، يتم التنقل. هنا ، يجب ألا يكون الصحن مرتفعًا جدًا ( posY > 20) أو أقصى يمينًا ( posX < 470) . يتم ذلك عن طريق تعديل CSS left و top .
بمجرد إدخال هذه التعليمات ، يمكنك التحقق من أن الصحن يوجه بمفاتيح الأسهم على لوحة المفاتيح.
لا شيء يحدث. هل نسيت شيئا؟
إذا بقي الصحن ثابتًا ، فتحقق من أن المفتاح Verr Numغير نشط. إذا كنت تستخدم كمبيوتر محمول ، فقد تكون مفاتيح الأسهم مفقودة من لوحة المفاتيح. في هذه الحالة ، سيكون عليك اختيار مفاتيح أخرى. راجع قسم إدارة أحداث لوحة المفاتيح في الجزء 3 ، الدرس 1 للحصول على قائمة رموز ASCII لمفاتيح لوحة المفاتيح.
عرض العناصر #BON و #MAUVAIS
صور #bon و #mauvais هي للظهور بشكل دوري في مواقع اختيارها عشوائيا. لذلك ، تحتاج إلى إعداد وظيفة ستعمل على فترات منتظمة. هنا هو كود هذه الوظيفة:

function afficheElements()
{
  var elemX = Math.floor(Math.random()*500)+20;
  var elemY = Math.floor(Math.random()*300)+20;
  var elemType = Math.floor(Math.random()*2);
  if (elemType == 0)
  {
    $('#bon').css('top',elemY).css('left',elemX);
    $('#bon').show();
    $('#mauvais').css('display','none');
  }
  else
  {
    $('#mauvais').css('top',elemY).css('left',elemX);
    $('#mauvais').show();
    $('#bon').css('display','none');
  }
}
تستخدم العبارات الثلاثة الأولى الدالة Math.random() لاختيار أرقام عشوائية. الأول يتوافق مع حدود العنصر الذي سيتم عرضه. يتراوح بين 0 و 519. والثاني هو إحداثيات العنصر الذي سيتم عرضه. يتراوح بين 0 و 319. أخيرًا ، يحدد الثالث نوع العنصر الذي سيتم عرضه. إذا كانت elemType مساويا ل 0 ، يتم عرض العنصر#bon في الإحداثيات (elemY ، elemX) ، ثم يتم إخفاء العنصر #mauvais :

if (elemType == 0)
{
  $('#bon').css('top',elemY).css('left',elemX);
  $('#bon').show();
  $('#mauvais').css('display','none');
}
على العكس ، إذا كان elemType مختلفًا عن 0 ، فسيتم عرض العنصر #mauvais عند الإحداثيات (elemY ، elemX)، ثم يتم إخفاء العنصر#bon :

else
{
  $('#mauvais').css('top',elemY).css('left',elemX);
  $('#mauvais').show();
  $('#bon').css('display','none');
}
تذكر أن تستخدم الطريقة setInterval() لاستدعاء الوظيفة بشكل متكرر afficheElements() . هنا ، يتم تحديد الفترة الفاصلة بين تنفيذين في ثانيتين:

setInterval(afficheElements, 2000);
إدارة الاصطدام
هذا البرنامج هو شبه كامل: لم يبق إلا للتعامل مع اصطدام بين الصحن الطائر والعناصر #bon و #mauvais . تحديد وظيفة لهذا الغرض collisions() .

function collisions()
{
  posX = parseInt($('#soucoupe').css('left'));
  posY = parseInt($('#soucoupe').css('top'));
  if ($('#bon').css('display') == 'none')
  {
    elemType = 'mauvais';
    elemX = parseInt($('#mauvais').css('left'));
    elemY = parseInt($('#mauvais').css('top'));
  }
  else 
     {
    elemType = 'bon';
    elemX = parseInt($('#bon').css('left'));
    elemY = parseInt($('#bon').css('top'));
  }
  if ((elemX>posX-20) && (elemX<(posX+125-50+20)) && (elemY>posY-20) && (elemY<(posY+177-116+20)) && (stopDetection == 0))
  {
    if (elemType=='bon')
    {
      var nbBon = parseInt($('#info1').text())+1;
      $('#info1').text(nbBon);
      var score = parseInt($('#info3').text())+5;
      $('#info3').text(score);
      $('#bon').css('display', 'none');
    }
    else
    {
      var nbMauvais = parseInt($('#info2').text())+1;
      $('#info2').text(nbMauvais);
      var score = parseInt($('#info3').text())-5;
      $('#info3').text(score);
      $('#mauvais').css('display', 'none');
    }
  }
}
الإرشادات الأولى والثانية تحفظ إحداثيات الصحن في المتغيرات posX و posY :

posX = parseInt($('#soucoupe').css('left'));
posY = parseInt($('#soucoupe').css('top'));
تحدد العبارة ifالتالية إحداثيات العنصر #bon أو #mauvais المعروض وتخزينها في المتغيرات elemX و elemY . إذا لم يتم عرض العنصر #bon

if ($('#bon').css('display') == 'none')
... هذا يعني أنه يتم عرض العنصر #mauvais . يتم تخزين السلسلة "mauvais" في المتغير elemType وتكون إحداثيات العنصر #mauvais في المتغيرات elemX و elemY :

elemType = 'mauvais';
elemX = parseInt($('#mauvais').css('left'));
elemY = parseInt($('#mauvais').css('top'));
خلاف ذلك ، يتم عرض العنصر #bon . يتم تخزين السلسلة "Bon" في المتغير elemType وتكون إحداثيات العنصر #bon في المتغيرات elemX و elemY :

elemType = 'bon';
elemX = parseInt($('#bon').css('left'));
elemY = parseInt($('#bon').css('top'));
يبقى فقط لاختبار ما إذا كان الصحن الطائر والعنصر المعروض في الإحداثيات ( elemX ، elemY ) يتداخلان:

if ((elemX>posX-20) && (elemX<(posX+125-50+20)) && (elemY>posY-20) && (elemY<(posY+177-116+20)))
لماذا كتبت posX+125-50+20و posY+177-116+20؟
صحيح أنه كان من الأسهل الكتابة posX+95 و posY+81 . إذا أشرت إلى ثلاثة أرقام كنتيجة لـ posX و posY ، فهي للأغراض التعليمية فقط: يبلغ عرض الصحن الطائر 125 بكسل وعناصر لجمع حوالي 50 بكسل. من خلال التحقق من أن حدود العنصر أكبر من تلك الموجودة في الوعاء وأصغر من الوعاء + عرض الوعاء - يتم التأكد من تغطية العنصر بالكامل بواسطة الوعاء.
ينطبق الشيء نفسه على الاختبارين الأخيرين: عن طريق التحقق من أن إحداثيات العنصر أكبر من إحداثيات الصحن الطائر وأصغر من تلك التي في الصحن الطائر + ارتفاع الصحن الطائر - ارتفاع العنصر ، واحد تأكد من أن الصحن الطائر مغطى بالكامل.
إضافة 20بكسل إلى posX و posY تعطي هامش أمان حول الصحن الطائر بحيث الاصطدام هو أسهل للكشف. بنفس الطريقة ، تتم إزالة 20 بكسل في الاختبارين الأول والثالث لتسهيل اكتشاف الاصطدامات. بدون هذه القطعة ، يجب أن يكون الصحن الطائر مغطى تمامًا من أجل حدوث تصادم.
الأسطر التالية بتحديث العلامات <span> #info1 ، #info2 و #info3 اعتمادا على طبيعة العنصر الذي اصطدم مع الصحن الطائر . إذا كان العنصر #bon :

if (elemType=='bon')
... #bon يتم زيادة عدد العناصر التي تم التقاطها بنسبة 1 ، والنتيجة تزداد ب 5 ويتم إخفاء العنصر #bon :

var nbBon = parseInt($('#info1').text())+1;
$('#info1').text(nbBon);
var score = parseInt($('#info3').text())+5;
$('#info3').text(score);
$('#bon').css('display', 'none');
إذا كان العنصر #mauvais، فسيتم زيادة عدد العناصر التي تم التقاطها بمقدار 1 ، ويتم تقليل النتيجة بمقدار 5 ويتم إخفاء العنصر #mauvais :

else
{
  var nbMauvais = parseInt($('#info2').text())+1;
  $('#info2').text(nbMauvais);
  var score = parseInt($('#info3').text())-5;
  $('#info3').text(score);
  $('#mauvais').css('display', 'none');
}
أخيرًا ، قم بتنشيط هذه الوظيفة على فترات منتظمة. على سبيل المثال ، كل 200 ميلي ثانية مع الوظيفة setInterval() :

setInterval(collisions, 200);
أشعر أنك لا تستطيع الانتظار لاختبار هذا الكود هيا اذهب !
كل شيء يعمل بشكل جيد إذا كانت مشكلة بسيطة في اكتشاف التصادم. نظرًا لأن الوظيفة collisions() تعمل كل 200 مللي ثانية ، فإن البرنامج يكتشف أحيانًا تصادمات متعددة أثناء حدوث واحد فقط. مما يؤدي إلى زيادة أو نقصان مفرط في عدد #bon أو #mauvais . بالطبع ، تنتشر هذه المشكلة إلى الدرجة التي يمكن أن تزيد أو تنقص أسرع بكثير مما ينبغي!
لحل هذه المشكلة ، سوف نحدد المتغير الشامل stopDetection الذي سنقوم بتهيئته إلى 0 بعد توفر DOM :

$(function() {
  var stopDetection = 0;
  ...
لماذا استخدام متغيرعام (global)؟
يُطلق على المتغير stopDetection" عام" لأنه غير مرتبط بطريقة أو وظيفة معينة. سيكون نطاقه عاما في جميع رموز JavaScript .
عند اكتشاف تصادم ، يتم تخزين القيمة 1 في المتغير stopDetection للإشارة إلى أنه لم يعد من الضروري اكتشاف التعارضات. بالتوازي ، لكي يكون التصادم فعالًا ، يجب أن يكون المتغير stopCollision مساويًا 0. وبالتالي يصبح كود الوظيفة collisions() كما يلي:

if ((elemX>posX) && (elemX<(posX+233)) && (elemY>posY) && (elemY<(posY+127)) && (stopDetection == 0))
{
  $('#son')[0].play();
  stopDetection = 1; 
كل ما تبقى هو تعيين المتغير stopDetection إلى 0 عند عرض عنصر جديد:

function afficheElements()
{
  stopDetection = 0;
  ...
هذا كل شيء ، كود التشغيل الكامل. آمل أن تطوره لم يشكل لك أي مشكلة. لا تتردد في تحرير أو إضافة أشياء (الأصوات على سبيل المثال). ما سيكون لطيفًا هو السماح للمشغل بإيقاف الموسيقى مؤقتًا أو تشغيلها.
جرب اللعبة

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>jeu</title>
  <style type="text/css">
    #jeu{
      width: 600px;
      height: 400px;
      border: 2px black solid;
      background: url('fond.png');
    }
    #soucoupe{
      z-index: 200; 
      position: absolute; 
      top: 20px; 
      left: 70px;
    }
    #bon{
      z-index: 100; 
      position: absolute; 
      display: none;
    }
    #mauvais{
      z-index: 100; 
      position: absolute; 
      display: none;
    }
  </style>
</head>

<body>
  <div id="jeu">
    <img id="soucoupe" src="soucoupe.png">
    <img id="bon" src="bon.png">
    <img id="mauvais" src="mauvais.png">
  </div>
  Bon : <span id="info1">0</span> Mauvais : <span id="info2">0</span> Score : <span id="info3">0</span> 
  <audio preload="auto" id="musiqueFond" autoplay="autoplay" loop="loop"><source src="BabyPleaseDontGo.mp3" type="audio/mp3"><source src="BabyPleaseDontGo.ogg" type="audio/ogg"></audio>

  <script src="jquery.js"></script>
  <script>
    $(function() {
      var stopDetection = 0;
      $(document).keydown(function(e){
      if (e.which == 39) // Vers la droite
      {
        posX = parseInt($('#soucoupe').css('left'));
          if (posX < 470)
            $('#soucoupe').css('left', posX+30);
        }     
        if (e.which == 37) // Vers la gauche
        {
          posX = parseInt($('#soucoupe').css('left'));
          if (posX > 20)
            $('#soucoupe').css('left', posX-30);
        }     
        if (e.which == 40) // Vers le bas
        {
          posY = parseInt($('#soucoupe').css('top'));
          if (posY < 230)
            $('#soucoupe').css('top', posY+30);
        }     
        if (e.which == 38) // Vers le haut
        {
          posY = parseInt($('#soucoupe').css('top'));
          if (posY > 20)
            $('#soucoupe').css('top', posY-30);
        } 
        if (e.which == 36) // Vers le haut et la gauche
        {
          posX = parseInt($('#soucoupe').css('left'));
          posY = parseInt($('#soucoupe').css('top'));
          if ((posY > 20) && (posX > 20))
            $('#soucoupe').css('left', posX-30).css('top', posY-30);
        }     
        if (e.which == 33) // Vers le haut et la droite
        {
          posX = parseInt($('#soucoupe').css('left'));
          posY = parseInt($('#soucoupe').css('top'));
          if ((posY > 20) && (posX < 470))
            $('#soucoupe').css('left', posX+30).css('top', posY-30);
        }     
        if (e.which == 35) // Vers le bas et la gauche
        {
          posX = parseInt($('#soucoupe').css('left'));
          posY = parseInt($('#soucoupe').css('top'));
          if ((posX > 20) && (posY < 230))
            $('#soucoupe').css('left', posX-30).css('top', posY+30);
        }     
        if (e.which == 34) // Vers le bas et la droite
        {
          posX = parseInt($('#soucoupe').css('left'));
          posY = parseInt($('#soucoupe').css('top'));
          if ((posY < 230) && (posX < 470))
            $('#soucoupe').css('left', posX+30).css('top', posY+30);
        }     
      });

      function afficheElements()
      {
        stopDetection = 0;
        var elemX = Math.floor(Math.random()*500)+20;
        var elemY = Math.floor(Math.random()*300)+20;
        var elemType = Math.floor(Math.random()*2);
        if (elemType == 0)
        {
          $('#bon').css('top',elemY).css('left',elemX);
          $('#bon').show();
          $('#mauvais').css('display','none');
        }
        else
        {
          $('#mauvais').css('top',elemY).css('left',elemX);
          $('#mauvais').show();
          $('#bon').css('display','none');
        }
      }

      function collisions()
      {
        posX = parseInt($('#soucoupe').css('left'));
        posY = parseInt($('#soucoupe').css('top'));
        if ($('#bon').css('display') == 'none')
        {
          elemType = 'mauvais';
          elemX = parseInt($('#mauvais').css('left'));
          elemY = parseInt($('#mauvais').css('top'));
        }
        else         
        {
          elemType = 'bon';
          elemX = parseInt($('#bon').css('left'));
          elemY = parseInt($('#bon').css('top'));
        }
        if ((elemX>posX-20) && (elemX<(posX+125-50+20)) && (elemY>posY-20) && (elemY<(posY+177-116+20)) && (stopDetection == 0))
        {
          stopDetection = 1;
          if (elemType=='bon')
          {
            var nbBon = parseInt($('#info1').text())+1;
            $('#info1').text(nbBon);
            var score = parseInt($('#info3').text())+5;
            $('#info3').text(score);
            $('#bon').css('display', 'none');
          }
          else
          {
            var nbMauvais = parseInt($('#info2').text())+1;
            $('#info2').text(nbMauvais);
            var score = parseInt($('#info3').text())-5;
            $('#info3').text(score);
            $('#mauvais').css('display', 'none');
          }
        }                         
      }
       
      setInterval(afficheElements, 2000);
      setInterval(collisions, 200);
    });
  </script>
</body>
</html>