Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π’Ρ‹Ρ€Π°Π·ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ JavaScriptΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 53

Автор ΠœΠ°Ρ€Π΅ΠΉΠ½ Π₯Π°Π²Π΅Ρ€Π±Π΅ΠΊΠ΅

.lost .player {

  background: rgb(160, 64, 64);

}

.won .player {

  box-shadow: -4px -7px 8px white, 4px -7px 8px white;

}

ПослС прикосновСния ΠΊ Π»Π°Π²Π΅ Ρ†Π²Π΅Ρ‚Π° ΠΈΠ³Ρ€ΠΎΠΊΠ° становятся Ρ‚Ρ‘ΠΌΠ½ΠΎ-красными, Π±ΡƒΠ΄Ρ‚ΠΎ ΠΎΠ½ сгорСл. Когда послСдняя ΠΌΠΎΠ½Π΅Ρ‚ΠΊΠ° собрана, ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ€Π°Π·ΠΌΡ‹Ρ‚Ρ‹Π΅ Ρ‚Π΅Π½ΠΈ для создания эффСкта сияния.

НСльзя ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΡƒΡ€ΠΎΠ²Π½ΠΈ всСгда Π²ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π² ΠΎΠΊΠ½ΠΎ просмотра. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π½Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ scrollPlayerIntoView – ΠΎΠ½ Π½ΡƒΠΆΠ΅Π½ для Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΈ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Ссли ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ Π½Π΅ Π²Π»Π΅Π·Π°Π΅Ρ‚ Π² ΠΎΠΊΠ½ΠΎ, ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‡Π΅Π½, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€ΠΎΠΊ всСгда Π±Ρ‹Π» Π±Π»ΠΈΠ·ΠΊΠΎ ΠΊ Ρ†Π΅Π½Ρ‚Ρ€Ρƒ. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ CSS Π·Π°Π΄Π°Ρ‘Ρ‚ ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ΅ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€, ΠΈ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ всё Π²Ρ‹Π»Π΅Π·Π°ΡŽΡ‰Π΅Π΅ Π·Π° Π½Π΅Π³ΠΎ Π½Π΅ Π²ΠΈΠ΄Π½ΠΎ. Π’Π°ΠΊΠΆΠ΅ ΠΌΡ‹ Π·Π°Π΄Π°Ρ‘ΠΌ элСмСнту ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ relative, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π°ΠΊΡ‚Ρ‘Ρ€Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Π³ΠΎ Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°Π»ΠΈΡΡŒ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π΅Π³ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ ΡƒΠ³Π»Π°.

.game {

  overflow: hidden;

  max-width: 600px;

  max-height: 450px;

  position: relative;

}

Π’ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ scrollPlayerIntoView ΠΌΡ‹ Π½Π°Ρ…ΠΎΠ΄ΠΈΠΌ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ³Ρ€ΠΎΠΊΠ° ΠΈ обновляСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‚ΠΊΠΈ ΠΎΠ±Ρ‘Ρ€Ρ‚Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ элСмСнта. ΠœΡ‹ мСняСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ, работая со свойствами scrollLeft ΠΈ scrollTop, ΠΊΠΎΠ³Π΄Π° ΠΈΠ³Ρ€ΠΎΠΊ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ Π±Π»ΠΈΠ·ΠΊΠΎ ΠΊ ΠΊΡ€Π°ΡŽ.

DOMDisplay.prototype.scrollPlayerIntoView = function() {

  var width = this.wrap.clientWidth;

  var height = this.wrap.clientHeight;

  var margin = width / 3;


  // The viewport

  var left = this.wrap.scrollLeft, right = left + width;

  var top = this.wrap.scrollTop, bottom = top + height;


  var player = this.level.player;

  var center = player.pos.plus(player.size.times(0.5))

                 .times(scale);


  if (center.x < left + margin)

    this.wrap.scrollLeft = center.x - margin;

  else if (center.x > right - margin)

    this.wrap.scrollLeft = center.x + margin - width;

  if (center.y < top + margin)

    this.wrap.scrollTop = center.y - margin;

  else if (center.y > bottom - margin)

    this.wrap.scrollTop = center.y + margin - height;

};

