Понимание проблем с таймером JavaScript - PullRequest
7 голосов
/ 06 мая 2010

Я начинаю на javascript MMORPG, который на самом деле будет работать гладко. В настоящее время я создал демо-версию, чтобы доказать, что я могу перемещать персонажей и заставлять их общаться друг с другом, а также видеть, как они перемещаются в прямом эфире.

http://set.rentfox.net/

Теперь таймеры Javascript - это то, что я не использовал широко, но, насколько я знаю, поправьте меня, если я ошибаюсь, это то, что одновременное выполнение нескольких setIntervals не очень хорошо работает, потому что все включено одна нить.

Допустим, я хотел, чтобы 10 разных людей обстреливали огненные шары монстра, используя позиционирование спрайтового фона с setInterval - эта анимация потребовала бы 10 setIntervals для перерисовки DOM для сдвигов фонового положения спрайтов. Разве это не будет большой ошибкой?

Мне было интересно, был ли способ обойти все это, возможно, с помощью Canvas, чтобы анимации могли происходить одновременно без создания очереди событий, и мне не нужно беспокоиться о таймерах.

Надеюсь, что это имеет смысл, и, пожалуйста, дайте мне знать, если мне нужно уточнить.

Ответы [ 2 ]

11 голосов
/ 06 мая 2010

Проблема с несколькими setInterval s имеет две стороны. Первый, как вы указали, так как весь Javascript в браузерах (в настоящее время) является однопоточным, выполнение одного таймера может задержать выполнение следующего таймера. ( Рабочие потоки , тем не менее; Firefox уже имеет их , как и Safari 4 [и, возможно, другие].) Во-вторых, таймер происходит с заданным интервалом, но если ваш обработчик все еще работает после истечения этого интервала, второй интервал полностью пропущен. Например, таймер может мешать самому себе.

Эта последняя часть нуждается в дополнительном объяснении: скажем, у вас setInterval в 10 мс (это самая быстрая скорость, которую вы можете ожидать от любой реализации; возможно, она зажата так, что не работает быстрее). Если ваш обработчик занимает 13 мс, интервал, который должен был произойти через 10 мс после его начала, будет полностью пропущен.

Я обычно использую setTimeout для такого рода вещей. Когда мой обработчик срабатывает, я делаю свою работу и затем планирую следующее событие в конце обработчика. Затем (в пределах того, в чем вы можете быть уверены), я знаю, что следующее событие произойдет через этот интервал.

Для того, что вы делаете, кажется, что лучше всего использовать один «импульсный» таймер, работающий с тем, что ему нужно делать с импульсом. Независимо от того, использует ли этот импульсный таймер setInterval или setTimeout, это оценочный вызов, основанный на том, что вы видите с вашим реальным кодом.

3 голосов
/ 06 мая 2010

+ 1 к Т. Дж. Краудеру, ответ был идеальным. Я настоятельно рекомендую научиться использовать Canvas поверх DOM-узлов для анимации игры; последний работает медленно и глючит, и в любой нетривиальной ситуации будет зависать браузер. OTOH, Canvas намного быстрее и может быть аппаратно ускорен, и даже имеет 3D-контекст, если вам это нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...