From 841aae260382e2bf5ebb44d765d8c7301d27caab Mon Sep 17 00:00:00 2001 From: Alexey Istomin Date: Sat, 20 Mar 2021 18:37:44 +0300 Subject: Restore "ё" letter in Russian translation (#239) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(ru): restore ё letter * docs(ru): resolve conflicts * refactor(idea): remove ide folder --- files/ru/games/anatomy/index.html | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'files/ru/games/anatomy/index.html') diff --git a/files/ru/games/anatomy/index.html b/files/ru/games/anatomy/index.html index 91949c9ac0..b3022fa527 100644 --- a/files/ru/games/anatomy/index.html +++ b/files/ru/games/anatomy/index.html @@ -18,17 +18,17 @@ original_slug: Games/Анатомия

Особенности игр.

-

Некоторые игры управляют своим циклом при помощи пользовательского ввода. Представьте, что вы разрабатываете игру типа "найди разницу между этими двумя похожими картинками". Такого рода игры показывают пользователю две картинки; они получают их клики (или касания); они преобразуют ввод в успешный , не успешный, пауза, работа с меню, и так далее; в конечном итоге, в зависимости от данных действий, они вычисляют обновленное состояние сцены. Игровой цикл продвигается пользовательскими действиями и "спит" пока таковые отсутствуют. Это пример так называемой пошаговой игры, которая не зависит от постоянного обновления каждого кадра, а только от действий пользователя.

+

Некоторые игры управляют своим циклом при помощи пользовательского ввода. Представьте, что вы разрабатываете игру типа "найди разницу между этими двумя похожими картинками". Такого рода игры показывают пользователю две картинки; они получают их клики (или касания); они преобразуют ввод в успешный , не успешный, пауза, работа с меню, и так далее; в конечном итоге, в зависимости от данных действий, они вычисляют обновлённое состояние сцены. Игровой цикл продвигается пользовательскими действиями и "спит" пока таковые отсутствуют. Это пример так называемой пошаговой игры, которая не зависит от постоянного обновления каждого кадра, а только от действий пользователя.

Другие игры требуют контроля над каждым из минимально возможных индивидуальных временных интервалов. Те же принципы, что и выше, применяются с небольшим изменением: каждый кадр анимации продолжает цикл, и любое изменение пользовательского ввода фиксируется на первом доступном ходе. Эта покадровая модель реализована в так называемом основном цикле. Если ваша игра зацикливается на времени, то это будет её полномочия, которые будут соблюдать ваши симуляции.

Но покадровое управление может и не понадобиться. Ваш игровой цикл может быть похож на пример поиска отличий и основан на входных событиях. Это может потребовать как ввода, так и симуляции времени. Он может даже зацикливаться на чем-то совершенно другом.

-

Современный JavaScript, как описано в следующих разделах, к счастью, позволяет легко разработать эффективный основной цикл выполнения один раз в кадр. Конечно, ваша игра будет оптимизирована настолько, насколько вы ее сделаете. Если что-то выглядит так, как будто оно должно быть прикреплено к более редкому исходу, то часто бывает хорошей идеей вырвать его из основного цикла (но не всегда).

+

Современный JavaScript, как описано в следующих разделах, к счастью, позволяет легко разработать эффективный основной цикл выполнения один раз в кадр. Конечно, ваша игра будет оптимизирована настолько, насколько вы её сделаете. Если что-то выглядит так, как будто оно должно быть прикреплено к более редкому исходу, то часто бывает хорошей идеей вырвать его из основного цикла (но не всегда).

Построение основного цикла в JavaScript 

-

Лучше всего JavaScript работает с событиями и callback функциями. Современные браузеры стремятся вызывать методы по мере необходимости и бездействовать (или выполнять другие задачи) в промежутках. Привязать код к моменту, который для него подходит — это отличная идея.  Подумайте о том, действительно ли ваша функция должна вызываться на строго определенном интервале времени, в каждом кадре или только после того, как произойдет что-то еще.  Подумайте о том, действительно ли функцию нужно вызывать в определённом интервале времени, на каждый кадр или только после того, как что-то произойдёт. Больше конкретики с браузером в том, когда функция должна быть вызвана, позволяет ему лучше оптимизировать этот процесс. Так же, вероятно, это облегчит вам работу.   

+

Лучше всего JavaScript работает с событиями и callback функциями. Современные браузеры стремятся вызывать методы по мере необходимости и бездействовать (или выполнять другие задачи) в промежутках. Привязать код к моменту, который для него подходит — это отличная идея.  Подумайте о том, действительно ли ваша функция должна вызываться на строго определённом интервале времени, в каждом кадре или только после того, как произойдёт что-то ещё.  Подумайте о том, действительно ли функцию нужно вызывать в определённом интервале времени, на каждый кадр или только после того, как что-то произойдёт. Больше конкретики с браузером в том, когда функция должна быть вызвана, позволяет ему лучше оптимизировать этот процесс. Так же, вероятно, это облегчит вам работу.   

Некоторый код должен выполняться кадр за кадром, так зачем же прикреплять эту функцию к чему-то другому, кроме графика перерисовки браузера? В Web, {{ domxref("window.requestAnimationFrame()") }} будет основой большинства хорошо запрограммированных покадровых основных циклов.  Callback функция должна быть передана ему при вызове. Callback функция будет выполнена в подходящее время перед следующей перерисовкой. Вот пример простого основного цикла:

@@ -41,26 +41,26 @@ original_slug: Games/Анатомия main(); // Start the cycle
-

Примечание: В каждом из методов main(), обсуждаемых здесь, мы планируем новый requestAnimationFrame перед выполнением нашего содержимого цикла. Это не случайно и считает лучшей практикой. Ранний вызов следующего requestAnimationFrame гарантирует, что браузер получит его вовремя, чтобы спланировать соответствующим образом, даже если ваш текущий кадр пропустит свое окно VSync.

+

Примечание: В каждом из методов main(), обсуждаемых здесь, мы планируем новый requestAnimationFrame перед выполнением нашего содержимого цикла. Это не случайно и считает лучшей практикой. Ранний вызов следующего requestAnimationFrame гарантирует, что браузер получит его вовремя, чтобы спланировать соответствующим образом, даже если ваш текущий кадр пропустит своё окно VSync.

-

Приведенный выше фрагмент кода содержит два оператора. Первый оператор создает функцию как глобальную переменную с именем main().Эта функция выполняет некоторую работу, а также сообщает браузеру, что нужно вызвать следующий кадр с помощью window.requestAnimationFrame(). Второй оператор вызывает функцию main(), описанную в первом операторе. Поскольку main() вызывается один раз во втором операторе и каждый его вызов помещает себя в очерёдность действий, чтобы отрисовать следующий кадр, main() синхронизируется с вашей частотой кадров.

+

Приведённый выше фрагмент кода содержит два оператора. Первый оператор создаёт функцию как глобальную переменную с именем main().Эта функция выполняет некоторую работу, а также сообщает браузеру, что нужно вызвать следующий кадр с помощью window.requestAnimationFrame(). Второй оператор вызывает функцию main(), описанную в первом операторе. Поскольку main() вызывается один раз во втором операторе и каждый его вызов помещает себя в очерёдность действий, чтобы отрисовать следующий кадр, main() синхронизируется с вашей частотой кадров.

Конечно, этот цикл не идеален. Прежде чем мы обсудим способы его изменения, давайте обсудим, что он уже делает хорошо.

Синхронизация основного цикла с тем, когда браузер рисует на дисплее, позволяет запускать цикл так часто, как браузер хочет рисовать. Вам предоставляется контроль над каждым кадром анимации. Это также очень просто, потому что main() - единственная функция, которая зацикливается. Шутер от первого лица (или подобная игра) представляет новую сцену один раз в каждом кадре. Вы не можете добиться большей плавности и быстродействия.

-

Но не стоит сразу предполагать, что анимация требует покадрового управления. Простые анимации можно легко выполнять даже с ускорением на GPU с помощью CSS-анимации и других инструментов, включенных в браузер. Их очень много и они сделают вашу жизнь проще.

+

Но не стоит сразу предполагать, что анимация требует покадрового управления. Простые анимации можно легко выполнять даже с ускорением на GPU с помощью CSS-анимации и других инструментов, включённых в браузер. Их очень много и они сделают вашу жизнь проще.

Создание улучшенного основного цикла в JavaScript.

-

У нашего цикла есть две очевидные проблемы: main() загрязняет {{ domxref("window") }} объект (в нем хранятся все глобальные переменные) и код не оставляет нам возможность остановить цикл, если только вся вкладка не будет закрыта или обновлена. Для решения первой проблемы, если нужно, чтобы основной цикл просто выполнялся и вам не нужен легкий (прямой) доступ к нему, вы можете поместить его внутрь самовызывающейся Function Expression (IIFE).

+

У нашего цикла есть две очевидные проблемы: main() загрязняет {{ domxref("window") }} объект (в нем хранятся все глобальные переменные) и код не оставляет нам возможность остановить цикл, если только вся вкладка не будет закрыта или обновлена. Для решения первой проблемы, если нужно, чтобы основной цикл просто выполнялся и вам не нужен лёгкий (прямой) доступ к нему, вы можете поместить его внутрь самовызывающейся Function Expression (IIFE).

/*
 * Начинаем с точки с запятой в случае, если какая-либо строка кода выше данного примера
 * полагается на автоматическую вставку точки с запятой (ASI). Браузер может случайно решить,
 * что весь этот код начинается с предыдущей строки. Первая точка с запятой отмечает начало
-* новой строки, если предыдущая не была пустой или завершенной.
+* новой строки, если предыдущая не была пустой или завершённой.
 */
 
 ;(function () {
@@ -73,19 +73,19 @@ main(); // Start the cycle
main(); // Вызов цикла })(); -

Когда браузер наткнется на IIFE (Immediately Invoked Function Expression), он определит основной цикл и сразу же поставит его в очередь для следующего кадра. Он не будет привязан ни к какому объекту, и main (или main() для методов) будет неиспользуемым именем, доступным в остальной части приложения для определения чего-то другого.

+

Когда браузер наткнётся на IIFE (Immediately Invoked Function Expression), он определит основной цикл и сразу же поставит его в очередь для следующего кадра. Он не будет привязан ни к какому объекту, и main (или main() для методов) будет неиспользуемым именем, доступным в остальной части приложения для определения чего-то другого.

Примечание: На практике распространено предотвращать следующий requestAnimationFrame() используя оператор if вместо вызова cancelAnimationFrame().

-

Чтобы остановить основной цикл, вам понадобиться отменить вызов main() с помощью {{ domxref("window.cancelAnimationFrame()") }}. Необходимо передать в cancelAnimationFrame() идентификатор последнего вызова requestAnimationFrame(). Давайте предположим, что функции и переменные вашей игры были определены в пространстве имен, которое вы назвали MyGame.  В таком случае, основной цикл будет выглядеть следующим образом:

+

Чтобы остановить основной цикл, вам понадобиться отменить вызов main() с помощью {{ domxref("window.cancelAnimationFrame()") }}. Необходимо передать в cancelAnimationFrame() идентификатор последнего вызова requestAnimationFrame(). Давайте предположим, что функции и переменные вашей игры были определены в пространстве имён, которое вы назвали MyGame.  В таком случае, основной цикл будет выглядеть следующим образом:

/*
 * Начинаем с точки с запятой в случае, если какая-либо строка кода выше данного примера
 * полагается на автоматическую вставку точки с запятой (ASI). Браузер может случайно решить,
 * что весь этот код начинается с предыдущей строки. Первая точка с запятой отмечает начало
-* новой строки, если предыдущая не была пустой или завершенной.
+* новой строки, если предыдущая не была пустой или завершённой.
 *
 * Давайте также предположим, что MyGame уже определена.
 */
@@ -100,7 +100,7 @@ main(); // Start the cycle
main(); // Вызов цикла })(); -

Теперь у нас есть переменная stopMain, объявленная в нашем пространстве имен MyGame, которая содержит идентификатор последнего вызова requestAnimationFrame() нашего основного цикла.  В любой момент мы может остановить основной цикл, сказав браузеру, чтобы тот отменил запрос, соответствующий последнему маркеру.

+

Теперь у нас есть переменная stopMain, объявленная в нашем пространстве имён MyGame, которая содержит идентификатор последнего вызова requestAnimationFrame() нашего основного цикла.  В любой момент мы может остановить основной цикл, сказав браузеру, чтобы тот отменил запрос, соответствующий последнему маркеру.

window.cancelAnimationFrame( MyGame.stopMain );
@@ -108,7 +108,7 @@ main(); // Start the cycle

Построение более оптимизированного основного цикла в JavaScript

-

В конце контов, в JavaScript браузер выполняет свой собственный основной цикл, и ваш код существует на некоторых его этапах. В приведенных выше разделах описываются основные циклы, которые стараются не отнимать контроль у браузера. Их методы прикрепляют себя к  window.requestAnimationFrame(), который запрашивает контроль над предстоящим кадром у браузера.  Браузер решает, как связать эти запросы с их основным циклом. Спецификация W3C для requestAnimationFrame на самом деле точно не определяет, когда браузеры должны выполнять колбэки requestAnimationFrame. Это может быть преимуществом, поскольку позволяет поставщикам браузеров свободно экспериментировать с решениями, которые они считают лучшими, и настраивать их с течением времени.

+

В конце контов, в JavaScript браузер выполняет свой собственный основной цикл, и ваш код существует на некоторых его этапах. В приведённых выше разделах описываются основные циклы, которые стараются не отнимать контроль у браузера. Их методы прикрепляют себя к  window.requestAnimationFrame(), который запрашивает контроль над предстоящим кадром у браузера.  Браузер решает, как связать эти запросы с их основным циклом. Спецификация W3C для requestAnimationFrame на самом деле точно не определяет, когда браузеры должны выполнять колбэки requestAnimationFrame. Это может быть преимуществом, поскольку позволяет поставщикам браузеров свободно экспериментировать с решениями, которые они считают лучшими, и настраивать их с течением времени.

Современные версии Firefox и Google Chrome (вероятно, и другие) пытаются подключить колбэки requestAnimationFrame к своему основному потоку в самом начале временного интервала фрейма. Таким образом основной поток браузера пытается выглядеть следующим образом: 

@@ -116,12 +116,12 @@ main(); // Start the cycle
  • Запустить новый кадр (пока предыдущий обрабатывается на дисплее.).
  • Пройтись по колбэкам requestAnimationFrame и вызвать их.
  • Выполнить сборку мусора и другие задачи для каждого кадра, когда вышеупомянутые колбэки перестают контролировать основной поток.
  • -
  • Спать (если только какое-либо событие не прервет сон браузера) до тех пор, пока монитор не будет готов к вашему изображению (VSync), и повторить его.
  • +
  • Спать (если только какое-либо событие не прервёт сон браузера) до тех пор, пока монитор не будет готов к вашему изображению (VSync), и повторить его.
  • Вы можете думать о разработке realtime applications, как о запасе времени для работы. Все вышеперечисленные шаги должны выполняться каждые 16  с половиной миллисекунд, чтобы не отставать от дисплея с частотой 60Гц.  Браузеры вызывают ваш код таким образом, чтобы предоставить ему максимум времени для вычислений. Ваш основной поток часто запускает рабочие нагрузки, которые даже не находятся в основном потоке (Например, растеризация или шейдеры в WebGL).  Большие вычисления могут выполняться на Web Worker-e или GPU одновременно с тем, как браузер использует свой основной поток для управления сборкой мусора, обработки асинхронных вызовов или других задач. 

    -

    Пока мы обсуждаем распределение нашего временного бюджета, многие браузеры имеют инструмент под названием High Resolution Time. Объект {{ domxref("Date") }} больше не используется в качестве основного метода синхронизации событий, поскольку он очень не точен и может быть изменен системными часами. High Resolution Time, с другой стороны, подсчитывает количество миллисекунд начиная с navigationStart (при выгрузке предыдущего документа). Это значение возвращается в виде десятичного числа с точностью до миллисекунды.  Он известен как DOMHighResTimeStamp, но для всех целей и задач считайте его числом с плавающей запятой.  

    +

    Пока мы обсуждаем распределение нашего временного бюджета, многие браузеры имеют инструмент под названием High Resolution Time. Объект {{ domxref("Date") }} больше не используется в качестве основного метода синхронизации событий, поскольку он очень не точен и может быть изменён системными часами. High Resolution Time, с другой стороны, подсчитывает количество миллисекунд начиная с navigationStart (при выгрузке предыдущего документа). Это значение возвращается в виде десятичного числа с точностью до миллисекунды.  Он известен как DOMHighResTimeStamp, но для всех целей и задач считайте его числом с плавающей запятой.  

    Примечание: Системы (аппаратные или программные), которые не могу обеспечить точность в микросекундах, могут по крайней мере обеспечить точность в миллисекундах.  Однако, они должны обеспечивать точность до 0,001 мс, если способны на это. 

    @@ -129,7 +129,7 @@ main(); // Start the cycle -

    Это значение нельзя использовать само по себе, потому что оно относиться к неинтересному событию, но его можно вычесть из другой временной ветки, чтобы четко и точно определить, сколько времени прошло между этими двумя точками. Чтобы получить одну из этих временных меток, вы можете вызвать window.performance.now() и сохранить результат в переменную. 

    +

    Это значение нельзя использовать само по себе, потому что оно относиться к неинтересному событию, но его можно вычесть из другой временной ветки, чтобы чётко и точно определить, сколько времени прошло между этими двумя точками. Чтобы получить одну из этих временных меток, вы можете вызвать window.performance.now() и сохранить результат в переменную. 

    var tNow = window.performance.now();
     
    @@ -140,7 +140,7 @@ main(); // Start the cycle * Начинаем с точки с запятой в случае, если какая-либо строка кода выше данного примера * полагается на автоматическую вставку точки с запятой (ASI). Браузер может случайно решить, * что весь этот код начинается с предыдущей строки. Первая точка с запятой отмечает начало -* новой строки, если предыдущая не была пустой или завершенной. +* новой строки, если предыдущая не была пустой или завершённой. * * Давайте также предположим, что MyGame уже определена. */ -- cgit v1.2.3-54-g00ecf