ΠœΠ΅Ρ‚ΠΎΠ΄ нахоТдСния Ρ†Π΅Π½Ρ‚Ρ€Π° ΠΈΠ³Ρ€ΠΎΠΊΠ° ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π½Π°ΡˆΠΈΡ… Ρ‚ΠΈΠΏΠΎΠ² Vector ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ расчёты, ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌΡ‹Π΅ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ, наглядно. Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΉΡ‚ΠΈ Ρ†Π΅Π½Ρ‚Ρ€ Π°ΠΊΡ‚Ρ‘Ρ€Π°, ΠΌΡ‹ добавляСм Π΅Π³ΠΎ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ (Π΅Π³ΠΎ Π»Π΅Π²Ρ‹ΠΉ Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ ΡƒΠ³ΠΎΠ») ΠΈ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρƒ высоты. Π­Ρ‚ΠΎ Ρ†Π΅Π½Ρ‚Ρ€ Π² ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Π°Ρ… уровня, Π½ΠΎ Π½Π°ΠΌ ΠΎΠ½ Π½ΡƒΠΆΠ΅Π½ Π² ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Π°Ρ… пиксСлСй, поэтому ΠΌΡ‹ ΡƒΠΌΠ½ΠΎΠΆΠ°Π΅ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Π²Π΅ΠΊΡ‚ΠΎΡ€ Π½Π° наш ΠΌΠ°ΡΡˆΡ‚Π°Π±.

Π—Π°Ρ‚Π΅ΠΌ сСрия ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΈΠ³Ρ€ΠΎΠΊ Π½Π΅ находится Π²Π½Π΅ доступного пространства. Иногда Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°Π΄Π°Π½Ρ‹ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‚ΠΊΠΈ, Π½ΠΈΠΆΠ΅ нуля ΠΈΠ»ΠΈ большС, Ρ‡Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‡ΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ элСмСнта. Но это Π½Π΅ ΡΡ‚Ρ€Π°ΡˆΠ½ΠΎ – DOM автоматичСски ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ ΠΈΡ… допустимыми значСниями. Если Π½Π°Π·Π½Π°Ρ‡ΠΈΡ‚ΡŒ scrollLeft Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ -10, ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π΅Π½ 0.

Π‘Ρ‹Π»ΠΎ Π±Ρ‹ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ‰Π΅ ΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‡ΠΈΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ ΠΈΠ³Ρ€ΠΎΠΊΠ° Π² Ρ†Π΅Π½Ρ‚Ρ€ ΠΎΠΊΠ½Π° просмотра – Π½ΠΎ это создаёт нСприятный Π΄Ρ€ΠΎΠΆΠ°Ρ‰ΠΈΠΉ эффСкт. Π’ΠΎ врСмя ΠΏΡ€Ρ‹ΠΆΠΊΠΎΠ² Π²ΠΈΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ постоянно Π΄Π²ΠΈΠ³Π°Ρ‚ΡŒΡΡ Π²Π²Π΅Ρ€Ρ… ΠΈ Π²Π½ΠΈΠ·. Π“ΠΎΡ€Π°Π·Π΄ΠΎ приятнСС ΠΈΠΌΠ΅Ρ‚ΡŒ Β«Π½Π΅ΠΉΡ‚Ρ€Π°Π»ΡŒΠ½ΡƒΡŽΒ» Π·ΠΎΠ½Ρƒ Π² сСрСдинС экрана, Π³Π΄Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π²ΠΈΠ³Π°Ρ‚ΡŒΡΡ, Π½Π΅ вызывая ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‚ΠΊΠΈ.

Π•Ρ‰Ρ‘ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡ‡ΠΈΡ‰Π°Ρ‚ΡŒ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΈΠ»ΠΈ Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ Π·Π°Π½ΠΎΠ²ΠΎ.

DOMDisplay.prototype.clear = function() {

  this.wrap.parentNode.removeChild(this.wrap);

};

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ наш ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ.

<link rel="stylesheet" href="css/game.css">


<script>

  var simpleLevel = new Level(simpleLevelPlan);

  var display = new DOMDisplay(document.body, simpleLevel);

</script>

Вэг <link> ΠΏΡ€ΠΈ использовании с rel="stylesheet" позволяСт Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» с CSS. Π€Π°ΠΉΠ» game.css содСрТит Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ для ΠΈΠ³Ρ€Ρ‹ стили.

Π”Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ ΠΈ столкновСниС

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π°ΠΌ Π½Π°Π΄ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠΉ – самоС интСрСсноС Π² ΠΈΠ³Ρ€Π΅. ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ ΠΈΠ³Ρ€ – Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ врСмя Π½Π° нСбольшиС ΠΎΡ‚Ρ€Π΅Π·ΠΊΠΈ, ΠΈ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ шагС ΡΠ΄Π²ΠΈΠ³Π°Ρ‚ΡŒ Π°ΠΊΡ‚Ρ‘Ρ€ΠΎΠ² Π½Π° Π΄ΠΈΡΡ‚Π°Π½Ρ†ΠΈΡŽ, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ ΠΈΡ… скорости (расстояниС Π² сСкунду), ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ Π½Π° Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΎΡ‚Ρ€Π΅Π·ΠΊΠ° (Π² сСкундах).

Π­Ρ‚ΠΎ просто. Π‘Π»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π°Π΄ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ взаимодСйствиС ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ΠΎΠ². Когда ΠΈΠ³Ρ€ΠΎΠΊ касаСтся ΠΏΠΎΠ»Π° ΠΈΠ»ΠΈ стСны, ΠΎΠ½ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ насквозь. Π˜Π³Ρ€Π° Π΄ΠΎΠ»ΠΆΠ½Π° Π·Π°ΠΌΠ΅Ρ‡Π°Ρ‚ΡŒ, ΠΊΠΎΠ³Π΄Π° Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ ΡΡ‚ΠΎΠ»ΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡŽ с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΈ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ соотвСтствСнно. Π‘Ρ‚Π΅Π½Ρ‹ ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅, ΠΌΠΎΠ½Π΅Ρ‚Ρ‹ ΡΠΎΠ±ΠΈΡ€Π°ΡŽΡ‚ΡΡ, ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅.

Π’ ΠΎΠ±Ρ‰Π΅ΠΌ случаС эта Π·Π°Π΄Π°Ρ‡Π° Π½Π΅ такая простая. МоТно Π½Π°ΠΉΡ‚ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ΡΡ «физичСскими Π΄Π²ΠΈΠΆΠΊΠ°ΠΌΠΈΒ», ΡΠΈΠΌΡƒΠ»ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ взаимодСйствия ΠΌΠ΅ΠΆΠ΄Ρƒ физичСскими ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Π² Π΄Π²ΡƒΡ… ΠΈΠ»ΠΈ Ρ‚Ρ€Ρ‘Ρ… измСрСниях. Π’ этой Π³Π»Π°Π²Π΅ ΠΌΡ‹ поступим ΠΏΡ€ΠΎΡ‰Π΅, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ столкновСния Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

ΠŸΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΡΠ΄Π²ΠΈΠ½ΡƒΡ‚ΡŒ ΠΈΠ³Ρ€ΠΎΠΊΠ° ΠΈΠ»ΠΈ Π±Π»ΠΎΠΊ Π»Π°Π²Ρ‹, ΠΌΡ‹ провСряСм, Π½Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ Π»ΠΈ нас Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π²Π½ΡƒΡ‚Ρ€ΡŒ нСпустой части Ρ„ΠΎΠ½Π°. Если Π΄Π° – ΠΌΡ‹ отмСняСм Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅. РСакция Π½Π° это Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Π²ΠΈΡΠ΅Ρ‚ΡŒ ΠΎΡ‚ Ρ‚ΠΈΠΏΠ° Π°ΠΊΡ‚Ρ‘Ρ€Π° – ΠΈΠ³Ρ€ΠΎΠΊ останавливаСтся, Π»Π°Π²Π° отскакиваСт.

ΠŸΠΎΠ΄Ρ…ΠΎΠ΄ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ использования Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΎΡ‚Ρ€Π΅Π·ΠΊΠΎΠ² Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Π»ΠΈΡΡŒ Π΄ΠΎ соприкосновСния. Если Π²Π·ΡΡ‚ΡŒ слишком большиС ΠΎΡ‚Ρ€Π΅Π·ΠΊΠΈ, ΠΈΠ³Ρ€ΠΎΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Π²ΠΈΡΠ°Ρ‚ΡŒ Π½Π°Π΄ Π·Π΅ΠΌΠ»Ρ‘ΠΉ. МоТно Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ слоТный Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ – Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ мСсто нСпосрСдствСнного соприкосновСния ΠΈ ΠΏΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚ΡŒ Π°ΠΊΡ‚Ρ‘Ρ€Π° Ρ‚ΡƒΠ΄Π°. ΠœΡ‹ поступим ΠΏΡ€ΠΎΡ‰Π΅, ΠΈ скроСм Π΅Π³ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, Π²Ρ‹Π±Ρ€Π°Π² нСбольшиС Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΎΡ‚Ρ€Π΅Π·ΠΊΠΈ.

ΠœΠ΅Ρ‚ΠΎΠ΄ сообщаСт, Π½Π΅ пСрСсСкаСтся Π»ΠΈ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ (Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ) с ΠΊΠ°ΠΊΠΈΠΌ-Π»ΠΈΠ±ΠΎ нСпустым пространством Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠΉ Ρ€Π΅ΡˆΡ‘Ρ‚ΠΊΠΈ.

Level.prototype.obstacleAt = function(pos, size) {

  var xStart = Math.floor(pos.x);

  var xEnd = Math.ceil(pos.x + size.x);

  var yStart = Math.floor(pos.y);

  var yEnd = Math.ceil(pos.y + size.y);


  if (xStart < 0 || xEnd > this.width || yStart < 0)

    return "wall";

  if (yEnd > this.height)

    return "lava";

  for (var y = yStart; y < yEnd; y++) {

    for (var x = xStart; x < xEnd; x++) {

      var fieldType = this.grid[y][x];

      if (fieldType) return fieldType;

    }

  }

};

ΠœΠ΅Ρ‚ΠΎΠ΄ вычисляСт Π·Π°Π½ΠΈΠΌΠ°Π΅ΠΌΡ‹Π΅ Ρ‚Π΅Π»ΠΎΠΌ ячСйки Ρ€Π΅ΡˆΡ‘Ρ‚ΠΊΠΈ, примСняя Math.floor ΠΈ Math.ceil Π½Π° ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Π°Ρ… Ρ‚Π΅Π»Π°. ΠŸΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ячССк – 1Γ—1 Π΅Π΄ΠΈΠ½ΠΈΡ†. ΠžΠΊΡ€ΡƒΠ³Π»ΡΡ Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ Ρ‚Π΅Π»Π° Π²Π²Π΅Ρ€Ρ… ΠΈ Π²Π½ΠΈΠ·, ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΠΊ ΠΈΠ· ячССк Ρ„ΠΎΠ½Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… касаСтся Ρ‚Π΅Π»ΠΎ.


Поиск столкновСний Π½Π° Ρ€Π΅ΡˆΡ‘Ρ‚ΠΊΠ΅

Если Ρ‚Π΅Π»ΠΎ высовываСтся ΠΈΠ· уровня, ΠΌΡ‹ всСгда Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ β€œwall” для Π΄Π²ΡƒΡ… сторон ΠΈ Π²Π΅Ρ€Ρ…Π° ΠΈ β€œlava” для Π½ΠΈΠ·Π°. Π­Ρ‚ΠΎ обСспСчит гибСль ΠΈΠ³Ρ€ΠΎΠΊΠ° ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ уровня. Когда Ρ‚Π΅Π»ΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ€Π΅ΡˆΡ‘Ρ‚ΠΊΠΈ, ΠΌΡ‹ Π² Ρ†ΠΈΠΊΠ»Π΅ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΠΌ Π±Π»ΠΎΠΊ ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚ΠΎΠ² Ρ€Π΅ΡˆΡ‘Ρ‚ΠΊΠΈ, Π½Π°ΠΉΠ΄Π΅Π½Π½Ρ‹ΠΉ ΠΎΠΊΡ€ΡƒΠ³Π»Π΅Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚, ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ содСрТимоС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ нСпустого ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚ΠΈΠΊΠ°.

БтолкновСния ΠΈΠ³Ρ€ΠΎΠΊΠ° с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ Π°ΠΊΡ‚Ρ‘Ρ€Π°ΠΌΠΈ (ΠΌΠΎΠ½Π΅Ρ‚Ρ‹, двиТущаяся Π»Π°Π²Π°) ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ послС сдвига ΠΈΠ³Ρ€ΠΎΠΊΠ°. Когда Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ Π΅Π³ΠΎ ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ Π°ΠΊΡ‚Ρ‘Ρ€Ρƒ, срабатываСт ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ эффСкт (сбор ΠΌΠΎΠ½Π΅Ρ‚ ΠΈΠ»ΠΈ гибСль).

Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ сканируСт массив Π°ΠΊΡ‚Ρ‘Ρ€ΠΎΠ², Π² поисках Ρ‚ΠΎΠ³ΠΎ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ накладываСтся Π½Π° Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚:

Level.prototype.actorAt = function(actor) {

  for (var i = 0; i < this.actors.length; i++) {

    var other = this.actors[i];

    if (other != actor &&

        actor.pos.x + actor.size.x > other.pos.x &&

        actor.pos.x < other.pos.x + other.size.x &&

        actor.pos.y + actor.size.y > other.pos.y &&

        actor.pos.y < other.pos.y + other.size.y)

      return other;

  }

};

Актёры ΠΈ дСйствия

ΠœΠ΅Ρ‚ΠΎΠ΄ animate Ρ‚ΠΈΠΏΠ° Level Π΄Π°Ρ‘Ρ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ всСм Π°ΠΊΡ‚Ρ‘Ρ€Π°ΠΌ уровня ΡΠ΄Π²ΠΈΠ½ΡƒΡ‚ΡŒΡΡ. АргумСнт step Π·Π°Π΄Π°Ρ‘Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΠΊ. ΠžΠ±ΡŠΠ΅ΠΊΡ‚ keys содСрТит ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΏΡ€ΠΎ стрСлки ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹, Π½Π°ΠΆΠ°Ρ‚Ρ‹Π΅ ΠΈΠ³Ρ€ΠΎΠΊΠΎΠΌ.

var maxStep = 0.05;


Level.prototype.animate = function(step, keys) {

  if (this.status != null)

    this.finishDelay -= step;


  while (step > 0) {

    var thisStep = Math.min(step, maxStep);

    this.actors.forEach(function(actor) {

      actor.act(thisStep, this, keys);

    }, this);

    step -= thisStep;

  }

};

Когда Ρƒ свойства уровня status Π΅ΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎΠ΅ ΠΎΡ‚ null (Π° это Π±Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠΎΠ³Π΄Π° ΠΈΠ³Ρ€ΠΎΠΊ Π²Ρ‹ΠΈΠ³Ρ€Π°Π» ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠΈΠ³Ρ€Π°Π»), ΠΌΡ‹ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Π΄ΠΎ нуля счётчик finishDelay, ΡΡ‡ΠΈΡ‚Π°ΡŽΡ‰ΠΈΠΉ врСмя ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΠΌ, ΠΊΠΎΠ³Π΄Π° ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΡ‘Π» Π²Ρ‹ΠΈΠ³Ρ€Ρ‹Ρˆ ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠΈΠ³Ρ€Ρ‹Ρˆ ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΠΌ, ΠΊΠΎΠ³Π΄Π° Π½Π°Π΄ΠΎ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠΊΠ°Π· уровня.

Π¦ΠΈΠΊΠ» while Π΄Π΅Π»ΠΈΡ‚ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π» Π½Π° ΡƒΠ΄ΠΎΠ±Π½Ρ‹Π΅ ΠΌΠ΅Π»ΠΊΠΈΠ΅ куски. Он слСдит, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΊΠΈ Π±Ρ‹Π»ΠΈ Π½Π΅ большС maxStep. К ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, шаг Π² 0,12 сСкунды Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ€Π΅Π·Π°Π½ Π½Π° Π΄Π²Π° шага ΠΏΠΎ 0,05 ΠΈ остаток Π² 0,02

Π£ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π°ΠΊΡ‚Ρ‘Ρ€ΠΎΠ² Π΅ΡΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ act, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ шаг, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ level ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ keys. Π’ΠΎΡ‚ ΠΎΠ½ для Ρ‚ΠΈΠΏΠ° Lava, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ key:

Lava.prototype.act = function(step, level) {

  var newPos = this.pos.plus(this.speed.times(step));

  if (!level.obstacleAt(newPos, this.size))

    this.pos = newPos;

  else if (this.repeatPos)

    this.pos = this.repeatPos;